2017-09-25 704 views
4

我試圖實現新的paymentQueue(_:shouldAddStorePayment:for:)方法,所以我的應用程序可以直接從App Store處理IAP。如何在iOS 11中處理應用內購買的shouldAddStorePayment?

我使用的是itms-services://網址來測試它,就像它說here

問題是,我的SKPaymentTransactionObserver是一個特定的視圖控制器,如果在打開itms-services://鏈接時不可見,則不會調用委託方法。

我該怎麼辦?我想我必須檢測用戶是否來自App Store推送正確的視圖控制器,但我不知道如何。我現在唯一能想到的其他選擇是使應用程序代理爲SKPaymentTransactionObserver,但這看起來非常麻煩,而且在嘗試時我無法使其工作。有沒有其他方法?

回答

6

這裏有一類我這樣做,可以幫助你實現你想要什麼,只需將下面的代碼複製並粘貼到新的文件中,然後你可以簡單地訪問類StoreManager.shared到你想要的任何方法/變量訪問。

1至初始化這個類,從你的didFinishLaunchingWithOptions StoreManager.shared.Begin只是調用(),然後加入支付觀察者。

import Foundation 
import StoreKit 


class StoreManager: NSObject{ 



    /** 
    Initialize StoreManager and load subscriptions SKProducts from Store 
    */ 
    static let shared = StoreManager() 

    func Begin(){ 
     print("StoreManager initialized".DubugText()) 
    } 


    override init() { 
     super.init() 


     // Add pyament observer to payment qu 
     SKPaymentQueue.default().add(self) 


    } 


    func requestProductWithID(identifers:Set<String>){ 

     if SKPaymentQueue.canMakePayments() { 
      let request = SKProductsRequest(productIdentifiers: 
       identifers) 
      request.delegate = self 
      request.start() 


     } else { 
      print("ERROR: Store Not Available") 
     } 


    } 

    func buyProduct(product: SKProduct) { 

     print("Buying \(product.productIdentifier)...") 
     let payment = SKPayment(product: product) 
     SKPaymentQueue.default().add(payment) 


    } 


    func restorePurchases(){ 

     SKPaymentQueue.default().restoreCompletedTransactions() 
    } 
    /* 
    Instance variables 

    */ 

} 








// MARK: 
// MARK: SKProductsRequestDelegate 

//The delegate receives the product information that the request was interested in. 
extension StoreManager:SKProductsRequestDelegate{ 

    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { 

     var products = response.products as [SKProduct] 


     var buys = [SKProduct]() 

     if (products.count > 0) { 

      for i in 0 ..< products.count 
      { 
       let product = products[i] 


       print("Product Found: ",product.localizedTitle) 
      } 


     } else { 
      print("No products found") 
     } 

     let productsInvalidIds = response.invalidProductIdentifiers 

     for product in productsInvalidIds 
     { 
      print("Product not found: \(product)") 
     } 
    } 


    func request(_ request: SKRequest, didFailWithError error: Error) { 
     print("Something went wrong: \(error.localizedDescription)") 
    } 
} 



// MARK: 
// MARK: SKTransactions 


extension StoreManager: SKPaymentTransactionObserver { 



    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
     for transaction in transactions { 
      switch (transaction.transactionState) { 
      case .purchased: 
       completeTransaction(transaction: transaction) 
       break 
      case .failed: 
       failedTransaction(transaction: transaction) 
       break 
      case .restored: 
       restoreTransaction(transaction: transaction) 
       break 
      case .deferred: 
       // TODO show user that is waiting for approval 

       break 
      case .purchasing: 
       break 
      } 
     } 
    } 

    private func completeTransaction(transaction: SKPaymentTransaction) { 

     print("completeTransaction...") 

     deliverPurchaseForIdentifier(identifier: transaction.payment.productIdentifier) 
     SKPaymentQueue.default().finishTransaction(transaction) 
    } 

    private func restoreTransaction(transaction: SKPaymentTransaction) { 


     guard let productIdentifier = transaction.original?.payment.productIdentifier else { return } 

     print("restoreTransaction... \(productIdentifier)") 


     deliverPurchaseForIdentifier(identifier: productIdentifier) 
     SKPaymentQueue.default().finishTransaction(transaction) 
    } 

    private func failedTransaction(transaction: SKPaymentTransaction) { 

     if let error = transaction.error as NSError? { 
      if error.domain == SKErrorDomain { 
       // handle all possible errors 
       switch (error.code) { 
       case SKError.unknown.rawValue: 
        print("Unknown error") 

       case SKError.clientInvalid.rawValue: 
        print("client is not allowed to issue the request") 


       case SKError.paymentCancelled.rawValue: 
        print("user cancelled the request") 

       case SKError.paymentInvalid.rawValue: 
        print("purchase identifier was invalid") 

       case SKError.paymentNotAllowed.rawValue: 
        print("this device is not allowed to make the payment") 

       default: 
        break; 
       } 
      } 


     } 

     SKPaymentQueue.default().finishTransaction(transaction) 
    } 

    private func deliverPurchaseForIdentifier(identifier: String?) { 

     guard let identifier = identifier else { return } 


    } 
} 



//In-App Purchases App Store 
extension StoreManager{ 

    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool { 
     return true 

     //To hold 
     //return false 

     //And then to continue 
     //SKPaymentQueue.default().add(savedPayment) 
    } 

} 
+0

好的,我希望有一種方法可以做到我想要的沒有所有這些,但是您的答案無論如何是巨大的幫助,所以我會將其標記爲已接受。謝謝。 :) – dbmrq

+0

不錯,簡單的解決方案!在沒有額外痛苦的情況下爲我工作=) –