Как получить местную валюту для SKProduct | Показать цену IAP в Swift
Я пытаюсь отобразить цену покупки приложения в местной валюте, поэтому правильный доллар отображается как для США, так и для США, а также для евро, 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 доллара США, используя матрицу ценообразования на основе яблок, и вывод значения должен соответствовать значениям цены продукта при подтверждении транзакции.
Ответы
Ответ 1
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
}
}
}
Оригинальный Anser:
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)
}
}
Ответ 2
вы должны использовать NSNumberFormatter с значениями продукта для цены и 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)
}
}
Изменить: добавьте другие вещи, когда вы укажете свой товарный массив более "быстрым" способом:
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 здесь
так:
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))
}
Ответ 3
В Руководстве по программированию 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
Ответ 4
Вы НЕ ДОЛЖНЫ отображать цену в местной валюте. Вы должны отобразить его в валюте, предоставляемой магазином. Если сказать, что французский пользователь покупает у французского магазина приложений, тогда цена появляется в евро, и это то, что платит пользователь. Если этот пользователь отправляется в Новую Зеландию и изменяет свой язык в Новую Зеландию, но остается с французским магазином приложений, они по-прежнему оплачиваются в евро. Итак, что вы должны отображать.
Вы говорите: "1,49 фунта стерлингов составляет 1,99 доллара США в соответствии с матрицей ценообразования Apple". Но 1,49 фунта не 1,99 доллара. Если я, как британский пользователь, отправляюсь в США и покупаю из магазина приложений в Великобритании, я плачу 1,49 фунта стерлингов, даже если я в США. И "£ 1.49" - это то, что расскажет вам магазин.
Ответ 5
Свифт 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)
}
}