«Parlez vous Francais?!» Или как заставить ваше приложение, говорить на многих языках

от автора

Всем привет,

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

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


Проект переписывался несколько раз, пока я не остановился на нужном мне варианте для навигации по приложению. Выбрал я ECSlideViewController. Решение очень было как раз кстати. Веб сайт данного оператора поддерживает 6 языков и я подумал если я делаю приложение, то нужно сделать его так же хорошо, с максимально-возможной реализацией для конечного пользователя, что бы по функционалу оно доходило до оригинального веб сайта. И эта короткая статья пойдет именно о локализации приложения под многие языки.

Приступим

Начнем все по порядку, что-то нужно будет сделать вручную, а что-то вам прийдется сделать с помощью кода. Как я уже говорил выше, мое приложение пока что имеет 5 языков (Английский, Иврит, Русский, Французский, Арабский). Еще до конца не перевел его, так как приложение в процессе разработки. Я лишь дам вам старт, с чего начать, а продолжите уже сами.

До того как прийти к этому, я прочитал много статей, примеров и теории. Оказалось все на порядок проще чем я думал. по дороге к решению, я 2 раза стер свои файлы с кодом, но хорошо что делал backup и потом смог нормально все восстановить. Хотя один раз раз пришлось переписывать много кода сначала. Но что бы уберечь вас от ошибок, я решил написать эту статью.

И так что вам для начала нужно сделать ручками. в Objective-C существует строгая система разделения языков. Каждый язык находится в своей директории и под своим языковым именем. Например Английский язык будет в директории en.lproj. Приступим к созданию языковых директорий в корневой директории проекта.
Создаем несколько таких языков, 2-3 для начала, потом вы сможете добавить с десяток другой по своему усмотрению.

Я создал Английский, Иврит, Русский. Вы можете создать свои языки. Обратите внимание, что директории языков имеют строгий формат и должны обозначаться именно такими буквами, которые знает Objective-C.

Тут можно найти правильный формат для своей локализации

Теперь создаем один файл под названием Lozalizable.strings таким образом, как показано на картинке:

после этого, в кореновй директории у вас появился вышеназванный файл.

откроем его и напишем первую строчку, которую захотим перевести, с Английского на Русский, именно с таким синтаксисом как показано на картинке

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

Теперь скопируем наш файл в директорию ru.lproj. Почему мы копируем, а не вставляем, по простой причине. этот же файл, но с другим переводом будет использоваться во всех языках. скопируйте его 3 раза. и поместите каждый экземпляр в в каждую созданную директорию с языками.

Пол работы сделано

Допустим что у вас уже есть свой проект, новый мы создавать не будем и в одном из классов у вас есть строки (NSString). Возьмем к примеру, объект Label.

  1. myLabel.text = @"Account";

как мы можем его локализировать принудительно. У меня для этого прописана панель языков с 5-ю кнопочками. каждая кнопочка отвечает за установку своего языка. Метку о выбранном языке я сохраняю в NSUserDefaults ввиде строки и первых букв языка.

При нажатии на кнопку происходит именно то что и задумывалось, я устанавливаю язык.

Пример кода будет приблизительно таким:

  1. (IBAction)switchLanguages:(id)sender {
  2.  
  3.     NSUserDefaults *userDefaults = [[NSUserDefaults alloc] init];
  4.  
  5.     switch ([sender tag]) {
  6.  
  7.         case 10:
  8.             [userDefaults setObject:@"en" forKey:@"Language"];
  9.             [userDefaults synchronize];
  10.  
  11.             break;
  12.         case 11:
  13.             [userDefaults setObject:@"he" forKey:@"Language"];
  14.             [userDefaults synchronize];
  15.             break;
  16.         case 12:
  17.             [userDefaults setObject:@"ru" forKey:@"Language"];
  18.             [userDefaults synchronize];
  19.             break;
  20.         case 13:
  21.             [userDefaults setObject:@"fr" forKey:@"Language"];
  22.             [userDefaults synchronize];
  23.             break;
  24.         case 14:
  25.             [userDefaults setObject:@"ar" forKey:@"Language"];
  26.             [userDefaults synchronize];
  27.             break;
  28.         default:
  29.       [userDefaults setObject:@"he" forKey:@"Language"];
  30.       [userDefaults synchronize];
  31.             break;
  32.  
  33.     }
  34.  
  35. }

