iOS中每个国家/地区的IAP定价不同

时间:2017-07-22 09:35:26

标签: ios appstore-approval storekit

我注意到,与其他国家/地区相比,我在中国的某款应用购买IAP的百分比非常低。我的结论是因为价格偏高。我希望能够为每个国家/地区的IAP实施不同的价格等级(首先是针对中国)。我知道有这些特价价格等级(A级,B级,备用级别4 ......)已经为“新兴国家”提供了一些更便宜的价格,但他们不会这样做。

我所有的IAP都是非消耗品。

经过研究,这是我的想法:

  1. 在每个IAP中为itunes门户定义一个正常且便宜的IAP。
  2. 当通过应用程序中的StoreKit API请求信息时,我会请求每个IAP的两个“变体”
  3. 返回的SKProduct.priceLocal.regionCode可以告诉我用户是否在中国,在这种情况下我会选择采用IAP的廉价变体(应用程序中实现的逻辑)。
  4. 这会是一个好方法吗? 苹果是否允许这种策略?

1 个答案:

答案 0 :(得分:0)

上述方法正常,我的应用程序被推送到AppStore;让我们看看它是否得到Apple的批准。

我的实施细节,以连接到中国AppStore的人购买折扣车为例:

class IAPManager : NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {

    //holds the literal string identifiers as also entered in the itunes connect portal for the in app purchases
    //the format of this string can be anything you want. I use a revers domain notation to make it "unique".
    //notice that we are requesting the price for a car, there are 2 prices the "normal" price and the "discount" price
    //the idea is that we will offer the "discount" price for people connected to the Chinese AppStore
    struct ProductIdentifiers {
        static let carNormalPricing   = "net.fantastic.car._normalpricing"
        static let carDiscountPricing = "net.fantastic.car._discountpricing"
    }


    //stores the product request send to the AppStore for retrieving the pricing info
    //as stated in the Apple documentation this should be kept in memory until the request completes
    private var productRequest: SKProductsRequest?

    //once the pricing is retrieved from the AppStore its stored here
    private var carPrices: (normal: SKProduct?, discount: SKProduct?)

    //this is where the "magic" happens, pleople connecting to the Chinese app store get the discount pricing
    //all others get then normal pricing. By changing the "zh" you can select different stores...
    //I have tested this and this does work (for China anayway).
    var carPriceToUse: SKProduct? {
        //if we don't have normal pricing no pricing available at all!
        guard let normal = carPrices.normal else {
            return nil
        }
        //if we don't have any discount pricing always use the normal of course
        guard let discount = carPrices.discount else {
            return normal
        }
        //we got both prices so select between them
        //for chinese languages we use discount pricing
        if discount.priceLocale.languageCode == "zh" {
            return discount
        }
        //if not go for normal pricing
        return normal
    }

    func askAppStoreForCarPrices() {
        //make list of the product ids that we will be retrieving from the AppStore
        var productIds = Set<String>()
        //we want to get the norma and discount pricing for our car
        productIds.insert(ProductIdentifiers.carNormalPricing)
        productIds.insert(ProductIdentifiers.carDiscountPricing)
        //make and sendout the request (on main queue)
        productRequest = SKProductsRequest(productIdentifiers: productIds)
        productRequest?.delegate = self
        DispatchQueue.main.async(){
            [weak self] in
            self?.productRequest?.start()
        }
    }

    func buyCar() {
        //only if I can buy...
        guard let storeProduct = carPriceToUse else {
            fatalError("Asked to buy but no prices loaded yet")
        }
        //ask to buy
        DispatchQueue.main.async(){
            let payment = SKPayment(product: storeProduct)
            SKPaymentQueue.default().add(payment)
        }
    }

    //MARK: - SKProductsRequestDelegate, SKPaymentTransactionObserver


    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        //parseout any priceinfo
        for product in response.products {
            if product.productIdentifier == ProductIdentifiers.carNormalPricing {
                carPrices.normal = product
            }
            if product.productIdentifier == ProductIdentifiers.carDiscountPricing {
                carPrices.discount = product
            }
        }
    }

    func request(_ request: SKRequest, didFailWithError error: Error) {
        //...handle error when retrieving prices here...
    }

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        //..handle actual buying process here
    }

}