Comments 23
Самый главный минус XLIFF — это отсутствие нормальной поддержки плурализации («один конь», «два коня»). Этого вполне достаточно, чтобы окончательно закопать эту технологию для нормального использования. Вся суть в (ещё более) удобном отделении данных о локализации и супер удобное взаимодействие с локализаторами. XLIFF распространенный формат, для него есть куча софта и он используется на разных платформах. Получается, что вашим локализаторам прийдется часть ресурсов размещать в XLIFF, а часть в проприетарном замороченном apple формате .stringsdict. Естественно они делать этого не будут (или будут плохо) и все прелести автоматизации сходят на нет.
Кстати, я решительно не согласен с предложенными вами способами именования ключей для строк («Auth», «Error»), в прошлом году я записал свои мысли на этот счет стандартных средств интернационализации тут.
Так что я бы рекомендовал какое-то другое решение для управления локализациями.
Кстати, я решительно не согласен с предложенными вами способами именования ключей для строк («Auth», «Error»), в прошлом году я записал свои мысли на этот счет стандартных средств интернационализации тут.
Так что я бы рекомендовал какое-то другое решение для управления локализациями.
0
Самый главный минус XLIFF — это отсутствие нормальной поддержки плурализации («один конь», «два коня»).
Да это минус, но у меня с ним не было больших проблем.
Кстати, я решительно не согласен с предложенными вами способами именования ключей для строк («Auth», «Error»)
Такое именование ключей вызвано форматом XLIFF, потому что он не подразумевает работу с ключами. Он собирает таблички из оригинальной строки и перевода к ней. Если бы оригинальной строкой выступал был абстрактный ключ, то это было бы уже нарушением формата.
0
Можно поподробнее о «нарушении формата»? Поковырял интеграцию Xcode с XLIFF ещё раз и немного сам стандарт. Не понял про «таблички из оригинальной строки и перевода к ней». Ключи на языке разработки — это как раз та практика, которую предлагает Apple (я её не поддерживаю). Xcode работает с файлами ресурсов (т.е. ключи даже не обязательно использовать из кода) и он использует и ключ и перевод.
Например, для такой строчки:
Получается такой кусок в одном из XLIFF:
Просто API работает так, что, если для ключа нет перевода, то NSLocalizedString + NSString возвращают ключ.
Или может быть я что-то упустил?
Например, для такой строчки:
/* Testy Commenty! */ "testy" = "ru Testy!";
Получается такой кусок в одном из XLIFF:
<trans-unit id="testy"> <source>en Testy!</source> <target>ru Testy!</target> </trans-unit>
Просто API работает так, что, если для ключа нет перевода, то NSLocalizedString + NSString возвращают ключ.
Или может быть я что-то упустил?
0
> Ключом выступает не абстрактная строка, а текст на Development Language. Если меняется оригинальный текст, то его приходится заново переводить.
При локализация ксибов я использую такой подход:
Для интерфейстых элементов создаю собственные сабклассы со свойством
В сеттере которого присваиваю текст, полученный из NSLocalizedString по присвоенному по свойству ключу.
Это свойство видно в Interface Builder, в него и нужно прописать ключ локализации.
При локализация ксибов я использую такой подход:
Для интерфейстых элементов создаю собственные сабклассы со свойством
@proprerty (nonatomic, strong) IBDesignable NSString* locKey;
В сеттере которого присваиваю текст, полученный из NSLocalizedString по присвоенному по свойству ключу.
Это свойство видно в Interface Builder, в него и нужно прописать ключ локализации.
0
Вот, точно! В категорию нельзя ли обернуть, кстати, это?
0
Только что проверил: внезапно, работает. То есть, не нужен даже сабкласс.
0
Замечательно!
0
Вообще, я так запихиваю через Interface Builder многие вещи: шрифт из пресета, цвет placeholder'а у UITextField (который по умолчанию серый и не меняется в визуальном дизайнере), угол скругления, кастомный стиль кнопки и т.д. Практически всё, что обычно вручную делается в awakeFromNib можно реализовать таким образом.
0
Это я так же делаю, просто до упрощения локализации таким путем мысль еще не доходила.
Была идея вставлять ключи от строк прямо в текстовые поля и заменять на локализованные строки при инстанцировании и т.п. Но то была не оформленная идея, которая казалось немного кривой. А ваш способ, по-моему, идеален.
Была идея вставлять ключи от строк прямо в текстовые поля и заменять на локализованные строки при инстанцировании и т.п. Но то была не оформленная идея, которая казалось немного кривой. А ваш способ, по-моему, идеален.
0
Вашу идею, кстати, я тоже реализовывал, до того как нашёл способ добавить свойство в Interface Builder.
Там есть некоторые трудности с тем, что для некоторых контролов текст может быть выставлен для любых состояний (всех сочетаний получается 16 штук), причём непонятно, какие из них действительно выставлены.
С другой стороны, если у вас для разных состояний тексты действительно отличаются — возможно лучше использовать именно этот путь.
Там есть некоторые трудности с тем, что для некоторых контролов текст может быть выставлен для любых состояний (всех сочетаний получается 16 штук), причём непонятно, какие из них действительно выставлены.
С другой стороны, если у вас для разных состояний тексты действительно отличаются — возможно лучше использовать именно этот путь.
0
Сделал небольшой обзор на данный приём
0
Видел у ребят на соседних пару проектах это сделано через категории, они перенесли многие настройки UI компонентов (цвета, локализацию и что-то еще) в IB как раз через ibinspectable. Я не фанат такого, но оказалось реально удобно. Просто скетч проекта открываешь и копипастишь всё и в xcode, и код писать не надо.
0
И как это работает, например, с UIButton? Плохая идея сабклассить класс кластеры. Но вообще, если использовать нибы, IBDesignable действительно удобный инструмент.
0
UIButton — не кластер. Честно говоря, я не помню ни одного кластера среди наследников от UIView
0
Когда речь заходит про паттерн кластер в Cocoa, то обычно приводят в пример NSArray и UButton. Хотя я лично не проверял, каких именно типов возвращаются объекты из метода + (instancetype)buttonWithType:(UIButtonType)buttonType; Но пишут, что это наследники UIButton для не Custom типа…
0
Заглянул в доки — действительно, формально он не класс кластер (по крайней мере так не пишут прямо), так что тут я не прав. Но сабклассить его всё равно не стоит хотябы потому, что никто не гарантирует каким образом будет реализована иерархия классов и как API может измениться со временем.
0
Отличить кластер можно по возвращаему типу, не совпадающему с оригинальным. Для [NSArray array], например, это __NSArray0.
Конструкторы UIButton возвращает всегда UIButton. Так что даже если там внутри происходит какая-то «магия» — на наследование она не влияет.
> Но сабклассить его всё равно не стоит
В эппловской документации для таких классов содержится отдельное предупреждение (как, например, у UIWebView: «Subclassing Notes: The UIWebView class should not be subclassed.»)
В случае же кнопки — некоторые вещи просто невозможно реализовать без наследования (модификация intrinsicContentSize, например)
Конструкторы UIButton возвращает всегда UIButton. Так что даже если там внутри происходит какая-то «магия» — на наследование она не влияет.
> Но сабклассить его всё равно не стоит
В эппловской документации для таких классов содержится отдельное предупреждение (как, например, у UIWebView: «Subclassing Notes: The UIWebView class should not be subclassed.»)
В случае же кнопки — некоторые вещи просто невозможно реализовать без наследования (модификация intrinsicContentSize, например)
0
Да, всё верно, сейчас везде возвращается UIButton(по крайней мере -class возвращает его, не проверял все типы) и документация (обычно) явно описывает вопросы сабклассинга. Но, я помню времена, когда от типа зависел возвращаемый сабкласс. И достаточно много времени потратил на исследования различных хаков, которые применяет эппл под капотом. Сейчас не могу нагуглить, но я читал множество предостережений насчет UIButton и его отношения к class cluster, ребята из WWDC Labs советуют этого не делать.
То что это работает сейчас не значит, что это продолжит работать завтра. Сабклассить UIButton и навешивать это всё через IB — скользкая опасная дорога. Сегодня UIButton можно достаточно гибко кастумизировать, и я бы предпочел использовать средства UIButton, или сабкласс UIControl.
То что это работает сейчас не значит, что это продолжит работать завтра. Сабклассить UIButton и навешивать это всё через IB — скользкая опасная дорога. Сегодня UIButton можно достаточно гибко кастумизировать, и я бы предпочел использовать средства UIButton, или сабкласс UIControl.
0
Ну, как уже выяснилось в соседней метке — IB видит в том числе и свойства, объявленные в категориях.
По поводу UIButton: я работаю с платформой начиная с iPhone OS 3.1.3, и не разу не замечал у UIButton признаков кластера, в отличии от того же NSArray. Возможно — я был недостаточно внимателен. Возможно — вы что-то путаете.
По поводу наследования: не вижу ни одного повода от него отказываться — это основная концепция ООП.
К тому же нужно всего лишь следить за отсутствием конфликтов имён и не использовать приватные методы. Для того, чтобы при таком подходе что-то сломалось — Эппл должен переписать половину SDK, по пути сломав половину приложений из AppStore. Этого не случится никогда.
По поводу UIButton: я работаю с платформой начиная с iPhone OS 3.1.3, и не разу не замечал у UIButton признаков кластера, в отличии от того же NSArray. Возможно — я был недостаточно внимателен. Возможно — вы что-то путаете.
По поводу наследования: не вижу ни одного повода от него отказываться — это основная концепция ООП.
К тому же нужно всего лишь следить за отсутствием конфликтов имён и не использовать приватные методы. Для того, чтобы при таком подходе что-то сломалось — Эппл должен переписать половину SDK, по пути сломав половину приложений из AppStore. Этого не случится никогда.
0
Аналогичная ситуация, но признаки я встречал, поэтому сейчас немного удивлен их отсутствием.
Насчет опасности: я не про навешивание свойств в категории, это не будет работать, только если они выплюнут «бинарно совместимый» класс и засвиззлят -class и кучу всего ещё. Такое бывает, но редко и нам об этом никто не рассказывает. Такое действительно очень маловероятно.
Насчет наследования сейчас просто начнется холивар, так что, думаю, не стоит его начинать, всем понятна противоположная точка зрения.
Насчет опасности: я не про навешивание свойств в категории, это не будет работать, только если они выплюнут «бинарно совместимый» класс и засвиззлят -class и кучу всего ещё. Такое бывает, но редко и нам об этом никто не рассказывает. Такое действительно очень маловероятно.
Насчет наследования сейчас просто начнется холивар, так что, думаю, не стоит его начинать, всем понятна противоположная точка зрения.
0
Чтобы быстро тестировать приложение под другой локалью, можно добавить в настройки схемы (или создать копий схемы под каждую локаль и язык) пару аргументов для Run. А именно:
Параметры в скобках соответствуют международным стандартам и легко гуглятся.
- выбрать схему
- выбрать Edit Scheme в выпадающем меню
- выбрать Run
- выбрать Arguments
- добавить -AppleLocale de_De
- выбрать -AppleLanguages (de)
Параметры в скобках соответствуют международным стандартам и легко гуглятся.
0
Возможно, пригодится — перевели статью о локализации iOs-приложений на основе XCode 7.3.1: https://habrahabr.ru/company/alconost/blog/322434/.
0
Xcode Version 8.3.3 (8E3004b).
Для того, чтобы оставить приложению только русский язык теперь есть другой способ (возможно и был, не проверял на версиях старее).
Итак, цель: Один язык в приложении кроме английского.
1. Идем в настройки проекта (не Target), в списке ищем Localizations. Удаляем все лишние языки.
2. Идем в Target проекта (или extensions) -> Info -> Localization native development пишем «ru» для русского, для других языков смотри список (Настройки проекта — Localizations -> "+" открывается список с названием языка и коротким названием).
3.Чистим проект, удаляем приложение с девайса.
Итого: всегда русский язык в приложении
Для того, чтобы оставить приложению только русский язык теперь есть другой способ (возможно и был, не проверял на версиях старее).
Итак, цель: Один язык в приложении кроме английского.
1. Идем в настройки проекта (не Target), в списке ищем Localizations. Удаляем все лишние языки.
2. Идем в Target проекта (или extensions) -> Info -> Localization native development пишем «ru» для русского, для других языков смотри список (Настройки проекта — Localizations -> "+" открывается список с названием языка и коротким названием).
3.Чистим проект, удаляем приложение с девайса.
Итого: всегда русский язык в приложении
0
Sign up to leave a comment.
iOS Localization: XLIFF