2016-12-31 110 views
0

我在應用程序內購買已impelmented我app.I遵循this tutorial在我的應用程序在iOS應用內購買問題?

現在,當我嘗試加載產品,那麼它不load.It顯示誤差無法連接到iTunes store.I已經craeted iTunes上有一款產品。

下面是代碼

/ 

    * 
    * Copyright (c) 2016 Razeware LLC 
    * 
    * Permission is hereby granted, free of charge, to any person obtaining a copy 
    * of this software and associated documentation files (the "Software"), to deal 
    * in the Software without restriction, including without limitation the rights 
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
    * copies of the Software, and to permit persons to whom the Software is 
    * furnished to do so, subject to the following conditions: 
    * 
    * The above copyright notice and this permission notice shall be included in 
    * all copies or substantial portions of the Software. 
    * 
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
    * THE SOFTWARE. 
    */ 

    import StoreKit 

    public typealias ProductIdentifier = String 
    public typealias ProductsRequestCompletionHandler = (_ success: Bool, _ products: [SKProduct]?) ->() 

    open class IAPHelper : NSObject { 

     static let IAPHelperPurchaseNotification = "IAPHelperPurchaseNotification" 
     fileprivate let productIdentifiers: Set<ProductIdentifier> 
     fileprivate var purchasedProductIdentifiers = Set<ProductIdentifier>() 
     fileprivate var productsRequest: SKProductsRequest? 
     fileprivate var productsRequestCompletionHandler: ProductsRequestCompletionHandler? 

     public init(productIds: Set<ProductIdentifier>) { 
     productIdentifiers = productIds 
     for productIdentifier in productIds { 
      let purchased = UserDefaults.standard.bool(forKey: productIdentifier) 
      if purchased { 
      purchasedProductIdentifiers.insert(productIdentifier) 
      print("Previously purchased: \(productIdentifier)") 
      } else { 
      print("Not purchased: \(productIdentifier)") 
      } 
     } 
     super.init() 
     SKPaymentQueue.default().add(self) 
     } 

    } 

    // MARK: - StoreKit API 

    extension IAPHelper { 

     public func requestProducts(completionHandler: @escaping ProductsRequestCompletionHandler) { 
     productsRequest?.cancel() 
     productsRequestCompletionHandler = completionHandler 

     productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers) 
     productsRequest!.delegate = self 
     productsRequest!.start() 
     } 

     public func buyProduct(_ product: SKProduct) { 
     print("Buying \(product.productIdentifier)...") 
     let payment = SKPayment(product: product) 
     SKPaymentQueue.default().add(payment) 
     } 

     public func isProductPurchased(_ productIdentifier: ProductIdentifier) -> Bool { 
     return purchasedProductIdentifiers.contains(productIdentifier) 
     } 

     public class func canMakePayments() -> Bool { 
     return SKPaymentQueue.canMakePayments() 
     } 

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

    // MARK: - SKProductsRequestDelegate 

    extension IAPHelper: SKProductsRequestDelegate { 

     public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { 
     let products = response.products 
     print("Loaded list of products...") 
     productsRequestCompletionHandler?(true, products) 
     clearRequestAndHandler() 

     for p in products { 
      print("Found product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)") 
     } 
     } 

     public func request(_ request: SKRequest, didFailWithError error: Error) { 
     print("Failed to load list of products.") 
     print("Error: \(error.localizedDescription)") 
     productsRequestCompletionHandler?(false, nil) 
     clearRequestAndHandler() 
     } 

     private func clearRequestAndHandler() { 
     productsRequest = nil 
     productsRequestCompletionHandler = nil 
     } 
    } 

    // MARK: - SKPaymentTransactionObserver 

    extension IAPHelper: SKPaymentTransactionObserver { 

     public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
     for transaction in transactions { 
      switch (transaction.transactionState) { 
      case .purchased: 
      complete(transaction: transaction) 
      break 
      case .failed: 
      fail(transaction: transaction) 
      break 
      case .restored: 
      restore(transaction: transaction) 
      break 
      case .deferred: 
      break 
      case .purchasing: 
      break 
      } 
     } 
     } 

     private func complete(transaction: SKPaymentTransaction) { 
     print("complete...") 
     deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier) 
     SKPaymentQueue.default().finishTransaction(transaction) 
     } 

     private func restore(transaction: SKPaymentTransaction) { 
     guard let productIdentifier = transaction.original?.payment.productIdentifier else { return } 

     print("restore... \(productIdentifier)") 
     deliverPurchaseNotificationFor(identifier: productIdentifier) 
     SKPaymentQueue.default().finishTransaction(transaction) 
     } 

     private func fail(transaction: SKPaymentTransaction) { 
     print("fail...") 
     if let transactionError = transaction.error as? NSError { 
      if transactionError.code != SKError.paymentCancelled.rawValue { 
      print("Transaction Error: \(transaction.error?.localizedDescription)") 
      } 
     } 

     SKPaymentQueue.default().finishTransaction(transaction) 
     } 

     private func deliverPurchaseNotificationFor(identifier: String?) { 
     guard let identifier = identifier else { return } 

     purchasedProductIdentifiers.insert(identifier) 
     UserDefaults.standard.set(true, forKey: identifier) 
     UserDefaults.standard.synchronize() 
     NotificationCenter.default.post(name: NSNotification.Name(rawValue: IAPHelper.IAPHelperPurchaseNotification), object: identifier) 
     } 
    } 

請指導問題是什麼?

編輯: 失敗,錯誤被調用。「未能加載產品列表。」

+0

什麼是錯誤? –

+0

未獲取產品 – iOSGuy

回答

0

確保您已註銷設備上的任何生產iTunes帳戶。

我在使用我的實際iTunes帳戶登錄的測試電話上出現此錯誤。 您無法使用您製作的iTunes帳戶測試應用程序,因此出現此錯誤。我只是希望蘋果提供了更好的錯誤,以避免這種猜測...

解決方案創建測試用戶帳戶,如果你沒有一個。使用該帳戶測試應用內購買。

備註:如果您沒有收到產品,請確保您在發送與iTunes上的產品標識符相匹配的請求時使用產品標識。

另一個愚蠢的原因是,我們在模擬器上運行時遇到此錯誤。檢查是否

您的應用程序在模擬器中運行,不支持應用內廣告 購買

+0

我是否需要使用產品的測試員帳戶登錄 – iOSGuy

+0

我需要使用測試員帳戶登錄才能獲得產品 - – iOSGuy

+0

是的。否則,你不能測試應用內購買 –

0

退出iTunes的& iCloud帳戶後重置我的iOS設備&在應用程序內購買奮力盡管我不知道爲什麼。

您無需登錄iOS設備即可從應用程序購買中獲取產品。對於購買產品,我們必須先登錄設備。