如何获得SKProduct的本地货币| 在Swift中显示IAP价格

Ril*_*Dev 19 in-app-purchase ios swift

我试图使用当地货币显示应用内购买的价格,因此显示美国和加拿大以及欧元,英镑等的正确美元.

我知道每个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
    }
  }
Run Code Online (Sandbox Code Playgroud)

但这i不起作用似乎没有价格属性.

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

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

Oli*_*son 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
      }
    } 
 }
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)

您可能还想处理价格为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)
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:结合其他事情,当你指定你的产品时,更多'Swifty'的方式是:

var productsArray = [SKProduct]()
Run Code Online (Sandbox Code Playgroud)

然后在你的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

    }
Run Code Online (Sandbox Code Playgroud)

编辑:为了测试许多不同的语言环境,我通常会创建一个NSLocales数组,然后循环打印结果.有一个与所有localeIdentifiers的回购这里

所以:

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))
    }
Run Code Online (Sandbox Code Playgroud)


hen*_*dmg 17

Swift 5和2019版本:

创建SKProduct的扩展,以便您可以product.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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

原始分析工具:

Swift 4.2版本的Olivier的答案

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)
    }
}
Run Code Online (Sandbox Code Playgroud)


Phi*_*ick 9

《 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];
Run Code Online (Sandbox Code Playgroud)

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


Ahm*_*adi 7

只需执行以下操作

product.priceLocale.currencyCode
Run Code Online (Sandbox Code Playgroud)


gna*_*729 6

您不得以当地货币显示价格。您必须以商店提供的货币显示它。如果说法国用户从法国应用程序商店购买,那么价格将以欧元显示,这就是用户支付的费用。如果该用户前往新西兰并将其区域设置更改为新西兰,但仍使用法国应用商店,则仍以欧元计费。这就是您应该显示的内容。

\n\n

你说“根据苹果的定价矩阵,\xc2\xa31.49 是 1.99 美元”。但 \xc2\xa31.49 不是 1.99 美元。如果我,作为一名英国用户,去美国并从英国应用商店购买,即使我在美国,我也会支付 \xc2\xa31.49 。商店会告诉您“\xc2\xa31.49”。

\n


pka*_*amb 5

AppleregularPrice在此处提供示例代码:

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

}
Run Code Online (Sandbox Code Playgroud)