Search code examples
iosinternationalizationin-app-purchasestorekitmonogame

Collect iOS currency symbols for bitmap font?


My app is displaying the price of an in app purchase product. How can I (at design time) enumerate all the currency symbols and characters used in all of Apple's international app stores? I am displaying text in my app using "texture atlas" based bitmap fonts, i.e. I have to manually include each character I want to display.

I realize that this is a moving target, so I plan to make my logic forgiving. For example if some future equivalent of the Euro symbol is added by Apple and somebody's running an old version of my app, I will silently drop that character and just display the numeric part as "2.99" or "2,99" etc.

But how can I make my list as accurate as possible today, per Apple's official list?

Here's how the string is formatted (straight from Apple's sample):

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[numberFormatter setLocale:product.priceLocale];
NSString *formattedString = [numberFormatter stringFromNumber:product.price];

Solution

  • I quickly wrote a Swift playground to grab the NumberFormatter's output for every available locale. Filtering this to only include currency symbols and punctuation gives a relatively complete set of characters to include.

    let price = 0 as NSDecimalNumber
    let availableIdentifiers = Locale.availableIdentifiers
    var allCurrencySymbols: String = ""
    for identifier in availableIdentifiers
    {
        let locale = Locale(identifier: identifier)
        let formatter = NumberFormatter()
        formatter.formatterBehavior = NumberFormatter.Behavior.behavior10_4
        formatter.numberStyle = NumberFormatter.Style.currency
        formatter.locale = locale
    
        let formattedPrice = formatter.string(from: price)!
        let currencySymbolsOnly = formattedPrice.replacingOccurrences(of: "0", with: "")
        allCurrencySymbols.append(currencySymbolsOnly)
    }
    
    var set = Set<Character>()
    let allCurrencySymbolsMinusDuplicates = String(allCurrencySymbols.characters.filter{ set.insert($0).inserted } )
    print(allCurrencySymbolsMinusDuplicates)
    

    On my Mac, this produces the output…

    , ¤KMFCABuRE.‏₪٠٫۰$০₹YDTShN¥H€₺₦L₸rOP£៛၀nG₵денКМأم०UفجقVsk/zł؋Q༠Zد֏رسل₱؜یاoʻmكብርXdjbI₾ع​₽сом₼ت₩f₡¥Wරුeب₭नेरूtإë₴l৳يp₫лвč₮

    …which you can use to create your bitmap font. But remember your source font will need to support the characters, too.