【问题标题】:IAP(in app purchase) introductory price how can I manage it iOS?IAP(应用内购买)入门价格我如何管理它 iOS?
【发布时间】:2018-02-08 07:19:29
【问题描述】:

我已经为 iOS 成功实现了一组 IAP introductory price,但我很困惑是否需要在 iOS 端使用任何额外的代码来管理它?如果是,需要进行哪些更改?

【问题讨论】:

    标签: ios iphone in-app-purchase app-store-connect price


    【解决方案1】:

    好吧,如果你想正确地实现它,你实际上需要额外的代码。这是为了让客户清楚地了解他得到了什么。

    在 iOS 12 和 13 中,您可以获得 3 种不同的订阅介绍价格:

    • 免费试用
    • 现收现付
    • 预付款

    关于三者的意义以及订阅的简单和整体视图,请参阅Auto-renewable Subscriptions Apple doc with recommended UI

    在向您展示购买的视图控制器时,您应该:

    1. 正确显示优惠:例如:“开始您的 1 个月免费 试用,然后每月 1.99 美元”免费试用介绍价;
    2. 处理用户已经从过去的介绍价格中受益的事实,因此宁愿显示“订阅 1.99 美元/月”(到 继续同一个例子)。这需要您查看用户拥有的收据并检查“is_trial_period”或“is_in_intro_offer_period”是否设置为 true(请参阅答案底部的我的代码)。

    在我之前提到的 Apple 文档中,有许多“实际”屏幕显示了不同的用例。

    我的类处理每个产品的介绍价格状态

    /**
     Receipt description
     */
    public class LatestReceipt: CustomStringConvertible {
    
        public var description: String {
            let prefix = type(of: self)
            return """
            \(prefix) expires \(expiredDate?.compact(timeStyle: .medium) ?? "nil"):
            \(prefix) • product: \(productID);
            \(prefix) • isEligible: \(isEligible);
            \(prefix) • isActive: \(isActive);
            \(prefix) • have been in free trial: \(haveBeenInFreeTrialPeriod);
            \(prefix) • intro date: \(introOfferPeriodDate?.compact(timeStyle: .medium) ?? "nil");
            \(prefix) • free trial period: \(inFreeTrialPeriod).
    
            """
        }
    
    
        /// Related product ID
        var productID = ""
    
    
        /**
         Tells whether the user is eligible for any introductory period
    
         - Note: From the Apple Doc: You can use “is_in_intro_offer_period” value to determine if the user is eligible for introductory pricing. If a previous subscription period in the receipt has the value “true” for either the “is_trial_period” or “is_in_intro_offer_period” keys, the user is not eligible for a free trial or introductory price within that subscription group.
         */
        public var isEligible = true
    
        /// When did the user benefited the intro offer? Nil means never.
        public var introOfferPeriodDate: Date? = nil
        /// When did the user benefited the free trial? Nil means never.
        public var freeTrialPeriodDate: Date? = nil
        public var inFreeTrialPeriod = false
        /// Tells whether the user benefited the free trial period in the past
        public var haveBeenInFreeTrialPeriod = false
        /// Is still active for today?
        public var isActive = false
    
        /// Last expired date
        public var expiredDate: Date? = nil
    
        // Latest receipt content
        public var content = NSDictionary()
    
        /**
         Replaces the current receipt if the new one is more recent. And compute isActive and others propteries.
    
         - Parameters:
            - receipt: The new receipt to test.
         */
        public func replaceIfMoreRecent(receipt: NSDictionary) {
    
            // Replace receipt if more recent
            if let ed = expiredDate {
    
                // -- Expiring product (aka subscriptions): add only the most recent
                guard let receiptExpiresDate = receipt["expires_date"] as? String,
                    let red = StoreKit.getDate(receiptExpiresDate) else {
                    print("\(#function): *** Error unable to get receipt expiredDate or convert it to a Date(), skipped")
                    return
                }
    
                // This receipt is most recent than the currently stored? if, yes, replace
                if red.isAfter(ed) {
                    content = receipt
                    expiredDate = red
    
    
                    // Is in trial?
                    if let tp = content["is_trial_period"] as? String {
                        inFreeTrialPeriod = tp == "true"
    
                        if inFreeTrialPeriod {
                            haveBeenInFreeTrialPeriod = true
                        }
                    }
    
                    // When was the intro?
                    if let intro = content["is_in_intro_offer_period"] as? String,
                        intro == "true" {
                        introOfferPeriodDate = red
                    }
    
    
                    let now = Date()
    
                    // Subscription still active today?
                    isActive = red.isAfterOrSame(now)
    
                    // Eligibility; check against PREVIOUS subscription period
                    if !isActive {
                       // You can use “is_in_intro_offer_period” value to determine if the user is eligible for introductory pricing. If a previous subscription period in the receipt has the value “true” for either the “is_trial_period” or “is_in_intro_offer_period” keys, the user is not eligible for a free trial or introductory price within that subscription group.
                        let benefitedFromIntroductoryPrice = introOfferPeriodDate != nil || haveBeenInFreeTrialPeriod
                        isEligible = !benefitedFromIntroductoryPrice
                    }
    
                }
                print("\(#function): new \(self)")
            }
        }
    
    
        init(receipt: NSDictionary) {
            content = receipt
    
            if let productID = receipt["product_id"] as? String {
                self.productID = productID
            }
    
            // When subscription, set expires date
            if let receiptExpiresDate = receipt["expires_date"] as? String,
                let red = StoreKit.getDate(receiptExpiresDate) {
                expiredDate = red
    
                // Is in trial?
                if let tp = content["is_trial_period"] as? String,
                    tp == "true" {
                    inFreeTrialPeriod = true
                    haveBeenInFreeTrialPeriod = true
                }
    
                // When was the intro?
                if let intro = content["is_in_intro_offer_period"] as? String,
                    intro == "true" {
                    introOfferPeriodDate = red
                }
    
    
                let now = Date()
    
                // Subscription still active today?
                isActive = red.isAfterOrSame(now)
    
                // Eligibility; check against PREVIOUS subscription period
                if !isActive {
                    // You can use “is_in_intro_offer_period” value to determine if the user is eligible for introductory pricing. If a previous subscription period in the receipt has the value “true” for either the “is_trial_period” or “is_in_intro_offer_period” keys, the user is not eligible for a free trial or introductory price within that subscription group.
                    let benefitedFromIntroductoryPrice = introOfferPeriodDate != nil || inFreeTrialPeriod
                    isEligible = !benefitedFromIntroductoryPrice
                }
            }
        }
    
    }
    

    【讨论】:

    • 您好,您对我的情况有什么想法吗?我有一个现有的应用程序,其中包含在应用程序商店中的自动更新 IAP。我现在在 iTunes 上添加了介绍性价格,并且正在与沙盒用户进行测试。我在以前的版本中使用该用户全额购买了订阅。但是现在当我检查收据时,对于is_in_intro_offer_period,我得到true。即使我刚刚实施了介绍性优惠,而该用户之前从未购买过介绍性优惠。知道为什么会这样吗?
    【解决方案2】:

    如果您正确实施了 IAP 介绍性价格,您应该不需要在 iOS 端做任何额外的工作来管理它。价格通过 iTunesConnect 界面进行管理。通过正确实现它,我的意思是使用 SKProduct API 来获取价格并将其显示在应用程序中,这样当您从 iTunes 连接更改它时,它也会在应用程序中更改。

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 2012-09-26
      • 1970-01-01
      • 2014-07-11
      • 1970-01-01
      • 2019-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多