Всем привет,
Прошло совсем не много времени, с тех пор как я начал изучать Objective-C, но я начал работать над серьезным приложением. И передо мной стали различные задачи(проблемы), как реализовать то или это. Хочу поделится с вами одним из решений, одной из своих задач.
Итак начнем-с. Передо мной стала задача написать приложение биллинга для одного израильского мобильного оператора, в котором можно проверить состояние счета и выполнять некоторые настройки для своих мобильных линий.
Проект переписывался несколько раз, пока я не остановился на нужном мне варианте для навигации по приложению. Выбрал я ECSlideViewController. Решение очень было как раз кстати. Веб сайт данного оператора поддерживает 6 языков и я подумал если я делаю приложение, то нужно сделать его так же хорошо, с максимально-возможной реализацией для конечного пользователя, что бы по функционалу оно доходило до оригинального веб сайта. И эта короткая статья пойдет именно о локализации приложения под многие языки.
Начнем все по порядку, что-то нужно будет сделать вручную, а что-то вам прийдется сделать с помощью кода. Как я уже говорил выше, мое приложение пока что имеет 5 языков (Английский, Иврит, Русский, Французский, Арабский). Еще до конца не перевел его, так как приложение в процессе разработки. Я лишь дам вам старт, с чего начать, а продолжите уже сами.
До того как прийти к этому, я прочитал много статей, примеров и теории. Оказалось все на порядок проще чем я думал. по дороге к решению, я 2 раза стер свои файлы с кодом, но хорошо что делал backup и потом смог нормально все восстановить. Хотя один раз раз пришлось переписывать много кода сначала. Но что бы уберечь вас от ошибок, я решил написать эту статью.
И так что вам для начала нужно сделать ручками. в Objective-C существует строгая система разделения языков. Каждый язык находится в своей директории и под своим языковым именем. Например Английский язык будет в директории en.lproj. Приступим к созданию языковых директорий в корневой директории проекта.
Создаем несколько таких языков, 2-3 для начала, потом вы сможете добавить с десяток другой по своему усмотрению. Но не устоит переусердствовать, как как обычно в таких приложениях 1-3 языка не более. Редко когда дело доходит до 4-х. В последнее время, языки включены только в приложения с играми. А так как многие игры пишутся не на Objective-C то и локализация оных происходит не не там.
Я создал Английский, Иврит, Русский. Вы можете создать свои языки. Обратите внимание, что директории языков имеют строгий формат и должны обозначаться именно такими буквами, которые знает Objective-C. Английский будет — «en», Русский будет — «ru», Арабский будет — «ar» и т.д.
Тут можно найти правильный формат для своей локализации
Теперь создаем один файл под названием Lozalizable.strings таким образом, как показано на картинке:
после этого, в кореновй директории у вас появился вышеназванный файл.
откроем его и напишем первую строчку, которую захотим перевести, с Английского на Русский, именно с таким синтаксисом как показано на картинке
Слева текст оригинал, который нужно будет перевести, а справа его перевод. поэтому исходный язык приложения оставляем слева неизменным и опираясь на него переводим на другие языки.
Теперь скопируем наш файл в директорию ru.lproj. Почему мы копируем, а не вставляем, по простой причине. этот же файл, но с другим переводом будет использоваться во всех языках, поэтому исходный файл мы используем как шаблон, что бы составить список слов исходного языка. скопируйте его 3 раза. и поместите каждый экземпляр в в каждую созданную директорию с языками. Обратите внимание что бы имена файлов были одинаковы.
Допустим что у вас уже есть свой проект, новый мы создавать не будем и в одном из классов у вас есть строки (NSString). Возьмем к примеру, объект Label.
как мы можем его локализировать принудительно. У меня для этого прописана панель языков с 5-ю кнопочками. каждая кнопочка отвечает за установку своего языка. Метку о выбранном языке я сохраняю в NSUserDefaults ввиде строки из первых букв языка (en, ar, ru, he).
При нажатии на кнопку происходит именно то что и задумывалось, я устанавливаю язык и записываю его в NSUserDefaults.
Пример кода будет приблизительно таким:
Здесь, я для удобства, каждой кнопке установил свою метку (tag), которая передается в цикл switch и на основании метки я записываю нужную мне строчку в NSUserDefaults в категорию «Language». Здесь можно дальше экспериментировать и добавлять разные popup сообщение что язык изменен или хотите предупредить пользователя что язык поменяется на другой. нет пределу фантазиям.
Дальше в наш код мы добавим метод, который будет смотреть в NSUserDefaults при запуске приложения и проверять, что на данный момент установленно, и на основании метки, подгружать нужный нам файл Localizable.strings из нужной языковой директории.
Собственно сам метод будет таким:
имя метода languageSelectedStringForKey, вы можете изменить, по своему усмотрению. Главное сто бы оно отображало суть, что этот метод будет делать.
И теперь у нас есть кнопка, которая устанавливает нам нужную локализацию. И есть метод, который проверяет текущую настройку в NSUserDefaults и подгружает нужный нам язык. Что бы язык изменился, нужно закрыть приложение и открыть заново, не свернуть, а именно закрыть его совсем. Пока я редактировал статью, я нашел для себя как это сделать. в вашем случае может быть по другому. в методе switchLanguages, после добавления в NSUserDefaults, нужно вызвать метод
Теперь вернемся к нашему многострадальному myLabel.
и заменим строчку на вот такую:
Теперь просто сделайте Run и увидите как текст в myLabel изменится на тот, который вы указали при нажатии на кнопку.
Но если выхотите локализировать ваше приложение, согласно установленному языку в телефоне, например, пользователь изменил настройку интерфейс на русский, то можно прописать вот такую стандартную строчку
Тогда язык сменится везде на тот который вы указали в телефоне и все строки должны быть именно в таком формате. В таком случае это будет статическая локализация приложения, пока пользователь не изменил интерфейс своего телефона на другой.
При таком подходе, вам не нужно почти ничего прописывать. никаких методов и кода, а создать те языковые директории с нужными файлами, которые я описал выше и вместо custom метода languageSelectedStringForKey, использовать только этот NSLocalizedString. Можете выбирать подход, который нравится вам.
Так же важно знать, что локализация — это не только одни строки. я лишь объяснил с простого с чего начать, локализация — это дата и время, картинки и звуковые файлы так же могут быть локализированы. Подробнее про локализацию приложений, можно посмотреть видео с прошлого года WWDC2012 Session #224. Там подробно все объясняют.
Тем кому интересна эта статья, найдут в ней базу по локализации. Это сэкономит им несколько часов, а может и дней на поиск нужного решения. Не ограничивайтесь одним языком, может быть ваше приложение найдет поддержку и в другой стране. А если есть свои методы реализации той же идеи, можете написать свой tutorial млм оставить комментарий с решением. другие обязательно прочтут. И да, всем озлобленным посвящается http://habrahabr.ru/post/178747/
Вот такой оказался это простой способ. Терпение и труд, все перетрут.
Happy Coding!
Прошло совсем не много времени, с тех пор как я начал изучать Objective-C, но я начал работать над серьезным приложением. И передо мной стали различные задачи(проблемы), как реализовать то или это. Хочу поделится с вами одним из решений, одной из своих задач.
Итак начнем-с. Передо мной стала задача написать приложение биллинга для одного израильского мобильного оператора, в котором можно проверить состояние счета и выполнять некоторые настройки для своих мобильных линий.
Проект переписывался несколько раз, пока я не остановился на нужном мне варианте для навигации по приложению. Выбрал я ECSlideViewController. Решение очень было как раз кстати. Веб сайт данного оператора поддерживает 6 языков и я подумал если я делаю приложение, то нужно сделать его так же хорошо, с максимально-возможной реализацией для конечного пользователя, что бы по функционалу оно доходило до оригинального веб сайта. И эта короткая статья пойдет именно о локализации приложения под многие языки.
Приступим
Начнем все по порядку, что-то нужно будет сделать вручную, а что-то вам прийдется сделать с помощью кода. Как я уже говорил выше, мое приложение пока что имеет 5 языков (Английский, Иврит, Русский, Французский, Арабский). Еще до конца не перевел его, так как приложение в процессе разработки. Я лишь дам вам старт, с чего начать, а продолжите уже сами.
До того как прийти к этому, я прочитал много статей, примеров и теории. Оказалось все на порядок проще чем я думал. по дороге к решению, я 2 раза стер свои файлы с кодом, но хорошо что делал backup и потом смог нормально все восстановить. Хотя один раз раз пришлось переписывать много кода сначала. Но что бы уберечь вас от ошибок, я решил написать эту статью.
И так что вам для начала нужно сделать ручками. в Objective-C существует строгая система разделения языков. Каждый язык находится в своей директории и под своим языковым именем. Например Английский язык будет в директории en.lproj. Приступим к созданию языковых директорий в корневой директории проекта.
Создаем несколько таких языков, 2-3 для начала, потом вы сможете добавить с десяток другой по своему усмотрению. Но не устоит переусердствовать, как как обычно в таких приложениях 1-3 языка не более. Редко когда дело доходит до 4-х. В последнее время, языки включены только в приложения с играми. А так как многие игры пишутся не на Objective-C то и локализация оных происходит не не там.
Я создал Английский, Иврит, Русский. Вы можете создать свои языки. Обратите внимание, что директории языков имеют строгий формат и должны обозначаться именно такими буквами, которые знает Objective-C. Английский будет — «en», Русский будет — «ru», Арабский будет — «ar» и т.д.
Тут можно найти правильный формат для своей локализации
Теперь создаем один файл под названием Lozalizable.strings таким образом, как показано на картинке:
после этого, в кореновй директории у вас появился вышеназванный файл.
откроем его и напишем первую строчку, которую захотим перевести, с Английского на Русский, именно с таким синтаксисом как показано на картинке
Слева текст оригинал, который нужно будет перевести, а справа его перевод. поэтому исходный язык приложения оставляем слева неизменным и опираясь на него переводим на другие языки.
Теперь скопируем наш файл в директорию ru.lproj. Почему мы копируем, а не вставляем, по простой причине. этот же файл, но с другим переводом будет использоваться во всех языках, поэтому исходный файл мы используем как шаблон, что бы составить список слов исходного языка. скопируйте его 3 раза. и поместите каждый экземпляр в в каждую созданную директорию с языками. Обратите внимание что бы имена файлов были одинаковы.
Пол работы сделано
Допустим что у вас уже есть свой проект, новый мы создавать не будем и в одном из классов у вас есть строки (NSString). Возьмем к примеру, объект Label.
- myLabel.text = @"Account";
как мы можем его локализировать принудительно. У меня для этого прописана панель языков с 5-ю кнопочками. каждая кнопочка отвечает за установку своего языка. Метку о выбранном языке я сохраняю в NSUserDefaults ввиде строки из первых букв языка (en, ar, ru, he).
При нажатии на кнопку происходит именно то что и задумывалось, я устанавливаю язык и записываю его в NSUserDefaults.
Пример кода будет приблизительно таким:
- -(IBAction)switchLanguages:(id)sender {
- NSUserDefaults *userDefaults = [[NSUserDefaults alloc] init];
- switch ([sender tag]) {
- case 10:
- [userDefaults setObject:@"en" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- case 11:
- [userDefaults setObject:@"he" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- case 12:
- [userDefaults setObject:@"ru" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- case 13:
- [userDefaults setObject:@"fr" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- case 14:
- [userDefaults setObject:@"ar" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- default:
- [userDefaults setObject:@"he" forKey:@"Language"];
- [userDefaults synchronize];
- break;
- }
- }
Здесь, я для удобства, каждой кнопке установил свою метку (tag), которая передается в цикл switch и на основании метки я записываю нужную мне строчку в NSUserDefaults в категорию «Language». Здесь можно дальше экспериментировать и добавлять разные popup сообщение что язык изменен или хотите предупредить пользователя что язык поменяется на другой. нет пределу фантазиям.
Дальше в наш код мы добавим метод, который будет смотреть в NSUserDefaults при запуске приложения и проверять, что на данный момент установленно, и на основании метки, подгружать нужный нам файл Localizable.strings из нужной языковой директории.
Собственно сам метод будет таким:
- -(NSString *)languageSelectedStringForKey:(NSString *)key {
- NSString *language = [[NSUserDefaults standardUserDefaults] stringForKey:@"Language"];
- NSString *path;
- if ([language isEqual:@"en"]) {
- path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
- }
- else if ([language isEqual:@"he"]) {
- path = [[NSBundle mainBundle] pathForResource:@"he" ofType:@"lproj"];
- }
- else if ([language isEqual:@"ru"]) {
- path = [[NSBundle mainBundle] pathForResource:@"ru" ofType:@"lproj"];
- }
- else if ([language isEqual:@"fr"]) {
- path = [[NSBundle mainBundle] pathForResource:@"fr" ofType:@"lproj"];
- }
- else if ([language isEqual:@"ar"]) {
- path = [[NSBundle mainBundle] pathForResource:@"ar" ofType:@"lproj"];
- }
- else {
- path = [[NSBundle mainBundle] pathForResource:@"he" ofType:@"lproj"];
- }
- NSBundle *languageBundle = [NSBundle bundleWithPath:path];
- NSString *str = [languageBundle localizedStringForKey:(key) value:@"" table:nil];
- return str;
- }
имя метода languageSelectedStringForKey, вы можете изменить, по своему усмотрению. Главное сто бы оно отображало суть, что этот метод будет делать.
И теперь у нас есть кнопка, которая устанавливает нам нужную локализацию. И есть метод, который проверяет текущую настройку в NSUserDefaults и подгружает нужный нам язык. Что бы язык изменился, нужно закрыть приложение и открыть заново, не свернуть, а именно закрыть его совсем. Пока я редактировал статью, я нашел для себя как это сделать. в вашем случае может быть по другому. в методе switchLanguages, после добавления в NSUserDefaults, нужно вызвать метод
[self viewDidLoad];. Тут у каждого может быть индивидуально, но именно там нужно проводить дополнительные действия с приложением. У меня это сработало.
Теперь вернемся к нашему многострадальному myLabel.
и заменим строчку на вот такую:
- myLabel.text = [self languageSelectedStringForKey:@"Account"];
Теперь просто сделайте Run и увидите как текст в myLabel изменится на тот, который вы указали при нажатии на кнопку.
Но если выхотите локализировать ваше приложение, согласно установленному языку в телефоне, например, пользователь изменил настройку интерфейс на русский, то можно прописать вот такую стандартную строчку
- myLabel.text = NSLocalizedString(@"Account", nil);
Тогда язык сменится везде на тот который вы указали в телефоне и все строки должны быть именно в таком формате. В таком случае это будет статическая локализация приложения, пока пользователь не изменил интерфейс своего телефона на другой.
При таком подходе, вам не нужно почти ничего прописывать. никаких методов и кода, а создать те языковые директории с нужными файлами, которые я описал выше и вместо custom метода languageSelectedStringForKey, использовать только этот NSLocalizedString. Можете выбирать подход, который нравится вам.
Так же важно знать, что локализация — это не только одни строки. я лишь объяснил с простого с чего начать, локализация — это дата и время, картинки и звуковые файлы так же могут быть локализированы. Подробнее про локализацию приложений, можно посмотреть видео с прошлого года WWDC2012 Session #224. Там подробно все объясняют.
Тем кому интересна эта статья, найдут в ней базу по локализации. Это сэкономит им несколько часов, а может и дней на поиск нужного решения. Не ограничивайтесь одним языком, может быть ваше приложение найдет поддержку и в другой стране. А если есть свои методы реализации той же идеи, можете написать свой tutorial млм оставить комментарий с решением. другие обязательно прочтут. И да, всем озлобленным посвящается http://habrahabr.ru/post/178747/
Вот такой оказался это простой способ. Терпение и труд, все перетрут.
Happy Coding!