web-dev-qa-db-ja.com

SKProductの現地通貨を取得する方法| IAP価格をSwift

現地通貨を使用してアプリ内購入の価格を表示しようとしています。そのため、US、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はApples Pricing Matrixを使用した$ 1.99 USドルであり、値を出力すると、トランザクションの確認時に製品価格の値と一致するはずです。

20
RileyDev

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

元のアンサー:

Olivierの回答の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)
    }
}
13
henrik-dmg

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

ここで、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を指定すると、より「スウィフティ」な方法で実行できます。

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

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

7
phil mccullick

価格を現地通貨で表示してはなりません。ストアから提供された通貨で表示する必要があります。フランスのユーザーがフランスのアプリストアから購入するとすると、価格はユーロで表示され、それがユーザーが支払う金額です。そのユーザーがニュージーランドに行ってロケールをニュージーランドに変更したが、フランスのアプリストアに滞在している場合でも、ユーロで請求されます。だから、それを表示する必要があります。

「Appleの価格表によると1.49ポンドは1.99ドルです」と言います。しかし、1.49ポンドIS 1.99ドルではありません。英国のユーザーとして米国に行って英国のアプリストアから購入した場合、米国にいても1.49ポンドを支払います。そして「1.49ポンド」は店があなたに言うことです。

4
gnasher729

OlivierのpriceStringForProduct:itemのSwift 3バージョン

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)
        }
    }
1
Jacob Davis

単にあなたは次のことをする必要があるだけです

product.priceLocale.currencyCode
0
Ahmed Safadi