2017-12-12 24 views
0

私はthis RWチュートリアルに従っていました。多くのIAPとStorekitのチュートリアルと同様に、初めてIAPを購入するユーザーの流れについて話していますが、既にIAPを購入したユーザーが再びアプリを開くと、アプリがどのように動作するかを詳しく調べることができます。私の知る限り、ブロック/コンテンツは、(1)領収書及び(2)SessionIDのルックアップで表示されていること...コードを伝えることができるようStorekitとIAPをすでに購入したユーザーを扱う

:私は問題の鍵を見つけたとして、私の質問を更新

彼はSessionIDが何であるか、それがチュートリアルのデモの一部としてだけであるかチュートリアルの詳細には入っていません。たとえば、uploadReceiptが呼び出されたときにのみ設定されます(handlePurchasedStateまたはhandleRestoredStateが呼び出されたときにのみ呼び出されます)。つまり、ユーザーが既にサブスクリプションを持っているアプリを開くと、コンテンツがロックされないようにSessionIDを設定するコードは実行されていませんか?

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 

    func application(_ application: UIApplication, 
        didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

    SKPaymentQueue.default().add(self) 
    SubscriptionService.shared.loadSubscriptionOptions() 
    return true 
    } 
} 


// MARK: - SKPaymentTransactionObserver 

extension AppDelegate: SKPaymentTransactionObserver { 

    func paymentQueue(_ queue: SKPaymentQueue, 
        updatedTransactions transactions: [SKPaymentTransaction]) { 

    for transaction in transactions { 
     switch transaction.transactionState { 
     case .purchasing: 
     handlePurchasingState(for: transaction, in: queue) 
     case .purchased: 
     handlePurchasedState(for: transaction, in: queue) 
     case .restored: 
     handleRestoredState(for: transaction, in: queue) 
     case .failed: 
     handleFailedState(for: transaction, in: queue) 
     case .deferred: 
     handleDeferredState(for: transaction, in: queue) 
     } 
    } 
    } 

    func handlePurchasingState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) { 
    print("User is attempting to purchase product id: \(transaction.payment.productIdentifier)") 
    } 

    func handlePurchasedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) { 
    print("User purchased product id: \(transaction.payment.productIdentifier)") 

    queue.finishTransaction(transaction) 
    SubscriptionService.shared.uploadReceipt { (success) in 
     DispatchQueue.main.async { 
     NotificationCenter.default.post(name: SubscriptionService.purchaseSuccessfulNotification, object: nil) 
     } 
    } 
    } 

    func handleRestoredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) { 
    print("Purchase restored for product id: \(transaction.payment.productIdentifier)") 
    queue.finishTransaction(transaction) 
    SubscriptionService.shared.uploadReceipt { (success) in 
     DispatchQueue.main.async { 
     NotificationCenter.default.post(name: SubscriptionService.restoreSuccessfulNotification, object: nil) 
     } 
    } 
    } 

    func handleFailedState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) { 
    print("Purchase failed for product id: \(transaction.payment.productIdentifier)") 
    } 

    func handleDeferredState(for transaction: SKPaymentTransaction, in queue: SKPaymentQueue) { 
    print("Purchase deferred for product id: \(transaction.payment.productIdentifier)") 
    } 
} 

答えて

0

技術的にアプリの領収書を検証し、すべてのIAPにプログラムが実行されるたびに再処理ができてもあなたは、購入のユーザーがアプリを起動するたびに通知されません。それは非効率的だ。あなたのアプリは購入時に購入したものを追跡するだけです。

アプリを削除して再インストールした場合や、別の端末にインストールした場合は、アプリ領収書を更新して検証する「アプリ内購入の復元」機能を提供する必要があります。

+0

ありがとうございます...私はサブスクリプションIAPを使用していると言いましたが、購入したかどうかを知る必要はありませんが、期限切れかどうかを知る必要があります。最良のアプローチを見つけようとしていますか? – GarySabo

+0

質問をより具体的に更新しました。 – GarySabo

関連する問題