14
votes

I need a way to format the price from NSNumber into a string like this: "USD 0.99", not "$ 0.99".

My game uses custom fonts, and they could not have the symbols for all the available App Store currencies like GBP. So I think it's better to roll-back to string representation of currency.

The method used should be absolutely OK for any currency that App Store supports.

7

7 Answers

36
votes

If you want it localized (ie the currency on the correct side of the price) it is a bit of a hassle.

NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"1.99"];
NSLocale *priceLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"de_DE"] autorelease]; // get the locale from your SKProduct

NSNumberFormatter *currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
[currencyFormatter setLocale:priceLocale];
NSString *currencyString = [currencyFormatter internationalCurrencySymbol]; // EUR, GBP, USD...
NSString *format = [currencyFormatter positiveFormat];
format = [format stringByReplacingOccurrencesOfString:@"¤" withString:currencyString];
    // ¤ is a placeholder for the currency symbol
[currencyFormatter setPositiveFormat:format];

NSString *formattedCurrency = [currencyFormatter stringFromNumber:price];

You have to use the locale you get from the SKProduct. Don't use [NSLocale currentLocale]!

8
votes

The – productsRequest:didReceiveResponse: method gives you back a list of SKProducts.

Each product contains a property priceLocale which contains the local currency of the product for the current user.

You could use the following sample code (apple's) to format it:

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

Good luck!

4
votes

The Swift Example:

var currencyFormatter = NSNumberFormatter()
currencyFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
currencyFormatter.locale = priceLocale //SKProduct->priceLocale
var currencyString = currencyFormatter.internationalCurrencySymbol
var format = currencyFormatter.positiveFormat
format = format.stringByReplacingOccurrencesOfString("¤", withString: currencyString)
currencyFormatter.positiveFormat = format

var formattedCurrency = currencyFormatter.stringFromNumber(price) //SKProduct->price

println("formattedCurrency: \(formattedCurrency)")//formattedCurrency: 0,89 EUR
3
votes

Nice example I found here http://bendodson.com/weblog/2014/12/10/skproduct-localized-price-in-swift/

import StoreKit

extension SKProduct {

    @objc func localizedPrice() -> String {
        let formatter = NSNumberFormatter()
        formatter.numberStyle = .CurrencyStyle
        formatter.locale = self.priceLocale
        return formatter.stringFromNumber(self.price)!
    }
}
2
votes

use formatter in this way or you can also customize it

NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
[numberFormatter setNumberStyle: NSNumberFormatterCurrencyStyle];

or like this

[formatter setFormat:@"USD ###.00"];

i think you can check the currency for the country and store that in string and give that to the formatter.

1
votes

The easiest way to achieve this would be to use the NSNumberFormatter class to format the NSNumber value as required.

Whilst the methods are too numerous to mention, this provides a wide variety of output formatting capabilities including the setInternationalCurrencySymbol: method that should be of particular interest.

0
votes

SKProduct price is a NSDecimalNumber object, so one way you could do this would be to extend the NSDecimalNumber class. Here's my Swift code for this:

extension NSDecimalNumber {
    func asCurrency(locale:NSLocale) -> String? {
        var numberFormatter = NSNumberFormatter()
        numberFormatter.formatterBehavior = NSNumberFormatterBehavior.Behavior10_4
        numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        numberFormatter.locale = locale
        return numberFormatter.stringFromNumber(self)
    }
}

in Objective-C it would look like this:

@interface NSDecimalNumber (CurrencyExtension)

- (NSString*) asCurrency: (NSLocale *)locale;

@end

@implementation NSDecimalNumber (DellExtensions)

- (NSString*) asCurrency: (NSLocale *)locale {
    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
    [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
    [numberFormatter setLocale:product.priceLocale];
    return [numberFormatter stringFromNumber:product.price];
}

@end