Localizable.strings не загружает каждую другую сборку?

У меня возникла странная проблема с системой локализации, встроенной в Cocoa. Я использовал genstrings для создания файла localizable.strings для моего проекта, и файл загружает и заменяет строки, как ожидалось в моем приложении.

Однако, похоже, он работает только с каждой другой сборкой. Я создам код с XCode, протестирую его на своем устройстве, и он не будет отображать правильные строки без проблем. Однако следующая сборка не сможет загрузить файл строк (по крайней мере, это то, что я предполагаю). Это не случайно, но предсказуемо каждая другая сборка. Я ничего не делаю с файлом Localizable.strings.

Я не знаю, где даже начать диагностировать эту проблему, и мне было интересно, есть ли у кого-нибудь опыт локализации на Cocoa.

Я использую NSLocalizedString на всей моей базе кода так:

NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?")

Соответствующая запись в моем файле Localizable.strings:

/* Are you sure you want to start a new game? */
"ReallyNewGame" = "Do you really want to start a new game?";

Вот некоторые из частей моего Info.plist:

<key>CFBundleDevelopmentRegion</key>
<string>English</string>

Вот скриншот того, что происходит с каждой другой версией приложения:

Правильно: How it looks when correct

Неправильно: How it looks when incorrect

Я сбив с толку, почему это происходит. Я ничего не делаю вручную с файлом Localizable.strings, и я несколько раз очищал свой проект на XCode. Любые указатели в правильном направлении были бы весьма полезны. Если вам нужна дополнительная информация, я попытаюсь ее предоставить.

Спасибо!

Ответ 1

В случае, если это помогает кому-либо еще:

Я столкнулся с одной и той же проблемой: каждая другая сборка локализации не будет работать. Я обнаружил, что когда я проверил содержимое пакета, что Localizable.strings в en.lproj были повреждены - файл имел длину всего 76 байтов, если он должен был быть 4k. Следующая сборка коррупции исчезла, затем снова вернулась, а затем ушла...

Оказалось, что я скопировал дополнительную папку Localizable.strings в свой проект, когда скопировал папку из другого проекта. Когда я удалил дополнительную папку Localizable.strings, все волшебным образом работало. Уф!

Ответ 2

Я не могу дать вам прямой ответ, но могу предложить некоторые способы продолжения. На данный момент у меня нет приложения для нескольких языков, поэтому большинство из них - то, что я почерпнул, прочитав (возможно, у меня скоро будет интересный для вас вопрос):

1) Apple отказалась от пользователя English.lproj в пользу en.lproj. В любом случае, важно, что если вы используете "английский" в качестве значения CFBundleDevelopmentRegion, эта папка будет называться "английский", а не "en".

2) Ваш файл строк должен быть UTF16 и отмечен как таковой в инспекторе файлов (это самое правое в области Xcode)

3) Существует хороший предыдущий вопрос, в котором есть некоторые графические указатели на то, что ваши файлы локализации правильно введены в Xcode (поэтому Xcode знает об этом и знает он должен их обработать).

4) Возможно, ваш файл поврежден, в руководстве по ресурсам говорится, что вы можете запустить "plutil -lint Localizable.strings" на нем, чтобы проверить правильность

5) В качестве дополнительной заметки ряд людей указали на приложение для Mac App Store как приятную утилиту для объединения (не перезаписывать ) строковые файлы (по мере добавления).

