Positional parameters and stringsdict

Hi.


I was trying to do internationalization friendly pluralization in my code.


My source string looks like this:


NSString *fromString = [NSString localizedStringWithFormat:NSLocalizedString(@"%@ + %d other(s)", @"The from field for the message cell"), senderName, numberOfParticipants];


And I added the following to the stringsdict file for the project:


<key>%@ + %d other(s)</key>
<dict>
  <key>NSStringLocalizedFormatKey</key>
  <string>%#@others@</string>
  <key>others</key>
  <dict>
  <key>NSStringFormatSpecTypeKey</key>
  <string>NSStringPluralRuleType</string>
  <key>NSStringFormatValueTypeKey</key>
  <string>d</string>
  <key>zero</key>
  <string>%@</string>
  <key>one</key>
  <string>%@ + %d other</string>
  <key>other</key>
  <string>%@ + %d others</string>
  </dict>
</dict>


But the only string that was being displayed was from the other category.


John Doe + 0 others

John Doe + 1 others

John Doe + 2 others


After some trial and error my source string ended up like this:


NSString *fromString = [NSString localizedStringWithFormat:NSLocalizedString(@"%2$@ + %1$d other(s)", @"The from field for the message cell"), numberOfParticipants, senderName];


My stringsdict I formatted it like this:


<key>%2$@ + %1$d other(s)</key>
<dict>
  <key>NSStringLocalizedFormatKey</key>
  <string>%#@others@</string>
  <key>others</key>
  <dict>
  <key>NSStringFormatSpecTypeKey</key>
  <string>NSStringPluralRuleType</string>
  <key>NSStringFormatValueTypeKey</key>
  <string>d</string>
  <key>zero</key>
  <string>%2$@</string>
  <key>one</key>
  <string>%2$@ + %1$d other</string>
  <key>other</key>
  <string>%2$@ + %1$d others</string>
  </dict>
</dict>


This gave me:


John Doe

John Doe + 1 other

John Doe + 2 others


I'm really skeptical of calling it a solution. It seems like you should be able to specify the position of the parameter to read for the count of items, but I can't find any example or documentation which can enlighten me. The internaionalization guide only deals with simple strings with zero or one replacement parameters, the documentation for localizedStringWithFormat doesn't mention any special handling for pluralization.


What am I doing wrong?

Accepted Reply

Solved my issue.


I changed my .stringsdict to read:


<key>%@ + %d other(s)</key>
<dict>
  <key>NSStringLocalizedFormatKey</key>
  <string>%@%#@others@</string>
  <key>others</key>
  <dict>
  <key>NSStringFormatSpecTypeKey</key>
  <string>NSStringPluralRuleType</string>
  <key>NSStringFormatValueTypeKey</key>
  <string>d</string>
  <key>zero</key>
  <string></string>
  <key>one</key>
  <string> + %d other</string>
  <key>other</key>
  <string> + %d others</string>
  </dict>
</dict>


The following article gave me the breakthrough I needed: https://www.oneskyapp.com/academy/learn-ios-localization/2-format-strings-plurals/


I'll update the bug report I made to specify that I found the official documentation ambiguous, and that I think it could benefit from an example like in the link above.

Replies

You can look here for an example of using two numbers in the same formatting operation:


www.raizlabs.com/dev/2017/03/localized-pluralization-with-stringsdict/


Based on that, it looks like the order of the %#@ format keys (in the equivalent of your line 04 above) corresponds to the order of the numeric parameters being substituted. In your example, since you only have one format key, the number must be the first parameter.


What's not clear is if that order can be controlled. For example, it may be that you can replace line 04 with this:


  <string>%2$#@others@</string>


to get your original parameter order to work. You could test that fairly easily, but I wouldn't hold my breath for it to work.


IAC you should submit a bug report about this. If nothing else, the documentation should be clarified to be explict about which parameters are used for what.

Thanks for the information. I looked through the Foundation Release Notes for OS X v10.9 and it seems like your suggestion might resolve the issue, but unfortunately after trying it the issue remains.


My next action will be to file a bug report.

Solved my issue.


I changed my .stringsdict to read:


<key>%@ + %d other(s)</key>
<dict>
  <key>NSStringLocalizedFormatKey</key>
  <string>%@%#@others@</string>
  <key>others</key>
  <dict>
  <key>NSStringFormatSpecTypeKey</key>
  <string>NSStringPluralRuleType</string>
  <key>NSStringFormatValueTypeKey</key>
  <string>d</string>
  <key>zero</key>
  <string></string>
  <key>one</key>
  <string> + %d other</string>
  <key>other</key>
  <string> + %d others</string>
  </dict>
</dict>


The following article gave me the breakthrough I needed: https://www.oneskyapp.com/academy/learn-ios-localization/2-format-strings-plurals/


I'll update the bug report I made to specify that I found the official documentation ambiguous, and that I think it could benefit from an example like in the link above.

Thanks for posting your solution.

I'll update the bug report I made …

Thanks again.

Also, what’s that bug number?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

31631979

user_task_progress_format

        NSStringLocalizedFormatKey
        
        %1$@%2$#@lu_progress@%3$#@lu_total_tasks@
        
        lu_progress
        
            NSStringFormatSpecTypeKey
            NSStringPluralRuleType
            NSStringFormatValueTypeKey
            lu
            
            other
            
        
        
        lu_total_tasks
        
            
            NSStringFormatSpecTypeKey
            NSStringPluralRuleType
            
            NSStringFormatValueTypeKey
            lu
            
            one
             has finished %2$lu out of 1 task.
            other
             has finished %2$lu out of %3$lu tasks.

https://www.d******.com/ @developer.apple.com