Здесь я для удобства, каждой кнопке установил свою метку (tag), которая передается в цикл switch и на основании метки я записываю нужную мне строчку в NSUserDefaults в категорию «Language». Здесь можно дальше экспериментировать и добавлять разные popup сообщение что язык изменен или хотите предупредить пользователя что язык поменяется на другой. нет пределу фантазиям.

Дальше в наш код мы добавим метод, которые будет идти при запуске приложения в NSUserDefaults и проверять что на данный момент установленно, и на основании метки, подгружать нужный нам файл Localizable.strings.

Собственно сам метод будет таким:

  1. (NSString *)languageSelectedStringForKey:(NSString *)key {
  2.     NSString *language = [[NSUserDefaults standardUserDefaults] stringForKey:@"Language"];
  3.  
  4.     NSString *path;
  5.  
  6.     if ([language isEqual:@"en"]) {
  7.         path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
  8.     }
  9.     else if ([language isEqual:@"he"]) {
  10.         path = [[NSBundle mainBundle] pathForResource:@"he" ofType:@"lproj"];
  11.     }
  12.     else if ([language isEqual:@"ru"]) {
  13.         path = [[NSBundle mainBundle] pathForResource:@"ru" ofType:@"lproj"];
  14.     }
  15.     else if ([language isEqual:@"fr"]) {
  16.         path = [[NSBundle mainBundle] pathForResource:@"fr" ofType:@"lproj"];
  17.     }
  18.     else if ([language isEqual:@"ar"]) {
  19.         path = [[NSBundle mainBundle] pathForResource:@"ar" ofType:@"lproj"];
  20.     }
  21.     else {
  22.         path = [[NSBundle mainBundle] pathForResource:@"he" ofType:@"lproj"];
  23.     }
  24.  
  25.     NSBundle *languageBundle = [NSBundle bundleWithPath:path];
  26.     NSString *str = [languageBundle localizedStringForKey:(key) value:@"" table:nil];
  27.  
  28.     return str;
  29.  
  30. }

Первое свойство метода languageSelectedStringForKey, вы можете назвать как вам будет удобно. Я специально вам показываю именно свой вариант языков, что бы вам было проще представить, что на самом деле писанины там не много.

И теперь у нас есть кнопка, которая устанавливает нам нужную локализацию. И есть метод, который проверяет текущую настройку в NSUserDefaults и подгружает нужный нам язык. Что бы язык изменился, нужно закрыть приложение и открыть заново, не свернуть, а именно закрыть его совсем. я еще пока не нашел решения как это сделать на лету, но насколько я понял такое возможно.

Теперь вернемся к нашему многострадальному myLabel.

и заменим строчку на вот такую:

  1. myLabel.text = [self languageSelectedStringForKey:@"Accountt"];

Теперь просто сделайте Run и увидите как текст в myLabel изменится на тот, который указан в вашем файле локализации.

Но если выхотите локализировать ваше приложение, согласно установленному языку в телефоне, например, пользователь изменил настройку интерфейс на русский, то можно прописать вот такую стандартную строчку

  1. myLabel.text = NSLocalizedString(@"Account"nil);

Тогда язык сменится везде на тот который вы указали в телефоне и все строки должны быть именно в таком формате. В таком случае это будет статическая локализация приложения, пока пользователь не изменить интерфейс своего телефона на другой.

Вот такой оказался это простой способ. Терпение и труд, все перетрут.

Happy Coding!

ссылка на оригинал статьи http://habrahabr.ru/post/180765/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *