├── LICENSE ├── README.md ├── TTTLocalizedPluralString.h ├── TTTLocalizedPluralString.m └── TTTLocalizedPluralString.podspec /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 – 2018 Mattt (https://mat.tt/) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TTTLocalizedPluralString 2 | 3 | ## NSLocalizedString with a Count Argument 4 | 5 | > As of iOS 7 and Mac OS X 10.9 Mavericks, Foundation has the ability to specify localized strings according to pluralization and grammar rules. You can find more information about it in the [Localized Property List File](https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/#//apple_ref/doc/uid/TP30000742-CH2-SW56) section of the Foundation release notes. 6 | 7 | --- 8 | 9 | `NSLocalizedString` and its related macros make localizing Mac and iOS applications relatively straight-forward and simple. It falls down, however, when having to deal with strings whose conjugations change based on a dynamic count value. In such cases, you may have seen code like this: 10 | 11 | ```objective-c 12 | if (count == 1) { 13 | return NSLocalizedString(@"1 Person", nil); 14 | } else { 15 | return [NSString stringWithFormat:NSLocalizedString(@"%d People", nil), count]; 16 | } 17 | ``` 18 | 19 | While this works alright for English, you run into problems when targeting other locales. Consider some examples as described in the [Unicode Language Plural Rules](http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html): 20 | 21 | * Many Asian languages, like Japanese, Korean, Thai, and Simplified Chinese, do not have plural forms of nouns 22 | * Arabic has several plural forms, including rules for zero, one, two, as well as few, many, and other, which are determined using a rather complicated base 10 divmod operation to determine the parity. 23 | 24 | Fortunately, `TTTLocalizedPluralString` figures all of this out for you. You can use it just as you would `NSLocalizedString`, only in this case, you also have an argument for count. Here is the example from before, this time using `TTTLocalizedPluralString`. 25 | 26 | ```objective-c 27 | return TTTLocalizedPluralString(count, @"Person", nil); 28 | ``` 29 | 30 | This macro points to a function that determines the plural rule for the current locale, and then does an `NSBundle` localized string lookup for the corresponding value. In this case, `en.lproj/Localizable.strings` would have two keys for this: `%d Person (plural rule: one)` and `%d Person (plural rule: other)`. Other localizations would only require the keys used by that language (e.g. 1 for Japanese, and 6 for Arabic). 31 | 32 | Here is the full list of plural rules: 33 | 34 | * `zero` 35 | * `one` 36 | * `two` 37 | * `few` 38 | * `many` 39 | * `other` 40 | 41 | ## Supported Locales 42 | 43 | * Arabic (`ar`) 44 | * Bulgarian (`bg`) 45 | * Catalan (`ca`) 46 | * Chinese (Simplified) (`zh-Hans`) 47 | * Chinese (Traditional) (`zh-Hant`) 48 | * Croatian (`cr`) 49 | * Czech (`cs`) 50 | * Danish (`da`) 51 | * Dutch (`nl`) 52 | * English (`en`) 53 | * German (`de`) 54 | * Finish (`fi`) 55 | * Greek (`el`) 56 | * French (`fr`) 57 | * Hebrew (`he`) 58 | * Hungarian (`hu`) 59 | * Indonesian (`id`) 60 | * Italian (`it`) 61 | * Japanese (`ja`) 62 | * Korean (`ko`) 63 | * Latvian (`lv`) 64 | * Malay (`ms`) 65 | * Norwegian Bokmål (`nb`) 66 | * Norwegian Nynorsk (`nn`) 67 | * Polish (`pl`) 68 | * Portuguese (`pt`) 69 | * Romanian (`ro`) 70 | * Russian (`ru`) 71 | * Serbian (`sr`) 72 | * Spanish (`es`) 73 | * Slovak (`sk`) 74 | * Slovenian (`sl`) 75 | * Swedish (`sv`) 76 | * Thai (`th`) 77 | * Turkish (`tr`) 78 | * Ukrainian (`uk`) 79 | * Vietnamese (`vi`) 80 | 81 | --- 82 | 83 | ## Contact 84 | 85 | [Mattt](http://twitter.com/mattt) 86 | 87 | ## License 88 | 89 | TTTLocalizedPluralString is available under the MIT license. 90 | See the LICENSE file for more info. 91 | -------------------------------------------------------------------------------- /TTTLocalizedPluralString.h: -------------------------------------------------------------------------------- 1 | // TTTLocalizedPluralString.h 2 | // 3 | // Copyright (c) 2011 – 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | 25 | extern NSString * TTTLocalizedPluralStringKeyForCountAndSingularNoun(NSUInteger count, NSString *singular); 26 | extern NSString * TTTLocalizedPluralStringKeyForCountAndSingularNounForLanguage(NSUInteger count, NSString *singular, NSString *languageCode); 27 | 28 | #define TTTLocalizedPluralString(count, singular, comment) \ 29 | [NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:TTTLocalizedPluralStringKeyForCountAndSingularNoun(count, singular) value:@"" table:nil], count] 30 | 31 | #define TTTLocalizedPluralStringForLanguage(count, singular, languageCode) \ 32 | [NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:TTTLocalizedPluralStringKeyForCountAndSingularNounForLanguage(count, singular, languageCode) value:@"" table:nil], count] 33 | 34 | #define TTTLocalizedPluralStringFromTable(count, singular, tbl, comment) \ 35 | [NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:TTTLocalizedPluralStringKeyForCountAndSingularNoun(count, singular) value:@"" table:(tbl)], count] 36 | 37 | #define TTTLocalizedPluralStringFromTableInBundle(count, singular, tbl, bundle, comment) \ 38 | [NSString stringWithFormat:[bundle localizedStringForKey:TTTLocalizedPluralStringKeyForCountAndSingularNoun(count, singular) value:@"" table:(tbl)], count] 39 | 40 | #define TTTLocalizedPluralStringWithDefaultValue(count, singular, tbl, bundle, val, comment) \ 41 | [NSString stringWithFormat:[bundle localizedStringForKey:TTTLocalizedPluralStringKeyForCountAndSingularNoun(count, singular) value:(val) table:(tbl)], count] 42 | -------------------------------------------------------------------------------- /TTTLocalizedPluralString.m: -------------------------------------------------------------------------------- 1 | // TTTLocalizedPluralString.m 2 | // 3 | // Copyright (c) 2011 – 2018 Mattt (https://mat.tt) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import "TTTLocalizedPluralString.h" 24 | 25 | // Source: Unicode Common Locale Data Repository Plural Rules 26 | // http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html 27 | 28 | static NSString * const kTTTZeroPluralRule = @"zero"; 29 | static NSString * const kTTTOnePluralRule = @"one"; 30 | static NSString * const kTTTTwoPluralRule = @"two"; 31 | static NSString * const kTTTFewPluralRule = @"few"; 32 | static NSString * const kTTTManyPluralRule = @"many"; 33 | static NSString * const kTTTOtherPluralRule = @"other"; 34 | 35 | static NSString * TTTArabicPluralRuleForCount(NSUInteger count) { 36 | switch (count) { 37 | case 0: 38 | return kTTTZeroPluralRule; 39 | case 1: 40 | return kTTTOnePluralRule; 41 | case 2: 42 | return kTTTTwoPluralRule; 43 | default: { 44 | NSUInteger mod100 = count % 100; 45 | if (mod100 >= 3 && mod100 <= 10) { 46 | return kTTTFewPluralRule; 47 | } else if (mod100 >= 11) { 48 | return kTTTManyPluralRule; 49 | } else { 50 | return kTTTOtherPluralRule; 51 | } 52 | } 53 | } 54 | } 55 | 56 | static NSString * TTTBulgarianPluralRuleForCount(NSUInteger count) { 57 | switch (count) { 58 | case 1: 59 | return kTTTOnePluralRule; 60 | default: { 61 | return kTTTOtherPluralRule; 62 | } 63 | } 64 | } 65 | 66 | static NSString * TTTSimplifiedChinesePluralRuleForCount(NSUInteger count) { 67 | return kTTTOtherPluralRule; 68 | } 69 | 70 | static NSString * TTTTraditionalChinesePluralRuleForCount(NSUInteger count) { 71 | return kTTTOtherPluralRule; 72 | } 73 | 74 | static NSString * TTTCatalanPluralRuleForCount(NSUInteger count) { 75 | switch (count) { 76 | case 1: 77 | return kTTTOnePluralRule; 78 | default: 79 | return kTTTOtherPluralRule; 80 | } 81 | } 82 | 83 | static NSString * TTTCroatianPluralRuleForCount(NSUInteger count) { 84 | NSUInteger mod10 = count % 10; 85 | NSUInteger mod100 = count % 100; 86 | 87 | switch (mod10) { 88 | case 1: 89 | switch (mod100) { 90 | case 11: 91 | break; 92 | default: 93 | return kTTTOnePluralRule; 94 | } 95 | case 2: 96 | case 3: 97 | case 4: 98 | switch (mod100) { 99 | case 12: 100 | case 13: 101 | case 14: 102 | break; 103 | default: 104 | return kTTTFewPluralRule; 105 | } 106 | 107 | break; 108 | default: 109 | break; 110 | } 111 | 112 | return kTTTManyPluralRule; 113 | } 114 | 115 | static NSString * TTTCzechPluralRuleForCount(NSUInteger count) { 116 | switch (count) { 117 | case 1: 118 | return kTTTOnePluralRule; 119 | case 2: 120 | case 3: 121 | case 4: 122 | return kTTTFewPluralRule; 123 | default: 124 | return kTTTOtherPluralRule; 125 | } 126 | } 127 | 128 | static NSString * TTTEnglishPluralRuleForCount(NSUInteger count) { 129 | switch (count) { 130 | case 1: 131 | return kTTTOnePluralRule; 132 | default: 133 | return kTTTOtherPluralRule; 134 | } 135 | } 136 | 137 | static NSString * TTTFrenchPluralRuleForCount(NSUInteger count) { 138 | switch (count) { 139 | case 0: 140 | case 1: 141 | return kTTTOnePluralRule; 142 | default: 143 | return kTTTOtherPluralRule; 144 | } 145 | } 146 | 147 | static NSString * TTTGermanPluralRuleForCount(NSUInteger count) { 148 | switch (count) { 149 | case 1: 150 | return kTTTOnePluralRule; 151 | default: 152 | return kTTTOtherPluralRule; 153 | } 154 | } 155 | 156 | static NSString * TTTDanishPluralRuleForCount(NSUInteger count) { 157 | switch (count) { 158 | case 1: 159 | return kTTTOnePluralRule; 160 | default: 161 | return kTTTOtherPluralRule; 162 | } 163 | } 164 | 165 | static NSString * TTTDutchPluralRuleForCount(NSUInteger count) { 166 | switch (count) { 167 | case 1: 168 | return kTTTOnePluralRule; 169 | default: 170 | return kTTTOtherPluralRule; 171 | } 172 | } 173 | 174 | static NSString * TTTFinnishPluralRuleForCount(NSUInteger count) { 175 | switch (count) { 176 | case 1: 177 | return kTTTOnePluralRule; 178 | default: 179 | return kTTTOtherPluralRule; 180 | } 181 | } 182 | 183 | static NSString * TTTGreekPluralRuleForCount(NSUInteger count) { 184 | switch (count) { 185 | case 1: 186 | return kTTTOnePluralRule; 187 | default: 188 | return kTTTOtherPluralRule; 189 | } 190 | } 191 | 192 | static NSString * TTTHebrewPluralRuleForCount(NSUInteger count) { 193 | NSUInteger mod10 = count % 10; 194 | 195 | switch (count) { 196 | case 1: 197 | return kTTTOnePluralRule; 198 | case 2: 199 | return kTTTTwoPluralRule; 200 | case 3: 201 | case 4: 202 | case 5: 203 | case 6: 204 | case 7: 205 | case 8: 206 | case 9: 207 | case 10: 208 | break; 209 | default: 210 | switch (mod10) { 211 | case 0: 212 | return kTTTManyPluralRule; 213 | default: 214 | break; 215 | } 216 | } 217 | 218 | return kTTTOtherPluralRule; 219 | } 220 | 221 | static NSString * TTTHungarianPluralRuleForCount(NSUInteger count) { 222 | switch (count) { 223 | case 1: 224 | return kTTTOnePluralRule; 225 | default: 226 | return kTTTOtherPluralRule; 227 | } 228 | } 229 | 230 | static NSString * TTTIndonesianPluralRuleForCount(NSUInteger count) { 231 | return kTTTOtherPluralRule; 232 | } 233 | 234 | static NSString * TTTItalianPluralRuleForCount(NSUInteger count) { 235 | switch (count) { 236 | case 1: 237 | return kTTTOnePluralRule; 238 | default: 239 | return kTTTOtherPluralRule; 240 | } 241 | } 242 | 243 | static NSString * TTTJapanesePluralRuleForCount(NSUInteger count) { 244 | return kTTTOtherPluralRule; 245 | } 246 | 247 | static NSString * TTTKoreanPluralRuleForCount(NSUInteger count) { 248 | return kTTTOtherPluralRule; 249 | } 250 | 251 | static NSString * TTTLatvianPluralRuleForCount(NSUInteger count) { 252 | NSUInteger mod10 = count % 10; 253 | NSUInteger mod100 = count % 100; 254 | 255 | if (count == 0) { 256 | return kTTTZeroPluralRule; 257 | } 258 | 259 | if (count == 1) { 260 | return kTTTOnePluralRule; 261 | } 262 | 263 | switch (mod10) { 264 | case 1: 265 | if (mod100 != 11) { 266 | return kTTTOnePluralRule; 267 | } 268 | break; 269 | default: 270 | break; 271 | } 272 | 273 | return kTTTManyPluralRule; 274 | } 275 | 276 | static NSString * TTTMalayPluralRuleForCount(NSUInteger count) { 277 | return kTTTOtherPluralRule; 278 | } 279 | 280 | static NSString * TTTNorwegianBokmalPluralRuleForCount(NSUInteger count) { 281 | switch (count) { 282 | case 1: 283 | return kTTTOnePluralRule; 284 | default: 285 | return kTTTOtherPluralRule; 286 | } 287 | } 288 | 289 | static NSString * TTTNorwegianNynorskPluralRuleForCount(NSUInteger count) { 290 | switch (count) { 291 | case 1: 292 | return kTTTOnePluralRule; 293 | default: 294 | return kTTTOtherPluralRule; 295 | } 296 | } 297 | 298 | static NSString * TTTPolishPluralRuleForCount(NSUInteger count) { 299 | NSUInteger mod10 = count % 10; 300 | NSUInteger mod100 = count % 100; 301 | 302 | if (count == 1) { 303 | return kTTTOnePluralRule; 304 | } 305 | 306 | switch (mod10) { 307 | case 2: 308 | case 3: 309 | case 4: 310 | switch (mod100) { 311 | case 12: 312 | case 13: 313 | case 14: 314 | break; 315 | default: 316 | return kTTTFewPluralRule; 317 | } 318 | 319 | break; 320 | default: 321 | break; 322 | } 323 | 324 | return kTTTManyPluralRule; 325 | } 326 | 327 | static NSString * TTTPortuguesePluralRuleForCount(NSUInteger count) { 328 | switch (count) { 329 | case 1: 330 | return kTTTOnePluralRule; 331 | default: 332 | return kTTTOtherPluralRule; 333 | } 334 | } 335 | 336 | static NSString * TTTRomanianPluralRuleForCount(NSUInteger count) { 337 | NSUInteger mod100 = count % 100; 338 | 339 | switch (count) { 340 | case 0: 341 | return kTTTFewPluralRule; 342 | case 1: 343 | return kTTTOnePluralRule; 344 | default: 345 | if (mod100 > 1 && mod100 <= 19) { 346 | return kTTTFewPluralRule; 347 | } 348 | break; 349 | } 350 | 351 | return kTTTOtherPluralRule; 352 | } 353 | 354 | static NSString * TTTRussianPluralRuleForCount(NSUInteger count) { 355 | NSUInteger mod10 = count % 10; 356 | NSUInteger mod100 = count % 100; 357 | 358 | switch (mod100) { 359 | case 11: 360 | case 12: 361 | case 13: 362 | case 14: 363 | break; 364 | 365 | default: 366 | switch (mod10) { 367 | case 1: 368 | return kTTTOnePluralRule; 369 | case 2: 370 | case 3: 371 | case 4: 372 | return kTTTFewPluralRule; 373 | default: 374 | break; 375 | } 376 | 377 | } 378 | 379 | return kTTTManyPluralRule; 380 | } 381 | 382 | static NSString * TTTSerbianPluralRuleForCount(NSUInteger count) { 383 | switch (count) { 384 | case 1: 385 | return kTTTOnePluralRule; 386 | case 2: 387 | case 3: 388 | case 4: 389 | return kTTTFewPluralRule; 390 | default: 391 | return kTTTOtherPluralRule; 392 | } 393 | } 394 | 395 | static NSString * TTTSlovakPluralRuleForCount(NSUInteger count) { 396 | switch (count) { 397 | case 1: 398 | return kTTTOnePluralRule; 399 | case 2: 400 | case 3: 401 | case 4: 402 | return kTTTFewPluralRule; 403 | default: 404 | return kTTTOtherPluralRule; 405 | } 406 | } 407 | 408 | static NSString * TTTSlovenianPluralRuleForCount(NSUInteger count) { 409 | NSUInteger mod100 = count % 100; 410 | 411 | switch (mod100) { 412 | case 1: 413 | return kTTTOnePluralRule; 414 | case 2: 415 | return kTTTTwoPluralRule; 416 | case 3: 417 | case 4: 418 | return kTTTFewPluralRule; 419 | default: 420 | return kTTTOtherPluralRule; 421 | } 422 | } 423 | 424 | static NSString * TTTSpanishPluralRuleForCount(NSUInteger count) { 425 | switch (count) { 426 | case 1: 427 | return kTTTOnePluralRule; 428 | default: 429 | return kTTTOtherPluralRule; 430 | } 431 | } 432 | 433 | static NSString * TTTSwedishPluralRuleForCount(NSUInteger count) { 434 | switch (count) { 435 | case 1: 436 | return kTTTOnePluralRule; 437 | default: 438 | return kTTTOtherPluralRule; 439 | } 440 | } 441 | 442 | static NSString * TTTThaiPluralRuleForCount(NSUInteger count) { 443 | return kTTTOtherPluralRule; 444 | } 445 | 446 | static NSString * TTTTurkishPluralRuleForCount(NSUInteger count) { 447 | return kTTTOtherPluralRule; 448 | } 449 | 450 | static NSString * TTTUkrainianPluralRuleForCount(NSUInteger count) { 451 | NSUInteger mod10 = count % 10; 452 | NSUInteger mod100 = count % 100; 453 | 454 | switch (mod100) { 455 | case 11: 456 | case 12: 457 | case 13: 458 | case 14: 459 | break; 460 | 461 | default: 462 | switch (mod10) { 463 | case 1: 464 | return kTTTOnePluralRule; 465 | case 2: 466 | case 3: 467 | case 4: 468 | return kTTTFewPluralRule; 469 | default: 470 | break; 471 | } 472 | 473 | } 474 | 475 | return kTTTManyPluralRule; 476 | } 477 | 478 | static NSString * TTTVietnamesePluralRuleForCount(NSUInteger count) { 479 | return kTTTOtherPluralRule; 480 | } 481 | 482 | NSString * TTTLocalizedPluralStringKeyForCountAndSingularNoun(NSUInteger count, NSString *singular) { 483 | NSString *languageCode = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]; 484 | return TTTLocalizedPluralStringKeyForCountAndSingularNounForLanguage(count, singular, languageCode); 485 | } 486 | 487 | NSString * TTTLocalizedPluralStringKeyForCountAndSingularNounForLanguage(NSUInteger count, NSString *singular, NSString *languageCode) { 488 | NSString *pluralRule = nil; 489 | 490 | // Because -hasPrefix is being used here, any three-letter ISO 639-2/3 codes must come before two-letter ISO 639-1 codes in order to prevent, for instance, Konkani (kok) from having Korean (ko) pluralization applied 491 | if ([languageCode hasPrefix:@"ar"]) { 492 | pluralRule = TTTArabicPluralRuleForCount(count); 493 | } else if ([languageCode hasPrefix:@"bg"]) { 494 | pluralRule = TTTBulgarianPluralRuleForCount(count); 495 | } else if ([languageCode hasPrefix:@"ca"]) { 496 | pluralRule = TTTCatalanPluralRuleForCount(count); 497 | } else if ([languageCode hasPrefix:@"zh-Hans"]) { 498 | pluralRule = TTTSimplifiedChinesePluralRuleForCount(count); 499 | } else if ([languageCode hasPrefix:@"zh-Hant"]) { 500 | pluralRule = TTTTraditionalChinesePluralRuleForCount(count); 501 | } else if ([languageCode hasPrefix:@"cr"]) { 502 | pluralRule = TTTCroatianPluralRuleForCount(count); 503 | } else if ([languageCode hasPrefix:@"cs"]) { 504 | pluralRule = TTTCzechPluralRuleForCount(count); 505 | } else if ([languageCode hasPrefix:@"da"]) { 506 | pluralRule = TTTDanishPluralRuleForCount(count); 507 | } else if ([languageCode hasPrefix:@"nl"]) { 508 | pluralRule = TTTDutchPluralRuleForCount(count); 509 | } else if ([languageCode hasPrefix:@"en"]) { 510 | pluralRule = TTTEnglishPluralRuleForCount(count); 511 | } else if ([languageCode hasPrefix:@"fr"]) { 512 | pluralRule = TTTFrenchPluralRuleForCount(count); 513 | } else if ([languageCode hasPrefix:@"de"]) { 514 | pluralRule = TTTGermanPluralRuleForCount(count); 515 | } else if ([languageCode hasPrefix:@"fi"]) { 516 | pluralRule = TTTFinnishPluralRuleForCount(count); 517 | } else if ([languageCode hasPrefix:@"el"]) { 518 | pluralRule = TTTGreekPluralRuleForCount(count); 519 | } else if ([languageCode hasPrefix:@"he"]) { 520 | pluralRule = TTTHebrewPluralRuleForCount(count); 521 | } else if ([languageCode hasPrefix:@"hu"]) { 522 | pluralRule = TTTHungarianPluralRuleForCount(count); 523 | } else if ([languageCode hasPrefix:@"id"]) { 524 | pluralRule = TTTIndonesianPluralRuleForCount(count); 525 | } else if ([languageCode hasPrefix:@"it"]) { 526 | pluralRule = TTTItalianPluralRuleForCount(count); 527 | } else if ([languageCode hasPrefix:@"ja"]) { 528 | pluralRule = TTTJapanesePluralRuleForCount(count); 529 | } else if ([languageCode hasPrefix:@"ko"]) { 530 | pluralRule = TTTKoreanPluralRuleForCount(count); 531 | } else if ([languageCode hasPrefix:@"lv"]) { 532 | pluralRule = TTTLatvianPluralRuleForCount(count); 533 | } else if ([languageCode hasPrefix:@"ms"]) { 534 | pluralRule = TTTMalayPluralRuleForCount(count); 535 | } else if ([languageCode hasPrefix:@"nb"]) { 536 | pluralRule = TTTNorwegianBokmalPluralRuleForCount(count); 537 | } else if ([languageCode hasPrefix:@"nn"]) { 538 | pluralRule = TTTNorwegianNynorskPluralRuleForCount(count); 539 | } else if ([languageCode hasPrefix:@"pl"]) { 540 | pluralRule = TTTPolishPluralRuleForCount(count); 541 | } else if ([languageCode hasPrefix:@"pt"]) { 542 | pluralRule = TTTPortuguesePluralRuleForCount(count); 543 | } else if ([languageCode hasPrefix:@"ro"]) { 544 | pluralRule = TTTRomanianPluralRuleForCount(count); 545 | } else if ([languageCode hasPrefix:@"ru"]) { 546 | pluralRule = TTTRussianPluralRuleForCount(count); 547 | } else if ([languageCode hasPrefix:@"es"]) { 548 | pluralRule = TTTSpanishPluralRuleForCount(count); 549 | } else if ([languageCode hasPrefix:@"sr"]) { 550 | pluralRule = TTTSerbianPluralRuleForCount(count); 551 | } else if ([languageCode hasPrefix:@"sk"]) { 552 | pluralRule = TTTSlovakPluralRuleForCount(count); 553 | } else if ([languageCode hasPrefix:@"sl"]) { 554 | pluralRule = TTTSlovenianPluralRuleForCount(count); 555 | } else if ([languageCode hasPrefix:@"sv"]) { 556 | pluralRule = TTTSwedishPluralRuleForCount(count); 557 | } else if ([languageCode hasPrefix:@"th"]) { 558 | pluralRule = TTTThaiPluralRuleForCount(count); 559 | } else if ([languageCode hasPrefix:@"tr"]) { 560 | pluralRule = TTTTurkishPluralRuleForCount(count); 561 | } else if ([languageCode hasPrefix:@"uk"]) { 562 | pluralRule = TTTUkrainianPluralRuleForCount(count); 563 | } else if ([languageCode hasPrefix:@"vi"]) { 564 | pluralRule = TTTVietnamesePluralRuleForCount(count); 565 | } else { 566 | NSLog(@"Unsupported language: %@", languageCode); 567 | return nil; 568 | } 569 | 570 | return [NSString stringWithFormat:@"%%d %@ (plural rule: %@)", singular, pluralRule]; 571 | } 572 | -------------------------------------------------------------------------------- /TTTLocalizedPluralString.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'TTTLocalizedPluralString' 3 | s.summary = 'NSLocalizedString with a Count Argument.' 4 | s.version = '1.0.0' 5 | s.license = 'MIT' 6 | s.homepage = 'https://github.com/mattt/TTTLocalizedPluralString' 7 | s.social_media_url = 'https://twitter.com/mattt' 8 | s.author = { 'Mattt' => 'mattt@me.com' } 9 | s.source = { :git => 'https://github.com/mattt/TTTLocalizedPluralString.git', :tag => s.version } 10 | s.source_files = 'TTTLocalizedPluralString.{h,m}' 11 | end 12 | --------------------------------------------------------------------------------