Как получить местную валюту для SKProduct / Display IAP цена в Swift
Я пытаюсь отобразить цену покупки в приложении, используя местную валюту, поэтому правильный доллар отображается как для США и CA, так и для ЕВРО, GBP и т. д.
Я знаю, что каждый 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 долларов США, используя матрицу цен на яблоки, и вывод значения должен соответствовать значениям цены продукта при подтверждении транзакции.
5 ответов
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)
}
}
вы должны использовать NSNumberFormatter со значениями продукта для price и priceLocale для вывода строки, которая правильно отформатирована независимо от местоположения пользователя. товар.цена возвращает цену в местной валюте в виде 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)
}
}
Edit: пара других вещей, когда вы указываете свой productArray более "быстрый" способ сделать это:
var productsArray = [SKProduct]()
и затем в вашем didRecieveResponse, вместо того, чтобы зацикливаться на продуктах, вы можете просто установить productsArray в качестве ответа.продукты
var productsArray = [SKProduct]()
if response.products.count != 0 {
print("\(response.products.map {p -> String in return p.localizedTitle})")
productsArray = response.products
}
Edit: для тестирования нескольких разных локалей я обычно делаю массив 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))
}
вы не должны отображать цену в местной валюте. Вы должны отобразить его в валюте, предоставленной магазином. Если, скажем, французский пользователь покупает во французском app store, то цена поднимается в евро, и это то, что платит пользователь. Если пользователь едет в Новую Зеландию и меняет место жительства на Новую Зеландию, но остается во французском app store, ему все равно выставляется счет в евро. Так вот что вы должны показать.
вы говорите: "£1.49 составляет $ 1.99 в соответствии с ценами Apple матрица." Но £1.49-это не $ 1.99. Если я, как британский пользователь, еду в США и покупаю в UK app store, я плачу £1.49, даже если я в США. И" £1.49 " - это то, что магазин скажет вам.
в руководстве по программированию 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
Swift 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)
}
}