Restore auto-renewable subscription

Hello,


We use automatically renewable subscriptions.

our problem is that the app will continue to work even if the subscription has already been terminated / expired.



How can I find out if a subscription is still active?



our code is:


class LoadScreenViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {

    var list = [SKProduct]()
    var p = SKProduct()
    
    var checkSubscribe = true
    
    //ActivityIndicator Declaring
    var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        if(SKPaymentQueue.canMakePayments()) {
            print("IAP is enabled, loading")
            let productID: NSSet = NSSet(objects: "Se.Ds.RenewingSubMonthAuto", "Se.Ds.RenewingSubYearAuto")
            let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
            request.delegate = self
            request.start()
        } else {
            print("please enable IAPS")
        }
        
        restorePurchases()
        
        //ActivityIndicator Implement
        activityIndicator.center = self.view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white
        view.addSubview(activityIndicator)
        
        activityIndicator.startAnimating()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) { // Change `2.0` to the desired number of seconds.
            self.activityIndicator.stopAnimating()
            self.selectSubscription()
        }
        
    }
    
    func restorePurchases() {
        
        //        if SKPaymentQueue.canMakePayments(){
        print("restored complete")
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().restoreCompletedTransactions()
        //        }
        //        else{
        //            print("restored faild, IAP not activ?")
        //        }
    }
    
    func buyProduct() {
        print("buy " + p.productIdentifier)
        let pay = SKPayment(product: p)
        SKPaymentQueue.default().add(self)
        SKPaymentQueue.default().add(pay as SKPayment)
    }
    

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        print("product request")
        let myProduct = response.products
        for product in myProduct {
            print("product added")
            print(product.productIdentifier)
            print(product.localizedTitle)
            print(product.localizedDescription)
            print(product.price)
            
            list.append(product)
        }
    }

    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        print("transactions refresh")
        for transaction in queue.transactions {
            let t: SKPaymentTransaction = transaction
            let prodID = t.payment.productIdentifier as String
            
            switch prodID {
            case "Se.Ds.RenewingSubMonthAuto":
                print("Monthly subscription refreshed!")
                break
            case "Se.Ds.RenewingSubYearAuto":
                print("Yearly subscription refreshed!!")
                break
            default:
                print("IAP not found")
            }
        }
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        print("add payment")
        
        for transaction in transactions {
            print("ERROR: ", transaction.error as Any)
            switch transaction.transactionState {
                
            case .purchased:
                print("buy ok, unlock IAP HERE")
                print(p.productIdentifier)
                
                let prodID = p.productIdentifier
                switch prodID {
                case "Se.Ds.RenewingSubMonthAuto":
                    print("Monthly subscription purchased!!")
                    readySubscribe()
                    activityIndicator.stopAnimating()
                case "Se.Ds.RenewingSubYearAuto":
                    print("Yearly subscription purchased!!")
                    readySubscribe()
                    activityIndicator.stopAnimating()
                default:
                    print("IAP not found")
                }
                queue.finishTransaction(transaction)
                break
                
            case .restored:
                print("restored ok, unlock IAP HERE")
                print(p.productIdentifier)
                
                readySubscribe()
                activityIndicator.stopAnimating()
                queue.finishTransaction(transaction)
                break
                
            case .failed:
                print("buy error")
                alert(title: "Fail", message: transaction.error?.localizedDescription)
                queue.finishTransaction(transaction)
                activityIndicator.stopAnimating()
                break
                
            default:
                print("Default")
                break
            }
        }
    }
    
    func readySubscribe()  {
        UserDefaults.standard.setValue(checkSubscribe, forKeyPath: "subscribe")
        UserDefaults.standard.synchronize()
        self.performSegue(withIdentifier: "readySubscribe", sender: self)
    }
    
    func selectSubscription() {
        self.performSegue(withIdentifier: "selectSubscription", sender: self)
    }
    
    func alert (title:String, message:String?){
        
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
        
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: { (action) in
            alert.dismiss(animated: true, completion: nil)
        }))
        
        self.present(alert, animated: true, completion: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

Replies

TMI.


A device will receive a call to updatedTransactions with a new subscription renewal if that device ever called restoreCompletedTransactions. You can use that call to determine the expiration date of the subscription. If it appears that the subscription has expired you tell the user you have to check the subscription and you call restoreCompletedTransactions. That will generate a call back to updatedTransactions with the latest information.


Alternatively you can use the receipt. If you send any receipt to the Apple servers they will respond with the latest receipt information - and that will tell you if the subscription is still in effect.


So decide if you will be using a remote server or doing it all within the app. Then decide if you are going to decode the receipt yourself or send it to Apple.