SlideShare a Scribd company logo
Локализации
iOS-приложений
Андрей Субботин
Разработчик, Мобильные Яндекс.Карты (iOS)




Я.Субботник, Минск, 2 июня 2012 года
Can't read,
    won't buy.


2
52,4% не покупают продукт на чужом языке.
    60% — для Франции, Японии и России.
    89,3% — если английский знают плохо.


3
4
http://bit.ly/whylocalize




5
Интернационализация   i18n


    = подготовка продукта к
    локализации


6
Локализация      L10n

    = адаптация продукта к
    конкретному языку и
    местности

7
Локализация                 L10n

    Понятный язык интерфейса.
    Дата и время в привычном формате.
    Корректная сортировка списков.
    Поддержка местных единиц измерения.
    Правильное форматирование чисел.




8
Что локализуется
     в приложении?

    Текстовые строки.
    XIB-файлы.
    Изображения, аудио.


9
Подготовка строк
      к локализации


10
NSLocalizedString

 = ваш друг!




11
NSLog(NSLocalizedString(@"Some sample
     text", @"A text string to be output to the
     logs."));




12
NSLog(NSLocalizedString(@"Some sample
      text", @"A text string to be output to the
      logs."));


     2012-03-06 08:10:05.433
     L10nSample[15433:f803] Some sample
     text
     2012-03-06 08:11:02.117
     L10nSample[15438:f903] Некий
     примерный текст



13
NSFormatter

 = тоже ваш друг!


 →   Data Formatting Guide




14
Выделение строк


15
*.m → Localizable.strings

     $ genstrings *.m -o Resources/en.lproj




16
en.lproj/Localizable.strings
 /* A text string to be output to the logs. */

 "Some sample text" = "Some sample text";




     ru.lproj/Localizable.strings
 /* A text string to be output to the logs. */

 "Some sample text" = "Некий примерный текст";




17
Выделение строк
         из XIB


18
*.xib → *.strings

     $ ibtool --export-strings-file 
     en.lproj/ViewController.strings 
     en.lproj/ViewController.xib




19
en.lproj/ViewController.strings


     /* Class = "IBUIButton"; normalTitle = "Welcome!";
     ObjectID = "8"; */

     "8.normalTitle" = "Welcome!";




20
Вмерживание
      переводов
       обратно

21
*.strings → *.xib

     $ ibtool --import-strings-file 
     en.lproj/ViewController.strings 
     en.lproj/ViewController.xib 
     --write en.lproj/ViewController.xib




22
Инкрементальное
     обновление XIB'ов


23
Создали en.XIB.
     Локализовали en.XIB → ru.XIB.
     Добавили новую кнопку в en.XIB.

      А теперь что?!




24
en.xib → ru.xib
$ ibtool
--previous-file en.lproj/Window.old.xib
--incremental-file ru.lproj/Window.old.xib
--strings-file ru.lproj/Window.strings
--localize-incremental
--write ru.lproj/Window.xib
en.lproj/Window.new.xib


25
Храните предыдущие
     версии XIB файлов.


     Не правьте руками
     локализованные XIB файлы.




26
Переводчики
     Понимают английский.

     Не всегда понимают русский.

     Не используют Xcode
     и не редактируют XIB.

     Не знают контекста перевода
     без вашей помощи.


27
Tanker

     = web-сервис
     = API для загрузки и
     выгрузки переводов

28
Babelfish




      Yoda



29
Babelyoda


     избавляет от
     рутинной ручной работы



     сводит количество багов при
     локализации к минимуму


30
генерирует .strings
        из кода и XIB’ов       загружает .strings
                                        в Tanker

        забирает из Tanker’а
          свежие переводы

                                    обновляет
                                    XIB файлы
          аккуратно все
          коммитит в git
                                 PROFIT!!
31
Babelyoda


     = библиотека для работы с .strings,
     genstrings и ibtool




32
Babelfile
     ...по аналогии с
     Makefile, Gemfile, Rakefile и т.п.

     = единое место конфигурации.




33
Babelyoda::Specification.new do |s|
   s.name = 'YandexMaps'

     s.development_language = :en
     s.localization_languages = [:ru, :uk, :tr]

     s.engine = Babelyoda::Tanker.new do |t|
       t.token = ENV['TANKER_TOKEN']
       t.project_id = 'myak_iphone'
       t.endpoint = ENV['TANKER_HOST']
     end


     s.scm = Babelyoda::Git.new

   s.source_files = FileList['{Classes,Shared}/**/*.{m,mm,h}']
   s.resources_folder = 'Resources'
   s.xib_files = FileList['Resources/**/en.lproj/*.xib']
   s.strings_files = FileList['Resources/**/en.lproj/*.strings']
 end
34
rake babel yoda
     $


     One command to rule
           them all!

35
$ rake -T
rake babelyoda
rake babelyoda:create_keysets
rake babelyoda:drop_empty_strings
rake babelyoda:drop_orphan_keys
rake babelyoda:drop_orphan_keysets
rake babelyoda:extract
rake babelyoda:extract_strings
rake babelyoda:extract_xib_strings
rake babelyoda:fetch_strings
rake babelyoda:initBabelfile
rake babelyoda:localize_xibs
rake babelyoda:pull
rake babelyoda:push
rake babelyoda:remote:drop_keysets
rake babelyoda:remote:list
rake babelyoda:verify


36
yxbuildkit-prebuild.sh



     #!/bin/bash

     function verify {
     	 if [ $CONFIGURATION == 'AppStore' ] ; then
     	 	 rvm rvmrc trust . && rvm rvmrc load . && bundle 
                           && bundle exec rake babelyoda:verify
     	 	 return $?
     	 fi
     	 return 0
     }
     	
     git submodule update --init --recursive && verify

37
Available on GitHub!


     http://bit.ly/yandextool




38
Плюрализация

     х орр ор стори


39
I scanned 12
     directories.



40
NSLog(@"I scanned %g directories.",
           directoryCount);




41
I scanned 1
     directories.



42
NSLog(@"I scanned %g %@.",
         directoryCount,
         directoryCount == 1 ?
          @"directory" : @"directories",
      );



43
I scanned 1
     directory.



44
NSLog(
          NSLocalizedString(@"I scanned %g %@.", @”Text to show the number of
     directories scanned”),
          dirScanCount,
          dirScanCount == 1 ?
            NSLocalizedString(@"directory", @”Single directory”) :
            NSLocalizedString(@"directories", @”Plural directories”)
      );




45
Как это видит
     переводчик?




46
"I scanned %g %@." "Я просканировал
                   %g %@."


"directories"     "каталоги"



"directory"       "папка"


47
Я отсканировал 1
     папка.



48
Я отсканировал 5
     каталоги.



49
NSLog(
dirScanCount == 1 ?
NSLocalizedString("I scanned %g directory.", @”Blah”) :
NSLocalizedString("I scanned %g directories.", @”Blah”),
dirScanCount );




50
NSString *pluralTransfers =
NSLocalizedString(@"%d changes",
@"The number of changes shown in the route description");




51
NSString *forms[4] = {0};
     forms[0] = NSLocalizedString(@"%d change", @"Blah");
     forms[1] = NSLocalizedString(@"%d changes", @"Blah");
     forms[2] = NSLocalizedString(@"%d changes", @"Blah");
     forms[3] = NSLocalizedString(@"%d changes", @"Blah");

     int form = YXPluralFormForN(self.transfersCount);
     NSString *pluralTransfers = forms[i];




52
int YXPluralFormForRU(NSInteger n)
 {
    // One - 1, 21, 31, ...
    // Some - 2-4, 22-24, 32-34 ...
    // Many - 5-20, 25-30, ...
    NSInteger n10 = n % 10;
    if ((n10 == 1) && ((n == 1) || (n > 20))) {
        return 0;
    } else if ((n10 > 1) && (n10 < 5) && ((n > 20) || (n < 10))) {
        return 1;
    } else {
        return 2;
    }
 }




53
Как это видит
     переводчик?




54
"%d change"

     "%d changes"

     "%d changes"

     "%d changes"



55
NSString *forms[4] = {0};
     forms[0] = NSLocalizedString(@"NumberChanges0", @"Blah");
     forms[1] = NSLocalizedString(@"NumberChanges1", @"Blah");
     forms[2] = NSLocalizedString(@"NumberChanges2", @"Blah");
     forms[3] = NSLocalizedString(@"NumberChanges3", @"Blah");

     int form = YXPluralFormForN(self.transfersCount);
     NSString *pluralTransfers = forms[i];




56
Как это видит
     переводчик?




57
"NumberChanges0"

     "NumberChanges1"

     "NumberChanges2"

     "NumberChanges3"




58
genstrings “магия”


59
NSLocalizedString(@"%[one, some, many, none]d changes",
  @"The number of changes shown in the route description");




60
Localizable.strings


     /* The number of changes shown in the route description */
     "%[one]d changes" = "%d changes";
     "%[some]d changes" = "%d changes";
     "%[many]d changes" = "%d changes";
     "%[none]d changes" = "%d changes";

     /* The number of changes shown in the route description */
     "%[one]d changes" = "%d остановка";
     "%[some]d changes" = "%d остановки";
     "%[many]d changes" = "%d остановок";
     "%[none]d changes" = "";

61
"%[one, some, many, none]d changes"




       "%[some]d changes"


62
“Хитрости”


63
Английский текст в качестве ключа


     NSLocalizedString(@"Tap Here", @"Action button title");

     NSLocalizedString(@"TapButtonTitle", @"Action button title");




64
Английский текст в качестве ключа



           WelcomeButtonTitle
           WelcomeTitle
           ButtonTitleWelcome
           WelcomeTITLE
           WelcomeBtnTitle


65
Различные контексты




     Edit = Править
     Edit = Изменить
     Edit = Переименовать



66
Различные контексты



     NSLocalizedStringFromTable
     (<#key#>, <#tbl#>, <#comment#>)

     NSLocalizedStringFromTable
     (@”Edit”,@”Common”,@”Blah”)

     NSLocalizedStringFromTable
     (@”Edit”,@”Buttons”,@”Blah”)


67
Склеивание строк


     NSString *part1 = NSLocalizedString(@"People in the room",
                          @"Part 1");
     NSString *part2 = NSLocalizedString(@"%d", @"Part 2");
     NSString *halfResult = [NSString stringWithFormat:@"%@: %@",
                   part1, part2];
     NSString *result = [NSString stringWithFormat:halfResult, 5];




                     へやへ:5人
68
Склеивание строк



     NSLocalizedString(
       @"People in the room: %[one, some, many, none]d",
       @"Blah blah");




                     へやへ:5人
69
WTF!?




70
WTF!?




71
WTF!?




72
WTF!?




73
WTF!?




74
WTF!?
             WTF!?




     WTF!?


75
WTF!?




76
WTF!?   WTF!?
77
Андрей Субботин
Разработчик,
Мобильные Яндекс.Карты (iOS)

eploko@yandex-team.ru

@eploko

More Related Content

What's hot

SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON
 
Perl – жив?!
Perl – жив?!Perl – жив?!
Perl – жив?!
Anatoly Sharifulin
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Tanya Denisyuk
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9Technopark
 
Romanova techforum bash
Romanova techforum bashRomanova techforum bash
Romanova techforum bashkuchinskaya
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
Python Meetup
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после Java
Olim Saidov
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Timur Safin
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Ontico
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?
Ivan Tsyganov
 
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Timur Shemsedinov
 
Hacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данныхHacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данных
Anastasia Lubennikova
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...Ontico
 
Web осень 2013 лекция 3
Web осень 2013 лекция 3Web осень 2013 лекция 3
Web осень 2013 лекция 3Technopark
 
Perl 5.10 и 5.12
Perl 5.10 и 5.12Perl 5.10 и 5.12
Perl 5.10 и 5.12
Andrew Shitov
 
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Ontico
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Web осень 2013 лекция 1
Web осень 2013 лекция 1Web осень 2013 лекция 1
Web осень 2013 лекция 1Technopark
 

What's hot (20)

SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/LinuxSECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
SECON'2017, Клементьев Михаил, Обнаружение руткитов в GNU/Linux
 
Perl – жив?!
Perl – жив?!Perl – жив?!
Perl – жив?!
 
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
Андрей Дроздов "Создание высокопроизводительных rest api на tarantool"
 
Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9
 
Romanova techforum bash
Romanova techforum bashRomanova techforum bash
Romanova techforum bash
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после Java
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
 
PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?PiterPy#3. DSL in Python. How and why?
PiterPy#3. DSL in Python. How and why?
 
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Hacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данныхHacking PostgreSQL. Физическое представление данных
Hacking PostgreSQL. Физическое представление данных
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
12 вариантов использования Redis — в Tarantool (Александр Календарев, Констан...
 
Web осень 2013 лекция 3
Web осень 2013 лекция 3Web осень 2013 лекция 3
Web осень 2013 лекция 3
 
Perl 5.10 и 5.12
Perl 5.10 и 5.12Perl 5.10 и 5.12
Perl 5.10 и 5.12
 
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
Хранение json-документов в Tarantool / Андрей Дроздов (Mail.ru Group)
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Web осень 2013 лекция 1
Web осень 2013 лекция 1Web осень 2013 лекция 1
Web осень 2013 лекция 1
 

Similar to Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"

Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Yandex
 
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Yandex
 
Sphinx. настройка, эксплуатация
Sphinx. настройка, эксплуатацияSphinx. настройка, эксплуатация
Sphinx. настройка, эксплуатацияandreyborue
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
Глеб Тарасов
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDB
Dmitry Viskov
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
DevGAMM Conference
 
Haskell
HaskellHaskell
Haskell
DevDay
 
Haskell Lite - presentation for DevDay about Haskell language
Haskell Lite - presentation for DevDay about Haskell languageHaskell Lite - presentation for DevDay about Haskell language
Haskell Lite - presentation for DevDay about Haskell language
Alexander Granin
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...phpdevby
 
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API: SyntaxTree vs CodeDom, SemanticModel vs ReflectionRoslyn API: SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Denis Tsvettsih
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
Tech Talks @NSU
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоStanfy
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"
Yandex
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
Яковенко Кирилл
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
Alexander Granin
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Ontico
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
Anton Kirillov
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Yandex
 

Similar to Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу" (20)

Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
Владимир Алаев "Разработка на Node.js: инструменты, библиотеки, сервисы"
 
Sphinx. настройка, эксплуатация
Sphinx. настройка, эксплуатацияSphinx. настройка, эксплуатация
Sphinx. настройка, эксплуатация
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Cтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDBCтрах и ненависть в MongoDB
Cтрах и ненависть в MongoDB
 
Convert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at VizorConvert this: peculiarities of cross-platform mobile game development at Vizor
Convert this: peculiarities of cross-platform mobile game development at Vizor
 
Haskell
HaskellHaskell
Haskell
 
Haskell Lite - presentation for DevDay about Haskell language
Haskell Lite - presentation for DevDay about Haskell languageHaskell Lite - presentation for DevDay about Haskell language
Haskell Lite - presentation for DevDay about Haskell language
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
 
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API: SyntaxTree vs CodeDom, SemanticModel vs ReflectionRoslyn API: SyntaxTree vs CodeDom, SemanticModel vs Reflection
Roslyn API : SyntaxTree vs CodeDom, SemanticModel vs Reflection
 
Tech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVMTech Talks @NSU: Как приручить дракона: введение в LLVM
Tech Talks @NSU: Как приручить дракона: введение в LLVM
 
Как приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVMКак приручить дракона: введение в LLVM
Как приручить дракона: введение в LLVM
 
Фундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел ТайкалоФундаментальные основы разработки под iOS. Павел Тайкало
Фундаментальные основы разработки под iOS. Павел Тайкало
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"
 
Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3Лекция #5. Введение в язык программирования Python 3
Лекция #5. Введение в язык программирования Python 3
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 

More from Yandex

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
Yandex
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Yandex
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Yandex
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Yandex
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Yandex
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Yandex
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Yandex
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Yandex
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Yandex
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Yandex
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Yandex
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Yandex
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Yandex
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Yandex
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Yandex
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Yandex
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Yandex
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Yandex
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Yandex
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Yandex
 

More from Yandex (20)

Предсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of TanksПредсказание оттока игроков из World of Tanks
Предсказание оттока игроков из World of Tanks
 
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
Как принять/организовать работу по поисковой оптимизации сайта, Сергей Царик,...
 
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров ЯндексаСтруктурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
Структурированные данные, Юлия Тихоход, лекция в Школе вебмастеров Яндекса
 
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров ЯндексаПредставление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
Представление сайта в поиске, Сергей Лысенко, лекция в Школе вебмастеров Яндекса
 
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
Плохие методы продвижения сайта, Екатерины Гладких, лекция в Школе вебмастеро...
 
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
Основные принципы ранжирования, Сергей Царик и Антон Роменский, лекция в Школ...
 
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
Основные принципы индексирования сайта, Александр Смирнов, лекция в Школе веб...
 
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
Мобильное приложение: как и зачем, Александр Лукин, лекция в Школе вебмастеро...
 
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
Сайты на мобильных устройствах, Олег Ножичкин, лекция в Школе вебмастеров Янд...
 
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
Качественная аналитика сайта, Юрий Батиевский, лекция в Школе вебмастеров Янд...
 
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
Что можно и что нужно измерять на сайте, Петр Аброськин, лекция в Школе вебма...
 
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
Как правильно поставить ТЗ на создание сайта, Алексей Бородкин, лекция в Школ...
 
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеровКак защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
Как защитить свой сайт, Пётр Волков, лекция в Школе вебмастеров
 
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
Как правильно составить структуру сайта, Дмитрий Сатин, лекция в Школе вебмас...
 
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
Технические особенности создания сайта, Дмитрий Васильева, лекция в Школе веб...
 
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
Конструкторы для отдельных элементов сайта, Елена Першина, лекция в Школе веб...
 
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
Контент для интернет-магазинов, Катерина Ерошина, лекция в Школе вебмастеров ...
 
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
Как написать хороший текст для сайта, Катерина Ерошина, лекция в Школе вебмас...
 
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
Usability и дизайн - как не помешать пользователю, Алексей Иванов, лекция в Ш...
 
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
Cайт. Зачем он и каким должен быть, Алексей Иванов, лекция в Школе вебмастеро...
 

Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"

  • 1. Локализации iOS-приложений Андрей Субботин Разработчик, Мобильные Яндекс.Карты (iOS) Я.Субботник, Минск, 2 июня 2012 года
  • 2. Can't read, won't buy. 2
  • 3. 52,4% не покупают продукт на чужом языке. 60% — для Франции, Японии и России. 89,3% — если английский знают плохо. 3
  • 4. 4
  • 6. Интернационализация i18n = подготовка продукта к локализации 6
  • 7. Локализация L10n = адаптация продукта к конкретному языку и местности 7
  • 8. Локализация L10n Понятный язык интерфейса. Дата и время в привычном формате. Корректная сортировка списков. Поддержка местных единиц измерения. Правильное форматирование чисел. 8
  • 9. Что локализуется в приложении? Текстовые строки. XIB-файлы. Изображения, аудио. 9
  • 10. Подготовка строк к локализации 10
  • 12. NSLog(NSLocalizedString(@"Some sample text", @"A text string to be output to the logs.")); 12
  • 13. NSLog(NSLocalizedString(@"Some sample text", @"A text string to be output to the logs.")); 2012-03-06 08:10:05.433 L10nSample[15433:f803] Some sample text 2012-03-06 08:11:02.117 L10nSample[15438:f903] Некий примерный текст 13
  • 14. NSFormatter = тоже ваш друг! → Data Formatting Guide 14
  • 16. *.m → Localizable.strings $ genstrings *.m -o Resources/en.lproj 16
  • 17. en.lproj/Localizable.strings /* A text string to be output to the logs. */ "Some sample text" = "Some sample text"; ru.lproj/Localizable.strings /* A text string to be output to the logs. */ "Some sample text" = "Некий примерный текст"; 17
  • 19. *.xib → *.strings $ ibtool --export-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib 19
  • 20. en.lproj/ViewController.strings /* Class = "IBUIButton"; normalTitle = "Welcome!"; ObjectID = "8"; */ "8.normalTitle" = "Welcome!"; 20
  • 21. Вмерживание переводов обратно 21
  • 22. *.strings → *.xib $ ibtool --import-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib --write en.lproj/ViewController.xib 22
  • 23. Инкрементальное обновление XIB'ов 23
  • 24. Создали en.XIB. Локализовали en.XIB → ru.XIB. Добавили новую кнопку в en.XIB. А теперь что?! 24
  • 25. en.xib → ru.xib $ ibtool --previous-file en.lproj/Window.old.xib --incremental-file ru.lproj/Window.old.xib --strings-file ru.lproj/Window.strings --localize-incremental --write ru.lproj/Window.xib en.lproj/Window.new.xib 25
  • 26. Храните предыдущие версии XIB файлов. Не правьте руками локализованные XIB файлы. 26
  • 27. Переводчики Понимают английский. Не всегда понимают русский. Не используют Xcode и не редактируют XIB. Не знают контекста перевода без вашей помощи. 27
  • 28. Tanker = web-сервис = API для загрузки и выгрузки переводов 28
  • 29. Babelfish Yoda 29
  • 30. Babelyoda избавляет от рутинной ручной работы сводит количество багов при локализации к минимуму 30
  • 31. генерирует .strings из кода и XIB’ов загружает .strings в Tanker забирает из Tanker’а свежие переводы обновляет XIB файлы аккуратно все коммитит в git PROFIT!! 31
  • 32. Babelyoda = библиотека для работы с .strings, genstrings и ibtool 32
  • 33. Babelfile ...по аналогии с Makefile, Gemfile, Rakefile и т.п. = единое место конфигурации. 33
  • 34. Babelyoda::Specification.new do |s| s.name = 'YandexMaps' s.development_language = :en s.localization_languages = [:ru, :uk, :tr] s.engine = Babelyoda::Tanker.new do |t| t.token = ENV['TANKER_TOKEN'] t.project_id = 'myak_iphone' t.endpoint = ENV['TANKER_HOST'] end s.scm = Babelyoda::Git.new s.source_files = FileList['{Classes,Shared}/**/*.{m,mm,h}'] s.resources_folder = 'Resources' s.xib_files = FileList['Resources/**/en.lproj/*.xib'] s.strings_files = FileList['Resources/**/en.lproj/*.strings'] end 34
  • 35. rake babel yoda $ One command to rule them all! 35
  • 36. $ rake -T rake babelyoda rake babelyoda:create_keysets rake babelyoda:drop_empty_strings rake babelyoda:drop_orphan_keys rake babelyoda:drop_orphan_keysets rake babelyoda:extract rake babelyoda:extract_strings rake babelyoda:extract_xib_strings rake babelyoda:fetch_strings rake babelyoda:initBabelfile rake babelyoda:localize_xibs rake babelyoda:pull rake babelyoda:push rake babelyoda:remote:drop_keysets rake babelyoda:remote:list rake babelyoda:verify 36
  • 37. yxbuildkit-prebuild.sh #!/bin/bash function verify { if [ $CONFIGURATION == 'AppStore' ] ; then rvm rvmrc trust . && rvm rvmrc load . && bundle && bundle exec rake babelyoda:verify return $? fi return 0 } git submodule update --init --recursive && verify 37
  • 38. Available on GitHub! http://bit.ly/yandextool 38
  • 39. Плюрализация х орр ор стори 39
  • 40. I scanned 12 directories. 40
  • 41. NSLog(@"I scanned %g directories.", directoryCount); 41
  • 42. I scanned 1 directories. 42
  • 43. NSLog(@"I scanned %g %@.", directoryCount, directoryCount == 1 ? @"directory" : @"directories", ); 43
  • 44. I scanned 1 directory. 44
  • 45. NSLog( NSLocalizedString(@"I scanned %g %@.", @”Text to show the number of directories scanned”), dirScanCount, dirScanCount == 1 ? NSLocalizedString(@"directory", @”Single directory”) : NSLocalizedString(@"directories", @”Plural directories”) ); 45
  • 46. Как это видит переводчик? 46
  • 47. "I scanned %g %@." "Я просканировал %g %@." "directories" "каталоги" "directory" "папка" 47
  • 49. Я отсканировал 5 каталоги. 49
  • 50. NSLog( dirScanCount == 1 ? NSLocalizedString("I scanned %g directory.", @”Blah”) : NSLocalizedString("I scanned %g directories.", @”Blah”), dirScanCount ); 50
  • 51. NSString *pluralTransfers = NSLocalizedString(@"%d changes", @"The number of changes shown in the route description"); 51
  • 52. NSString *forms[4] = {0}; forms[0] = NSLocalizedString(@"%d change", @"Blah"); forms[1] = NSLocalizedString(@"%d changes", @"Blah"); forms[2] = NSLocalizedString(@"%d changes", @"Blah"); forms[3] = NSLocalizedString(@"%d changes", @"Blah"); int form = YXPluralFormForN(self.transfersCount); NSString *pluralTransfers = forms[i]; 52
  • 53. int YXPluralFormForRU(NSInteger n) { // One - 1, 21, 31, ... // Some - 2-4, 22-24, 32-34 ... // Many - 5-20, 25-30, ... NSInteger n10 = n % 10; if ((n10 == 1) && ((n == 1) || (n > 20))) { return 0; } else if ((n10 > 1) && (n10 < 5) && ((n > 20) || (n < 10))) { return 1; } else { return 2; } } 53
  • 54. Как это видит переводчик? 54
  • 55. "%d change" "%d changes" "%d changes" "%d changes" 55
  • 56. NSString *forms[4] = {0}; forms[0] = NSLocalizedString(@"NumberChanges0", @"Blah"); forms[1] = NSLocalizedString(@"NumberChanges1", @"Blah"); forms[2] = NSLocalizedString(@"NumberChanges2", @"Blah"); forms[3] = NSLocalizedString(@"NumberChanges3", @"Blah"); int form = YXPluralFormForN(self.transfersCount); NSString *pluralTransfers = forms[i]; 56
  • 57. Как это видит переводчик? 57
  • 58. "NumberChanges0" "NumberChanges1" "NumberChanges2" "NumberChanges3" 58
  • 60. NSLocalizedString(@"%[one, some, many, none]d changes", @"The number of changes shown in the route description"); 60
  • 61. Localizable.strings /* The number of changes shown in the route description */ "%[one]d changes" = "%d changes"; "%[some]d changes" = "%d changes"; "%[many]d changes" = "%d changes"; "%[none]d changes" = "%d changes"; /* The number of changes shown in the route description */ "%[one]d changes" = "%d остановка"; "%[some]d changes" = "%d остановки"; "%[many]d changes" = "%d остановок"; "%[none]d changes" = ""; 61
  • 62. "%[one, some, many, none]d changes" "%[some]d changes" 62
  • 64. Английский текст в качестве ключа NSLocalizedString(@"Tap Here", @"Action button title"); NSLocalizedString(@"TapButtonTitle", @"Action button title"); 64
  • 65. Английский текст в качестве ключа WelcomeButtonTitle WelcomeTitle ButtonTitleWelcome WelcomeTITLE WelcomeBtnTitle 65
  • 66. Различные контексты Edit = Править Edit = Изменить Edit = Переименовать 66
  • 67. Различные контексты NSLocalizedStringFromTable (<#key#>, <#tbl#>, <#comment#>) NSLocalizedStringFromTable (@”Edit”,@”Common”,@”Blah”) NSLocalizedStringFromTable (@”Edit”,@”Buttons”,@”Blah”) 67
  • 68. Склеивание строк NSString *part1 = NSLocalizedString(@"People in the room", @"Part 1"); NSString *part2 = NSLocalizedString(@"%d", @"Part 2"); NSString *halfResult = [NSString stringWithFormat:@"%@: %@", part1, part2]; NSString *result = [NSString stringWithFormat:halfResult, 5]; へやへ:5人 68
  • 69. Склеивание строк NSLocalizedString( @"People in the room: %[one, some, many, none]d", @"Blah blah"); へやへ:5人 69
  • 75. WTF!? WTF!? WTF!? 75
  • 77. WTF!? WTF!? 77