Pull to refresh

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

Reading time8 min
Views2.3K
Всем привет,

Прошло совсем не много времени, с тех пор как я начал изучать 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.

  1. myLabel.text = @"Account";


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



При нажатии на кнопку происходит именно то что и задумывалось, я устанавливаю язык и записываю его в 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 и подгружает нужный нам язык. Что бы язык изменился, нужно закрыть приложение и открыть заново, не свернуть, а именно закрыть его совсем. Пока я редактировал статью, я нашел для себя как это сделать. в вашем случае может быть по другому. в методе switchLanguages, после добавления в NSUserDefaults, нужно вызвать метод
[self viewDidLoad];
. Тут у каждого может быть индивидуально, но именно там нужно проводить дополнительные действия с приложением. У меня это сработало.

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

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

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


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

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

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


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

Так же важно знать, что локализация — это не только одни строки. я лишь объяснил с простого с чего начать, локализация — это дата и время, картинки и звуковые файлы так же могут быть локализированы. Подробнее про локализацию приложений, можно посмотреть видео с прошлого года WWDC2012 Session #224. Там подробно все объясняют.

Тем кому интересна эта статья, найдут в ней базу по локализации. Это сэкономит им несколько часов, а может и дней на поиск нужного решения. Не ограничивайтесь одним языком, может быть ваше приложение найдет поддержку и в другой стране. А если есть свои методы реализации той же идеи, можете написать свой tutorial млм оставить комментарий с решением. другие обязательно прочтут. И да, всем озлобленным посвящается http://habrahabr.ru/post/178747/

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

Happy Coding!
Tags:
Hubs:
-2
Comments10

Articles

Change theme settings