Search code examples
iosswiftin-app-purchase

How to get Local Currency for SKProduct | Display IAP Price in Swift


I am trying to display the price of an in app purchase using the local currency, so the correct dollar is displayed for both US & CA as well as Euro, GBP etc.

I know each SKProduct has a price which appears during the transaction as an alert view, this appears when confirming the purchase.

However I want to display the price before confirmation.

I was thinking to do something like this:

//Products Array
var productsArray: Array<SKProduct!> = []

//Request Products
    func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
        if response.products.count != 0 {
            for product in response.products {
                print("\(product.localizedTitle)")
                productsArray.append(product)
            }
        }
        else {
            print("There are no products.")
        }

        if response.invalidProductIdentifiers.count != 0 {
            print("\(response.invalidProductIdentifiers.description)")
        }            
     }


let item = SKProduct
  for i in productsArray {
    if i.localizedTitle == "com.Company.App.item1" 
      item = i
    }
  }

But this doesn't work as i Doesn't seem to have a price property.

Does anybody know how I can set a label text to the price of an iAP using the correct local currency?

For example £1.49 GBP is $1.99 US dollars using Apples Pricing Matrix and outputting the value should match the values of the product price when confirming the transaction.


Solution

  • Swift 5 and 2021 version:

    Create an extension to SKProduct so you can access product.localizedPrice conveniently:

    extension SKProduct {
    
        private static let formatter: NumberFormatter = {
            let formatter = NumberFormatter()
            formatter.numberStyle = .currency
            return formatter
        }()
    
        var isFree: Bool {
            price == 0.00
        }
    
        var localizedPrice: String? {
            guard !isFree else {
                return nil
            }
            
            let formatter = SKProduct.formatter
            formatter.locale = priceLocale
    
            return formatter.string(from: price)
        }
    
    }
    

    Original Anser:

    Swift 4.2 version of Olivier's answer

    func priceStringForProduct(item: SKProduct) -> String? {
        let price = item.price
        if price == NSDecimalNumber(decimal: 0.00) {
            return "GET" //or whatever you like really... maybe 'Free'
        } else {
            let numberFormatter = NumberFormatter()
            let locale = item.priceLocale
            numberFormatter.numberStyle = .currency
            numberFormatter.locale = locale
            return numberFormatter.string(from: price)
        }
    }