Почему происходит сбой приложения при покупке в App Store, но все работает в песочнице (iOS)? - PullRequest
0 голосов

Всем доброго времени суток!

Проблема в следующем: когда я тестирую приложение в песочнице, все работает нормально.И приложение появляется в App Store и вылетает при попытке купить.Покупка не расходная.

Некоторые факты, которые могут привести к правильной мысли:

  • Сбой происходит после строк: let payment = SKPayment (product: subscription.product);SKPaymentQueue.default (). Добавить (оплата)
  • Приложение не падает "мгновенно", а через ~ 1 секунду, что означает, что оно падает после некоторого ответа от сервера
  • Окнопри вводе пароля, логина, подтверждения покупки не появляется на экране.До этого происходит сбой.
  • Это приложение было размещено в App Store как обновление старого.Он был создан в новом проекте, в котором идентификатор пакета был изменен на идентификатор пакета старого приложения.
  • Все покупки в 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)")
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...