Как загружаются XIBS для локализованных приложений?

#iphone #localization #ios-simulator

#iPhone #локализация #ios-симулятор

Вопрос:

Я обнаружил, что после пары дней успешного запуска и отладки локализованных приложений на симуляторе он (или процесс развертывания XCode) перешел в состояние, при котором, если бы симулятор был настроен на один из поддерживаемых мной локальных языков, при запуске произошел бы сбой со следующим стеком:

 3   CoreFoundation                      0x01780e6a  [NSException raise:format:]   58
4   UIKit                               0x008050fa -[UINib instantiateWithOwner:options:]   2024
5   UIKit                               0x00806ab7 -[NSBundle(UINSBundleAdditions) loadNibNamed:owner:options:]   168
6   UIKit                               0x0060c17a -[UIApplication _loadMainNibFile]   172
7   UIKit                               0x0060ccf4 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:]   
8   UIKit                               0x00617617 -[UIApplication handleEvent:withNewEvent:]   1533
9   UIKit                               0x0060fabf -[UIApplication sendEvent:]   71
10  UIKit                               0x00614f2e _UIApplicationHandleEvent   7576
11  GraphicsServices                    0x01e13992 PurpleEventCallback   1550
  

Сбой происходит из-за того, что UIApplication не удается загрузить файл MainWindow.nib:

Завершение работы приложения из-за неперехваченного исключения ‘NSInternalInconsistencyException’, причина: ‘Не удалось загрузить NIB в bundle: ‘NSBundle /.app> (загружено)’ с именем ‘MainWindow»

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

  • Локализуйте каждый загружаемый Xib-файл на основе языка на устройстве. Итак, ваш локализованный пользовательский интерфейс полностью настроен с помощью Interface Builder.
  • Вы можете настроить локализуемый файл.strings для каждого целевого языка и получить доступ к строкам в нем из кода.

Я выбрал более поздний вариант, потому что хотел, чтобы все мои локализованные строки были в одном месте (чтобы их можно было перевести все сразу). Это означает, что у меня в моем проекте нет никаких xib-файлов в директориях, зависящих от языка (fr.lproj, zh-Hant.lproj и т.д.). Вместо этого у меня есть en.lproj, полный всех моих файлов xib (файлов nib после их сборки) и каталогов для конкретного языка, содержащих соответствующие переведенные файлы Localizable.strings.

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

После долгих поисков я понял, что симулятор дает сбой, потому что он искал свои файлы nib в каталоге, определяемом для конкретного языка (fr.lpro, sz-Hant.lproj, ja.lproj в зависимости от языковых настроек).

Таким образом, похоже, что симулятор находится в состоянии, когда он не ищет языковой каталог по умолчанию (en.lproj) после того, как ему не удается найти указатель в языковом каталоге.

Я решил проблему, перейдя в каталог приложений для симулятора (на основе сообщения об исключении выше):

/Пользователи / …/ Библиотека / Поддержка приложений / Симулятор iPhone /4.3/Приложения //.app

Затем перейдите в подкаталог для конкретного языка и скопируйте все файлы nib из en.lproj в этот каталог.

Скопировав файлы вручную, симулятор загружает файлы nib для конкретного языка (которые на самом деле являются просто копиями файлов в каталоге en.lproj), и все работает нормально.

Итак, мои вопросы:

  • Это просто ошибка в симуляторе? Итак, большое «НЕТ» этому
  • У кого-нибудь еще была эта проблема? Да
  • Это результат какой-то непонятной настройки XCode, которую я случайно переключил? Нет, не похоже

Обновить

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

Я попробовал предложенное McCygnus исправление (удалите все локализации для моих xibs, что переместит их обратно в корневой каталог), и это отсортировало его для меня. Итак, я предполагаю, что система локализации проверяет текущий языковой каталог, а затем корневой, он не вернется к вашему языку по умолчанию.

Комментарии:

1. У меня тоже эта проблема. Это воспроизводится как на симуляторе, так и на устройстве. Я вижу только одно сложное решение — добавить одинаковые файлы .xib в каждую папку .lproj. Это кажется не логически правильным, но я не могу найти никакого другого решения. Есть мысли?

2. @berec Итак, вы хотите убедиться, что все ваши xibs находятся в корневом каталоге. Вы можете положиться на то, что они находятся в en.lproj, если их нет в каталогах, специфичных для конкретного языка.

Ответ №1:

Недавно у меня возникла эта проблема, когда у меня была английская версия nib, но я не локализовал ее ни для одного из других языков (MyNib был в en.lproj). Симулятор искал MyNib только в каталоге другого языка (da.lproj, de.lproj и т.д.) И не возвращался к английской версии, если не был найден. Я исправил это, удалив английскую локализацию для наконечника. Это привело к тому, что он был в корневом каталоге app bundle с другими ресурсами, а не в en.lproj. После этого все работало отлично.

Меня это немного смутило, поскольку я думал, что система локализации проверяет все языки в предпочтительном пользователем порядке, причем английский обычно используется разработчиком в качестве универсального. Я не уверен, является ли это изменением в поведении загрузки или ошибкой симулятора (я никогда не пробовал на устройстве). Я предполагаю, что это последнее, но я не знаю наверняка. Это напоминает мне, что мне нужно отправить отчет об ошибке по нему.

Комментарии:

1. 1 Похоже, что это та же проблема. Я думаю, один или оба из нас должны это зарегистрировать 🙂

Ответ №2:

если вы используете

 [[Class alloc] initWithNibName:@"aNibName" bundle:nil];  
  

измените его на

 [[Class alloc] initWithNibName:@"aNibName" bundle:[NSBundle mainBundle]];
  

Ответ №3:

У меня был тот же симптом, но другая основная причина, которой я хотел бы поделиться. Я удалил локализацию, на что намекал McCygnus (спасибо за это), но все равно получил то же исключение, только для iPad. Оказалось, что мой файл Info.plist содержал ссылку на файл главного окна для конкретного iPad (MainWindow-iPad.nib). После удаления этого все заработало.

Ответ №4:

Я смог решить эту проблему, просто перезапустив xcode. =/

Комментарии:

1. Я сейчас так зол, что потратил два часа на поиск этой проблемы, и в конце концов простое закрытие xcode и возврат к нему сделали свое дело! боже мой!

2. Я пришел к выводу, что перезапуск xcode почти всегда стоит попробовать после 5 минут какой-либо странной проблемы. Печально, как часто это срабатывает.