Автоматизация  локализации iOS-приложений             Андрей Субботин         eploko@yandex-team.ru                      @...
Зачем?         Что это?Как это?         Кто?Яндекс.        СтрашноеПолезное       Забавное           2
Зачем нужналокализация?     3
Cant read,wont buy.     4
52,4% не покупают продукт на чужом                             языке.      60% — для Франции, Японии и                    ...
http://bit.ly/whylocalize            6
Интернационализация   i18n = подготовка продукта к            локализации              7
Локализация      L10n= адаптация продукта к   конкретному языку и            местности          8
Понятный язык интерфейса.      9
Дата и время в привычном формате.              10
Корректная сортировка списков.           11
Поддержка местных единиц измерения.                12
Правильное форматирование чисел.             13
Что локализуется в приложении?       14
Текстовые строки.15
XIB-файлы.16
Изображения, аудио.17
Как приложение  подгружает   ресурсы?      18
19
en.lproj           20
ru.lproj           21
Подготовка строк к локализации       22
NSLocalizedString           = ваш друг!   23
NSLocalizedString(@"key",@"translator comment")               24
NSLog(NSLocalizedString(@"Some sampletext", @"A text string to be output to thelogs."));                     25
2012-03-06 08:10:05.433L10nSample[15433:f803] Some sampletext2012-03-06 08:11:02.117L10nSample[15438:f903] Некийпримерный ...
NSFormatter        = тоже ваш друг!→ Data Formatting Guide   27
Выделение строк       28
*.m → Localizable.strings$ genstrings *.m -o Resources/en.lproj                   29
en.lproj/Localizable.strings/* A text string to be output to the logs. */"Some sample text" = "Some sample text";ru.lproj/...
Выделение строк    из XIB       31
*.xib → *.strings$ ibtool --export-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib               32
en.lproj/ViewController.strings/* Class = "IBUIButton"; normalTitle = "Welcome!";ObjectID = "8"; */"8.normalTitle" = "Welc...
Вмерживание переводов  обратно     34
*.strings → *.xib$ ibtool --import-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib --write en.lpr...
Инкрементальноеобновление XIBов        36
Создали en.XIB.  Локализовали en.XIB → ru.XIB.Добавили новую кнопку в en.XIB.               А теперь что?!          37
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
en.xib → ru.xib$ ibtool--previous-file en.lproj/Window.old.xib--incremental-file ru.lproj/Window.old.xib--strings-file ru....
Храните предыдущие версии XIB файлов.45
Не правьте рукамилокализованные XIB файлы.      46
Переводчики     47
Переводчикипонимают английский. 48
Переводчикине всегда понимают русский.       49
Переводчики не используют Xcodeи не редактируют XIB. 50
ПереводчикиНе знают контекста перевода          без вашей помощи.        51
Как ониработают?    52
Вместе с вами,           но редко.53
Очень часто        по e-mail.54
translations.launchpad.net                +1 к карме        55
Tanker= web-сервис= API для загрузки ивыгрузки переводов           56
Babelfish Yoda   57
Babelyoda           избавляет отрутинной ручной работысводит количество багов      при локализации к              минимуму...
генерирует .strings из кода и XIB’ов          загружает .strings                                в Tanker    забирает из Ta...
Babelyoda= библиотека для работы с .strings,                genstrings и ibtool              60
Babelfile              ...по аналогии сMakefile, Gemfile, Rakefile и т.п.= единое место конфигурации.        61
Babelyoda::Specification.new do |s| s.name = YandexMaps s.development_language = :en s.localization_languages = [:ru, :uk, ...
Babelyoda::Specification.new do |s| s.name = YandexMaps s.development_language = :en s.localization_languages = [:ru, :uk, ...
Babelyoda::Specification.new do |s| s.name = YandexMaps s.development_language = :en s.localization_languages = [:ru, :uk, ...
Babelyoda::Specification.new do |s| s.name = YandexMaps s.development_language = :en s.localization_languages = [:ru, :uk, ...
Babelyoda::Specification.new do |s| s.name = YandexMaps s.development_language = :en s.localization_languages = [:ru, :uk, ...
rake babel yoda$One command to rule      them all!        67
$ rake -Trake babelyodarake babelyoda:create_keysetsrake babelyoda:drop_empty_stringsrake babelyoda:drop_orphan_keysrake b...
yxbuildkit-prebuild.sh#!/bin/bashfunction verify {	 if [ $CONFIGURATION == AppStore ] ; then	 	 rvm rvmrc trust . && rvm r...
Available on GitHub!https://github.com/eploko/babelyoda                 70
Плюрализациях орр ор стори      71
I scanned 12directories.      72
NSLog(@"I scanned %g directories.",      directoryCount);                 73
I scanned 1directories.       74
NSLog(@"I scanned %g %@.",    directoryCount,    directoryCount == 1 ?     @"directory" : @"directories", );              ...
I scanned 1directory.       76
NSLog(     NSLocalizedString(@"I scanned %g %@.", @”Text to show the number ofdirectories scanned”),     dirScanCount,    ...
Как это видитпереводчик?      78
"I scanned %g %@.""directories""directory"                79
"Я просканировал %g %@.""каталоги""папка"             80
Я отсканировал 1папка.       81
Я отсканировал 5каталоги.       82
NSLog(dirScanCount == 1 ?NSLocalizedString("I scanned %g directory.", @”Blah”) :NSLocalizedString("I scanned %g directorie...
“It is more complicated thanyou think.”— The Eighth Networking Truth, from RFC 1925                                 84
NSString *pluralTransfers =NSLocalizedString(@"%d changes",@"The number of changes shown in the route description");      ...
NSString *forms[4] = {0};forms[0] = NSLocalizedString(@"%d change", @"Blah");forms[1] = NSLocalizedString(@"%d changes", @...
int YXPluralFormForRU(NSInteger n){   // One - 1, 21, 31, ...   // Some - 2-4, 22-24, 32-34 ...   // Many - 5-20, 25-30, ....
Как это видитпереводчик?      88
"%d change""%d changes""%d changes""%d changes"              89
NSString *forms[4] = {0};forms[0] = NSLocalizedString(@"NumberChanges0", @"Blah");forms[1] = NSLocalizedString(@"NumberCha...
Как это видитпереводчик?      91
"NumberChanges0""NumberChanges1""NumberChanges2""NumberChanges3"          92
genstrings “магия”        93
NSLocalizedString(@"%[one, some, many, none]d changes",  @"The number of changes shown in the route description");        ...
Localizable.strings/* The number of changes shown in the route description */"%[one]d changes" = "%d changes";"%[some]d ch...
Localizable.strings/* The number of changes shown in the route description */"%[one]d changes" = "%d остановка";"%[some]d ...
NSString *YXPluralFormForRU(NSInteger n){  // One - 1, 21, 31, ...  // Some - 2-4, 22-24, 32-34 ...  // Many - 5-20, 25-30...
NSString *pluralKey = NSLocalizedString(  @"%[one, some, many, none]d changes",  @"The number of changes shown in the rout...
"%[one, some, many, none]d changes"  "%[some]d changes"
“Хитрости”    100
Английский текст в качестве ключаNSLocalizedString(@"Tap Here", @"Action button title");NSLocalizedString(@"TapButtonTitle...
Английский текст в качестве ключа      WelcomeButtonTitle      WelcomeTitle      ButtonTitleWelcome      WelcomeTITLE     ...
Различные контекстыEdit = ПравитьEdit = ИзменитьEdit = Переименовать        103
Различные контекстыNSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)NSLocalizedStringFromTable(@”Edit”,@”Common”,@...
Склеивание строкNSString *part1 = NSLocalizedString(@"People in the room",                     @"Part 1");NSString *part2 ...
Склеивание строкNSLocalizedString(  @"People in the room: %[one, some, many, none]d",  @"Blah blah");                へやへ:5...
Полезные проекты107
Linguan108
Wincent Strings Utility“Merges, extracts andcombines .string files (forincremental localization)”— http://wincent.com/a/pro...
genstrings2“40x faster than genstrings”— http://www.cocoanetics.com/2012/01/genstrings2/                                110
Twine“String Management for iOS,Mac OS X, and AndroidDevelopment”— http://www.mobiata.com/blog/2012/02/08/twine-string-man...
WTF!?  112
WTF!?113
WTF!?114
WTF!?115
WTF!?        116
WTF!?              WTF!?WTF!?        117
WTF!?        118
WTF!?WTF!?WTF!?WTF!?              WTF!?        119
WTF!?         WTF!?        120
Andrey SubbotinВопросы? :-)   eploko@yandex-team.ru                            @eploko
Upcoming SlideShare
Loading in …5
×

Андрей Субботин "Автоматизация локализации iOS-приложений"

1,746 views

Published on

Андрей Субботин рассказал про ужасы локализации и как с ними бороться на пошаговом примере: от «Эврика, нам нужно перевести проект на язык Х!» до «Как не прострелить себе ногу, когда у вас есть Xcode, разработчики, переводчики и дедлайн».

Были рассмотрены все базовые инструментаы локализации (genstrings, ibtool) и способы их использования.

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,746
On SlideShare
0
From Embeds
0
Number of Embeds
768
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Андрей Субботин "Автоматизация локализации iOS-приложений"

  1. 1. Автоматизация локализации iOS-приложений Андрей Субботин eploko@yandex-team.ru @eploko 1
  2. 2. Зачем? Что это?Как это? Кто?Яндекс. СтрашноеПолезное Забавное 2
  3. 3. Зачем нужналокализация? 3
  4. 4. Cant read,wont buy. 4
  5. 5. 52,4% не покупают продукт на чужом языке. 60% — для Франции, Японии и России. 89,3% — если английский знают плохо. 5
  6. 6. http://bit.ly/whylocalize 6
  7. 7. Интернационализация i18n = подготовка продукта к локализации 7
  8. 8. Локализация L10n= адаптация продукта к конкретному языку и местности 8
  9. 9. Понятный язык интерфейса. 9
  10. 10. Дата и время в привычном формате. 10
  11. 11. Корректная сортировка списков. 11
  12. 12. Поддержка местных единиц измерения. 12
  13. 13. Правильное форматирование чисел. 13
  14. 14. Что локализуется в приложении? 14
  15. 15. Текстовые строки.15
  16. 16. XIB-файлы.16
  17. 17. Изображения, аудио.17
  18. 18. Как приложение подгружает ресурсы? 18
  19. 19. 19
  20. 20. en.lproj 20
  21. 21. ru.lproj 21
  22. 22. Подготовка строк к локализации 22
  23. 23. NSLocalizedString = ваш друг! 23
  24. 24. NSLocalizedString(@"key",@"translator comment") 24
  25. 25. NSLog(NSLocalizedString(@"Some sampletext", @"A text string to be output to thelogs.")); 25
  26. 26. 2012-03-06 08:10:05.433L10nSample[15433:f803] Some sampletext2012-03-06 08:11:02.117L10nSample[15438:f903] Некийпримерный текст 26
  27. 27. NSFormatter = тоже ваш друг!→ Data Formatting Guide 27
  28. 28. Выделение строк 28
  29. 29. *.m → Localizable.strings$ genstrings *.m -o Resources/en.lproj 29
  30. 30. 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" = "Некий примерный текст"; 30
  31. 31. Выделение строк из XIB 31
  32. 32. *.xib → *.strings$ ibtool --export-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib 32
  33. 33. en.lproj/ViewController.strings/* Class = "IBUIButton"; normalTitle = "Welcome!";ObjectID = "8"; */"8.normalTitle" = "Welcome!"; 33
  34. 34. Вмерживание переводов обратно 34
  35. 35. *.strings → *.xib$ ibtool --import-strings-file en.lproj/ViewController.strings en.lproj/ViewController.xib --write en.lproj/ViewController.xib 35
  36. 36. Инкрементальноеобновление XIBов 36
  37. 37. Создали en.XIB. Локализовали en.XIB → ru.XIB.Добавили новую кнопку в en.XIB. А теперь что?! 37
  38. 38. 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.xiben.lproj/Window.new.xib 38
  39. 39. 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.xiben.lproj/Window.new.xib 39
  40. 40. 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.xiben.lproj/Window.new.xib 40
  41. 41. 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.xiben.lproj/Window.new.xib 41
  42. 42. 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.xiben.lproj/Window.new.xib 42
  43. 43. 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.xiben.lproj/Window.new.xib 43
  44. 44. 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.xiben.lproj/Window.new.xib 44
  45. 45. Храните предыдущие версии XIB файлов.45
  46. 46. Не правьте рукамилокализованные XIB файлы. 46
  47. 47. Переводчики 47
  48. 48. Переводчикипонимают английский. 48
  49. 49. Переводчикине всегда понимают русский. 49
  50. 50. Переводчики не используют Xcodeи не редактируют XIB. 50
  51. 51. ПереводчикиНе знают контекста перевода без вашей помощи. 51
  52. 52. Как ониработают? 52
  53. 53. Вместе с вами, но редко.53
  54. 54. Очень часто по e-mail.54
  55. 55. translations.launchpad.net +1 к карме 55
  56. 56. Tanker= web-сервис= API для загрузки ивыгрузки переводов 56
  57. 57. Babelfish Yoda 57
  58. 58. Babelyoda избавляет отрутинной ручной работысводит количество багов при локализации к минимуму 58
  59. 59. генерирует .strings из кода и XIB’ов загружает .strings в Tanker забирает из Tanker’а свежие переводы обновляет XIB файлы аккуратно все коммитит в git PROFIT!!
  60. 60. Babelyoda= библиотека для работы с .strings, genstrings и ibtool 60
  61. 61. Babelfile ...по аналогии сMakefile, Gemfile, Rakefile и т.п.= единое место конфигурации. 61
  62. 62. 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 62
  63. 63. 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 63
  64. 64. 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 64
  65. 65. 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 65
  66. 66. 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 66
  67. 67. rake babel yoda$One command to rule them all! 67
  68. 68. $ rake -Trake babelyodarake babelyoda:create_keysetsrake babelyoda:drop_empty_stringsrake babelyoda:drop_orphan_keysrake babelyoda:drop_orphan_keysetsrake babelyoda:extractrake babelyoda:extract_stringsrake babelyoda:extract_xib_stringsrake babelyoda:fetch_stringsrake babelyoda:initBabelfilerake babelyoda:localize_xibsrake babelyoda:pullrake babelyoda:pushrake babelyoda:remote:drop_keysetsrake babelyoda:remote:listrake babelyoda:verify 68
  69. 69. yxbuildkit-prebuild.sh#!/bin/bashfunction 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 69
  70. 70. Available on GitHub!https://github.com/eploko/babelyoda 70
  71. 71. Плюрализациях орр ор стори 71
  72. 72. I scanned 12directories. 72
  73. 73. NSLog(@"I scanned %g directories.", directoryCount); 73
  74. 74. I scanned 1directories. 74
  75. 75. NSLog(@"I scanned %g %@.", directoryCount, directoryCount == 1 ? @"directory" : @"directories", ); 75
  76. 76. I scanned 1directory. 76
  77. 77. NSLog( NSLocalizedString(@"I scanned %g %@.", @”Text to show the number ofdirectories scanned”), dirScanCount, dirScanCount == 1 ? NSLocalizedString(@"directory", @”Single directory”) : NSLocalizedString(@"directories", @”Plural directories”) ); 77
  78. 78. Как это видитпереводчик? 78
  79. 79. "I scanned %g %@.""directories""directory" 79
  80. 80. "Я просканировал %g %@.""каталоги""папка" 80
  81. 81. Я отсканировал 1папка. 81
  82. 82. Я отсканировал 5каталоги. 82
  83. 83. NSLog(dirScanCount == 1 ?NSLocalizedString("I scanned %g directory.", @”Blah”) :NSLocalizedString("I scanned %g directories.", @”Blah”),dirScanCount ); 83
  84. 84. “It is more complicated thanyou think.”— The Eighth Networking Truth, from RFC 1925 84
  85. 85. NSString *pluralTransfers =NSLocalizedString(@"%d changes",@"The number of changes shown in the route description"); 85
  86. 86. 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]; 86
  87. 87. 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; }} 87
  88. 88. Как это видитпереводчик? 88
  89. 89. "%d change""%d changes""%d changes""%d changes" 89
  90. 90. 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]; 90
  91. 91. Как это видитпереводчик? 91
  92. 92. "NumberChanges0""NumberChanges1""NumberChanges2""NumberChanges3" 92
  93. 93. genstrings “магия” 93
  94. 94. NSLocalizedString(@"%[one, some, many, none]d changes", @"The number of changes shown in the route description"); 94
  95. 95. 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"; 95
  96. 96. Localizable.strings/* The number of changes shown in the route description */"%[one]d changes" = "%d остановка";"%[some]d changes" = "%d остановки";"%[many]d changes" = "%d остановок";"%[none]d changes" = ""; 96
  97. 97. NSString *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 @”[one]”; } else if ((n10 > 1) && (n10 < 5) && ((n > 20) || (n < 10))) { return @”[some]”; } else { return @”[many]”; }} 97
  98. 98. NSString *pluralKey = NSLocalizedString( @"%[one, some, many, none]d changes", @"The number of changes shown in the route description");NSString *pluralTransfers = YXLocalizedStringN(pluralKey,self.transfersCount); 98
  99. 99. "%[one, some, many, none]d changes" "%[some]d changes"
  100. 100. “Хитрости” 100
  101. 101. Английский текст в качестве ключаNSLocalizedString(@"Tap Here", @"Action button title");NSLocalizedString(@"TapButtonTitle", @"Action button title"); 101
  102. 102. Английский текст в качестве ключа WelcomeButtonTitle WelcomeTitle ButtonTitleWelcome WelcomeTITLE WelcomeBtnTitle 102
  103. 103. Различные контекстыEdit = ПравитьEdit = ИзменитьEdit = Переименовать 103
  104. 104. Различные контекстыNSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)NSLocalizedStringFromTable(@”Edit”,@”Common”,@”Blah”)NSLocalizedStringFromTable(@”Edit”,@”Buttons”,@”Blah”) 104
  105. 105. Склеивание строк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人 105
  106. 106. Склеивание строкNSLocalizedString( @"People in the room: %[one, some, many, none]d", @"Blah blah"); へやへ:5人 106
  107. 107. Полезные проекты107
  108. 108. Linguan108
  109. 109. Wincent Strings Utility“Merges, extracts andcombines .string files (forincremental localization)”— http://wincent.com/a/products/wincent-strings-util/ 109
  110. 110. genstrings2“40x faster than genstrings”— http://www.cocoanetics.com/2012/01/genstrings2/ 110
  111. 111. Twine“String Management for iOS,Mac OS X, and AndroidDevelopment”— http://www.mobiata.com/blog/2012/02/08/twine-string-management-ios-mac-os-x 111
  112. 112. WTF!? 112
  113. 113. WTF!?113
  114. 114. WTF!?114
  115. 115. WTF!?115
  116. 116. WTF!? 116
  117. 117. WTF!? WTF!?WTF!? 117
  118. 118. WTF!? 118
  119. 119. WTF!?WTF!?WTF!?WTF!? WTF!? 119
  120. 120. WTF!? WTF!? 120
  121. 121. Andrey SubbotinВопросы? :-) eploko@yandex-team.ru @eploko

×