如何获得 SKProduct 的本地货币 |以 Swift 显示 IAP 价格
How to get Local Currency for SKProduct | Display IAP Price in 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
}
}
但这不起作用,因为 i
似乎没有价格 属性。
有人知道如何使用正确的本地货币将标签文本设置为 iAP 的价格吗?
例如£1.49 GBP是$1.99 US dollars using Apples Pricing Matrix并且输出值应该与确认交易时的产品价格值相匹配。
您应该将 NSNumberFormatter 与 price 和 priceLocale 的产品值一起使用,以输出格式正确的字符串,而不管用户位于何处。 product.price returns 作为 NSDecimalNumber 的本地货币价格,以及 product.productLocale returns 价格值的 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 数组,然后循环打印结果。有一个包含所有 localeIdentifiers 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))
}
您不得以当地货币显示价格。您必须以商店提供的货币显示它。如果说法国用户从法国应用商店购买,那么价格就会以欧元计算,这就是用户支付的金额。如果该用户去新西兰并将他或她的区域设置更改为新西兰,但仍留在法国应用商店,他们仍将以欧元计费。所以这就是你应该展示的。
您说“根据 Apple 的定价矩阵,1.49 英镑等于 1.99 美元”。但是 1.49 英镑不是 1.99 美元。如果我作为英国用户去美国并从英国应用商店购买,即使我在美国,我也要支付 1.49 英镑。 “£1.49”是商店会告诉您的。
Swift Olivier 的 3 版本 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)
}
}
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];
Swift5和2021版本:
创建 SKProduct 的扩展以便您可以方便地访问 product.localizedPrice
:
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)
}
}
原答案:
Swift Olivier 的回答 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)
}
}
Apple 在此处提供 regularPrice
示例代码:
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)
}
}
您只需要执行以下操作
product.priceLocale.currencyCode
我正在尝试使用本地货币显示应用内购买的价格,因此对于美国和加拿大以及欧元、英镑等都显示正确的美元。
我知道每个 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 GBP是$1.99 US dollars using Apples Pricing Matrix并且输出值应该与确认交易时的产品价格值相匹配。
您应该将 NSNumberFormatter 与 price 和 priceLocale 的产品值一起使用,以输出格式正确的字符串,而不管用户位于何处。 product.price returns 作为 NSDecimalNumber 的本地货币价格,以及 product.productLocale returns 价格值的 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 数组,然后循环打印结果。有一个包含所有 localeIdentifiers 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))
}
您不得以当地货币显示价格。您必须以商店提供的货币显示它。如果说法国用户从法国应用商店购买,那么价格就会以欧元计算,这就是用户支付的金额。如果该用户去新西兰并将他或她的区域设置更改为新西兰,但仍留在法国应用商店,他们仍将以欧元计费。所以这就是你应该展示的。
您说“根据 Apple 的定价矩阵,1.49 英镑等于 1.99 美元”。但是 1.49 英镑不是 1.99 美元。如果我作为英国用户去美国并从英国应用商店购买,即使我在美国,我也要支付 1.49 英镑。 “£1.49”是商店会告诉您的。
Swift Olivier 的 3 版本 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)
}
}
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];
Swift5和2021版本:
创建 SKProduct 的扩展以便您可以方便地访问 product.localizedPrice
:
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)
}
}
原答案:
Swift Olivier 的回答 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)
}
}
Apple 在此处提供 regularPrice
示例代码:
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)
}
}
您只需要执行以下操作
product.priceLocale.currencyCode