Как получить местную валюту для 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)
        }
    }