6) Если все по-прежнему выглядит хорошо, добавьте следующее в свой AppDelegate "didFinishLaunchingWithOptions" (вверху), когда приложение запускается первым:

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSLog(@"Strings file: %@", [bundel pathForResource:@"Localizable" ofType:@".strings"]);
NSLog(@"Localizations: %@" [bundle localizations]);
NSLog(@"Local Dict: %@", [bundle localizedInfoDictionary]];
NSLog(@"localizedStringForKey: %@", [bundle localizedStringForKey:@"ReallyNewGame"value:@"WTF???" table:nil];
NSLog(@"Localized String: %@", NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?"));
exit(0); // just testing the above for now

Запустите приложение несколько раз. Выходные данные должны быть одинаковыми. Если он не добавляет комментарий к этому ответу, и мы можем продолжить дальше. Если это то же самое, хорошо, тогда что-то еще больше вызывает коррупцию в вашем приложении.

Ответ 3

Эта проблема возникает, когда:

  • у вас есть как минимум два файла */<locale>.lproj/<table_name>.strings, например два файла */en.lproj/Localizable.strings
  • вы поддерживаете несколько языков с помощью *.strings файлов

Вероятно, вы бы не создали два + .strings файла с тем же именем. Обычно эта проблема возникает, если вы используете внешнюю библиотеку с Localizable.strings файлами в своих ресурсах. У вас, вероятно, есть Localizable.strings файл в ваших ресурсах - и что конфликт, который XCode не удается решить.

TL; DR; Общий совет: , если вы создаете библиотеку, которая будет использоваться в качестве стороннего кода другими разработчиками, вместо создания файла Localizable.strings и использования NSLocalizedString() в нем, создайте таблицу локализованных строк подстановочных имен (например, MyLibName.strings) и используйте NSLocalizedStringFromTable.

Пример проблемы и подробное описание:

Я создал репозиторий "проблема-демон": https://github.com/kajot/LocalizedStringsMergingFailure

В частности, с тестом, который терпит неудачу при каждом прогоне: https://github.com/kajot/LocalizedStringsMergingFailure/blob/master/LocalizedStringsMergingFailureTests/LocalizedStringsMergingFailureTests.m

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings

Каждая OTHER построена, XCode создаст поврежденный файл Localizable.strings в комплекте. Решение: НЕ создавайте/добавляйте более одной таблицы LocalizedString с тем же именем к одной и той же цели.

LocalizedString table - это набор файлов */<locale>.lproj/<tableName>.strings. В приведенном выше примере есть две таблицы, каждая из которых называется Localizable (имя по умолчанию для таблицы).

Если таблица называется Localizable, вы получаете локализованные строки из таблицы с помощью

`NSLocalizedString(key, optionalComment)`.

Решение:

Вы можете либо объединить эти две таблицы (объединить соответствующие файлы с переводами с одних и тех же языков), либо изменить имя одной из таблиц.

Пример второго подхода (измененное имя одной из таблиц):

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── NewTableName.strings
│   │   └── en.lproj
│   │       └── NewTableName.strings

Теперь вы можете получить перевод из новой таблицы (NewTableName) с помощью NSLocalizedStringFromTable(key, @"NewTableName", optionalComment) и из "оригинальной" таблицы (Localizable) с помощью NSLocalizedString(key, optionalComment).

Ответ 5

У меня была аналогичная проблема с моим приложением. У меня было несколько целей в моем приложении и все с различными значками приложений. По какой-то причине один из значков приложений был поврежден, и, таким образом, все мои объекты переключились через приложения-иконы других целей. что довольно странно, потому что одна цель не должна знать о значке приложения других целей, если она не используется для обеих целей и помечена для обеих целей в xcode.

Я решил эту проблему, удалив поврежденный png и добавив его заново в проект. Если вы сделаете это с вашим файлом i18n, это тоже поможет. Но обязательно удалите не только ссылку из xcode, но и полный файл. Лучше всего было бы открыть файл в каком-то внешнем редакторе, например textwrangler, и скопировать текст в новый файл, а затем использовать его вместо этого.

Удачи.

Ответ 6

поведение,, что вы испытали, полностью нормальное. почему?


если вы проверите эти строки, соответствующая часть оригинального определения макроса NSLocalizedString:

#define NSLocalizedString(key, comment) \
        [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

вы могли видеть, что параметр comment является обманным параметром, он никогда не используется. (это просто для разработчика, который читает код)


более того, если вы проверите ссылку класса NSBundle, вы можете прочитать следующее интересное о возвращаемом значении метода -localizedStringForKey:value:table::

Возвращаемое значение

Если значение nil или пустая строка, а локализованная строка не найдена в таблице, возвращает ключ.

вот почему вы возвращаете свой ключ, потому что, вероятно, нет значения для этого ключа в ваших файлах Localizable.string.

печальные новости, но это нормально.


решение будет следующим:

NSLocalizedString(@"Are you sure you want to start a new game?", @"");

и в вашем Localizable.string файле:

@"Are you sure you want to start a new game?" = "Do you really want to start a new game?";