如何获得SKProduct的本地货币|在Swift

时间:2016-04-22 12:56:37

标签: ios swift in-app-purchase

我正在尝试使用当地货币显示应用内购买的价格,因此显示美国和美国的正确美元。 CA以及欧元,英镑等。

我知道每个SKProduct都有一个在交易过程中出现的价格作为警报视图,这在确认购买时出现。

但是我想在确认之前显示价格。

我在考虑做这样的事情:

//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
    }
  }

但是这不起作为i似乎没有价格属性。

有人知道如何使用正确的本地货币将标签文本设置为iAP的价格吗?

例如1.49英镑使用苹果定价矩阵为1.99美元,并且在确认交易时输出的值应与产品价格的值相匹配。

7 个答案:

答案 0 :(得分:18)

您应该将NSNumberFormatter与price和priceLocale的产品值一起使用,以输出格式正确的字符串,而不管用户的位置如何。 product.price以NSDecimalNumber的形式返回本地货币的价格,product.productLocale返回价格值的NSLocale。

例如

var item = SKProduct()
for i in productsArray {
    if i.productIdentifier == "com.Company.App.item1" {
      item = i
      if let formattedPrice = priceStringForProduct(item) {
        //update ui with price
      }
    } 
 }

其中priceStringForProduct是在别处定义的函数: -

func priceStringForProduct(item: SKProduct) -> String? {
    let numberFormatter = NSNumberFormatter()
    let price = item.price
    let locale = item.priceLocale
    numberFormatter.numberStyle = .CurrencyStyle
    numberFormatter.locale = locale
    return numberFormatter.stringFromNumber(price)
}

您可能还想处理价格为0.0(免费套餐)的特殊情况。在这种情况下,将priceStringForProduct函数修改为:

func priceStringForProduct(item: SKProduct) -> String? {
    let price = item.price
    if price == NSDecimalNumber(float: 0.0) {
        return "GET" //or whatever you like really... maybe 'Free'
    } else {
        let numberFormatter = NSNumberFormatter()
        let locale = item.priceLocale
        numberFormatter.numberStyle = .CurrencyStyle
        numberFormatter.locale = locale
        return numberFormatter.stringFromNumber(price)
    }
}

编辑:结合其他事情,当您指定productArray时,更多'Swifty'方式是:

var productsArray = [SKProduct]()

然后在你的didRecieveResponse中,你可以将productsArray设置为response.products

而不是遍历产品。
var productsArray = [SKProduct]()
    if response.products.count != 0 {

        print("\(response.products.map {p -> String in return p.localizedTitle})")
        productsArray = response.products

    }

编辑:为了测试许多不同的语言环境,我通常会创建一个NSLocales数组,然后循环打印结果。有一个包含所有localeIdentifier的here

的仓库

这样:

let testPrice = NSDecimalNumber(float: 1.99)
let localeArray = [NSLocale(localeIdentifier: "uz_Latn"),
    NSLocale(localeIdentifier: "en_BZ"),
    NSLocale(localeIdentifier: "nyn_UG"),
    NSLocale(localeIdentifier: "ebu_KE"),
    NSLocale(localeIdentifier: "en_JM"),
    NSLocale(localeIdentifier: "en_US")]
    /*I got these at random from the link above, pick the countries
    you expect to operate in*/

    for locale in localeArray {
        let numberFormatter = NSNumberFormatter()
        numberFormatter.numberStyle = .CurrencyStyle
        numberFormatter.locale = locale
        print(numberFormatter.stringFromNumber(testPrice))
    }

答案 1 :(得分:6)

StoreKit编程指南中包含此代码段,用于显示使用App Store货币的价格:

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

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html 清单2-3

答案 2 :(得分:4)

您不得以当地货币显示价格。您必须以商店提供的货币显示它。如果说法国用户从法国应用程序商店购买,则价格以欧元计价,这就是用户支付的价格。如果该用户前往新西兰并将他或她的地点更改为新西兰但仍留在法国应用程序商店,他们仍然会以欧元结算。这就是你应该展示的东西。

根据Apple的定价矩阵,你说“1.49英镑是1.99美元”。但是1.49英镑不是1.99美元。如果我作为英国用户,去英国并从英国应用程序商店购买,即使我在美国也支付1.49英镑。并且“1.49英镑”是商店告诉你的。

答案 3 :(得分:4)

Swift 5和2019版本:

创建SKProduct扩展,以便您可以方便地访问它,例如:fetchedProduct.localizedPrice。这是代码

extension SKProduct {
    fileprivate static var formatter: NumberFormatter {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        return formatter
    }

    var localizedPrice: String {
        if self.price == 0.00 {
            return "Get"
        } else {
            let formatter = SKProduct.formatter
            formatter.locale = self.priceLocale

            guard let formattedPrice = formatter.string(from: self.price)else {
                return "Unknown Price"
            }

            return formattedPrice
        }
    }
}

原始分析器:

Olivier答案的Swift 4.2版本

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)
    }
}

答案 4 :(得分:3)

您只需要执行以下操作

product.priceLocale.currencyCode

答案 5 :(得分:2)

Apple在此处提供了regularPrice示例代码:

  

https://developer.apple.com/documentation/storekit/in-app_purchase/offering_completing_and_restoring_in-app_purchases

extension SKProduct {

    /// - returns: The cost of the product formatted in the local currency.
    var regularPrice: String? {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.locale = self.priceLocale
        return formatter.string(from: self.price)
    }

}

答案 6 :(得分:1)

Swift 3版本的Olivier的priceStringForProduct:item

func priceStringForProduct(item: SKProduct) -> String? {
        let price = item.price
        if price == 0 {
            return "Free!" //or whatever you like
        } else {
            let numberFormatter = NumberFormatter()
            let locale = item.priceLocale
            numberFormatter.numberStyle = .currency
            numberFormatter.locale = locale
            return numberFormatter.string(from: price)
        }
    }