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)
.
Ответ 4
другой поток может помочь... Несколько файлов Localizable.strings в одном приложении iOS
возможно, вы можете очистить, а затем создать приложение из xcode...
Ответ 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?";