尝试在App Store中购买时,为什么app会崩溃,但所有内容都可以在沙箱(iOS)中运行?

时间:2019-03-14 15:20:57

标签: ios swift in-app-purchase app-store

大家好!

问题如下:当我在沙箱中测试应用程序时,一切正常。并且该应用程序出现在App Store中,并在您尝试购买时崩溃。购买的不是消耗品。

一些可能导致正确思考的事实:

  • 在以下行之后发生崩溃: 让付款= SKPayment(产品:subscription.product); SKPaymentQueue.default()。添加(付款)
  • 应用程序不会“立即”崩溃,而是在大约1秒钟后崩溃,这意味着它在服务器响应后崩溃了。
  • 输入密码,登录,确认购买的窗口不会出现在屏幕上。在此之前发生崩溃。
  • 此应用已作为旧应用的更新发布到App Store。它是在一个新项目中创建的,该项目的包ID更改为旧应用程序的包ID。
  • 由主持人批准的itunesconnect中的所有购买,均显示在App Store中。
class BillingManager: NSObject {

    static let sessionIdSetNotification = Notification.Name("SubscriptionServiceSessionIdSetNotification")
    static let optionsLoadedNotification = Notification.Name("SubscriptionServiceOptionsLoadedNotification")
    static let restoreSuccessfulNotification = Notification.Name("SubscriptionServiceRestoreSuccessfulNotification")
    static let purchaseSuccessfulNotification = Notification.Name("SubscriptionServiceRestoreSuccessfulNotification")

    private override init() { }
    private static var instance: BillingManager?

    /** создает 1 объект или возвращает текущий (синглтон) */
    static func shared() -> BillingManager {
        if instance == nil {
            instance = BillingManager()
        }
        return instance!
    }

    var isPro: Bool {

        /** Здесь проверяем дату подписки по UserDefaults */

        var subscriptionAccess = false


        if let purchase = UserDefaults.standard.string(forKey: "purchaseDate") {
            if let expires = UserDefaults.standard.string(forKey: "expiresDate") {
                if let purchaseDate = dateFormatter.date(from: purchase), let expiresDate = dateFormatter.date(from: expires) {

                    subscriptionAccess = (purchaseDate...expiresDate).contains(Date())

                }
            }
        }

        return (currentSubscription != nil) || subscriptionAccess || UserDefaults.standard.bool(forKey: "forever.subscription")
    }

    var hasReceiptData: Bool {
        return loadReceipt() != nil
    }

    var currentSessionId: String? {
        didSet {
            NotificationCenter.default.post(name: BillingManager.sessionIdSetNotification, object: currentSessionId)
        }
    }

    var currentSubscription: PaidSubscription?

    var options: [Subscription]? {
        didSet {
            NotificationCenter.default.post(name: BillingManager.optionsLoadedNotification, object: options)
        }
    }

    func loadSubscriptionOptions() {
        let productIDs = Set([InAppType.month.rawValue,
                              InAppType.halfYear.rawValue,
                              InAppType.year.rawValue,
                              InAppType.forever.rawValue,
                              InAppType.discountedForever.rawValue])

        let request = SKProductsRequest(productIdentifiers: productIDs)
        request.delegate = self
        request.start()
    }

    func purchase(subscription: Subscription) {
        let payment = SKPayment(product: subscription.product)
        SKPaymentQueue.default().add(payment)
    }

    func restorePurchases() {
        SKPaymentQueue.default().restoreCompletedTransactions()
    }

    func uploadReceipt(completion: ((_ success: Bool) -> Void)? = nil) {

        if let receiptData = loadReceipt() {
            Service.shared.upload(receipt: receiptData) { [weak self] (result) in
                guard let strongSelf = self else { return }
                switch result {
                case .success(let result):
                    strongSelf.currentSessionId = result.sessionId
                    strongSelf.currentSubscription = result.currentSubscription
                    completion?(true)
                case .failure(let error):
                    print(" Receipt Upload Failed: \(error)")
                    completion?(false)
                }
            }
        }
    }

    private func loadReceipt() -> Data? {
        guard let url = Bundle.main.appStoreReceiptURL else {
            return nil
        }

        do {
            let data = try Data(contentsOf: url)
            return data
        } catch {
            print("Error loading receipt data: \(error.localizedDescription)")
            return nil
        }
    }

}


extension BillingManager: SKProductsRequestDelegate {
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        options = response.products.map { Subscription(product: $0) }.sorted(by: { (left, right) -> Bool in
            left.product.price < right.product.price
        })

    }

    func request(_ request: SKRequest, didFailWithError error: Error) {
        if request is SKProductsRequest {
            print("Subscription Options Failed Loading: \(error.localizedDescription)")
        }
    }
}

0 个答案:

没有答案