Всем привет,
Прошло совсем не много времени, с тех пор как я написал первую статью(визитную карточку), там где я рассказал кто я и что я, но из-за отрицательных комментариев отдельных личностей и негатива пришлось ее спрятать. Так как критика должна быть всегда конструктивна и подкрепляться обязательно аргументами. Извините что начинаю свою статью именно с этой ноты, но просто «накипело».
Итак начнем-с. Передо мной стала задача написать приложение биллинга для одного израильского мобильного оператора, в котором можно проверить состояние счета и выполнять некоторые настройки для своих мобильных линий.
Проект переписывался несколько раз, пока я не остановился на нужном мне варианте для навигации по приложению. Выбрал я ECSlideViewController. Решение очень было как раз кстати. Веб сайт данного оператора поддерживает 6 языков и я подумал если я делаю приложение, то нужно сделать его так же хорошо, с максимально-возможной реализацией для конечного пользователя, что бы по функционалу оно доходило до оригинального веб сайта. И эта короткая статья пойдет именно о локализации приложения под многие языки.
Приступим
Начнем все по порядку, что-то нужно будет сделать вручную, а что-то вам прийдется сделать с помощью кода. Как я уже говорил выше, мое приложение пока что имеет 5 языков (Английский, Иврит, Русский, Французский, Арабский). Еще до конца не перевел его, так как приложение в процессе разработки. Я лишь дам вам старт, с чего начать, а продолжите уже сами.
До того как прийти к этому, я прочитал много статей, примеров и теории. Оказалось все на порядок проще чем я думал. по дороге к решению, я 2 раза стер свои файлы с кодом, но хорошо что делал backup и потом смог нормально все восстановить. Хотя один раз раз пришлось переписывать много кода сначала. Но что бы уберечь вас от ошибок, я решил написать эту статью.
И так что вам для начала нужно сделать ручками. в Objective-C существует строгая система разделения языков. Каждый язык находится в своей директории и под своим языковым именем. Например Английский язык будет в директории en.lproj. Приступим к созданию языковых директорий в корневой директории проекта.
Создаем несколько таких языков, 2-3 для начала, потом вы сможете добавить с десяток другой по своему усмотрению.
Я создал Английский, Иврит, Русский. Вы можете создать свои языки. Обратите внимание, что директории языков имеют строгий формат и должны обозначаться именно такими буквами, которые знает Objective-C.
Тут можно найти правильный формат для своей локализации
Теперь создаем один файл под названием Lozalizable.strings таким образом, как показано на картинке:
после этого, в кореновй директории у вас появился вышеназванный файл.
откроем его и напишем первую строчку, которую захотим перевести, с Английского на Русский, именно с таким синтаксисом как показано на картинке
Слева текст оригинал, который нужно будет перевести, а справа его перевод. поэтому исходный язык приложения оставляем слева неизменным и опираясь на него переводим на другие языки.
Теперь скопируем наш файл в директорию ru.lproj. Почему мы копируем, а не вставляем, по простой причине. этот же файл, но с другим переводом будет использоваться во всех языках. скопируйте его 3 раза. и поместите каждый экземпляр в в каждую созданную директорию с языками.
Пол работы сделано
Допустим что у вас уже есть свой проект, новый мы создавать не будем и в одном из классов у вас есть строки (NSString). Возьмем к примеру, объект Label.
- myLabel.text = @"Account";
как мы можем его локализировать принудительно. У меня для этого прописана панель языков с 5-ю кнопочками. каждая кнопочка отвечает за установку своего языка. Метку о выбранном языке я сохраняю в 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 и подгружает нужный нам язык. Что бы язык изменился, нужно закрыть приложение и открыть заново, не свернуть, а именно закрыть его совсем. я еще пока не нашел решения как это сделать на лету, но насколько я понял такое возможно.
Теперь вернемся к нашему многострадальному myLabel.
и заменим строчку на вот такую:
- myLabel.text = [self languageSelectedStringForKey:@"Accountt"];
Теперь просто сделайте Run и увидите как текст в myLabel изменится на тот, который указан в вашем файле локализации.
Но если выхотите локализировать ваше приложение, согласно установленному языку в телефоне, например, пользователь изменил настройку интерфейс на русский, то можно прописать вот такую стандартную строчку
- myLabel.text = NSLocalizedString(@"Account", nil);
Тогда язык сменится везде на тот который вы указали в телефоне и все строки должны быть именно в таком формате. В таком случае это будет статическая локализация приложения, пока пользователь не изменить интерфейс своего телефона на другой.
Вот такой оказался это простой способ. Терпение и труд, все перетрут.
Happy Coding!
Автор: perlik