2017-10-10 89 views
3

每當我構建一個adhoc構建並在ios 11上運行它時,它會彈出消息「需要登錄 - 輸入***** [Environment:Sandbox]的密碼」。因此,這繼續像循環激活而不會消失。嘗試從iCloud發出也沒有工作。我inAppPurchase代碼如下。登錄所需的環境沙盒問題

class InAppPurchase: NSObject,SKProductsRequestDelegate, 

SKPaymentTransactionObserver { 


    ///Singleton 
    private static var inappPurChase:InAppPurchase?; 

    public static var shared:InAppPurchase { 
     if inappPurChase == nil{ 
      inappPurChase = InAppPurchase() 
     } 
     return inappPurChase! 
    } 
    override private init() { 
     //Singleton complete 
    } 
    //////////// 

    var productsList = [SKProduct]() 
    var productToPurchase = SKProduct() 
    var productID = "" 
    let PURCHASE_ID_PREFIX = ""//"com.purelightbeta." 
    var onInAppPurchaseSuccess: (()->Void)? = nil 
    var onInAppPurchaseError: (()->Void)? = nil 
    var onNoProductsIDs: (()->Void)? = nil 
    var appEnvironment: ((String,Bool)->Void)? = nil 
    var onReceiptVarificationError: (()->Void)? = nil 
    var onRestorePurchaseError: ((String)->Void)? = nil 
    var onRestoreProductsIDs: ((NSMutableArray)->Void)? = nil 


    public func initPayment (productID: String) { 
     self.productID = PURCHASE_ID_PREFIX + productID 
     print("Initializing Purchase Product ID: \(self.productID)") 
     if SKPaymentQueue.canMakePayments() { 
      let productID: NSSet = NSSet(objects: self.productID) 
      let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>) 
      request.delegate = self 
      request.start() 
     }else { 
      print("In App Purchases not enabled") 
     } 
    } 

    func buyProduct() { 
     let payment = SKPayment(product: productToPurchase) 
     SKPaymentQueue.default().add(self) 
     SKPaymentQueue.default().add(payment as SKPayment) 
    } 


    public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { 
     let myProducts = response.products 
     print(myProducts) 
     productsList = [] 
     if myProducts.count == 0 { 
      print("No products") 
      if(onNoProductsIDs != nil){ 
      onNoProductsIDs!() 
      } 
     } 
     for product in myProducts { 
      print("Prod Details :\(product.productIdentifier) \(product.price) \(product.localizedDescription)") 
      productsList.append(product) 
     } 


     for product in productsList { 
      let productID = product.productIdentifier 
      if productID == self.productID { 
       productToPurchase = product 
       buyProduct() 
      } 
     } 

    } 

    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { 
     let productIDs: NSMutableArray = [] 
     for trasacton in queue.transactions { 
      if trasacton.transactionState == SKPaymentTransactionState.restored 
      { 
       let t: SKPaymentTransaction = trasacton as SKPaymentTransaction 
       let prodID = t.payment.productIdentifier as String 
       print("prodID:",prodID) 

       //let appStoreId = prodID.components(separatedBy: "com.purelightbeta.") 

       productIDs.add(prodID) 
       SKPaymentQueue .default().finishTransaction(trasacton) 

      } 

     } 
     if onRestoreProductsIDs != nil { 
      print(productIDs) 
      onRestoreProductsIDs! (productIDs) 
     } 

    } 

    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { 
     for transaction: AnyObject in transactions { 
      let trans = transaction as! SKPaymentTransaction 
      print(trans.error ?? "No in app error") 
      switch trans.transactionState { 
      case .purchased: 
       print("buy ok, AIP unlocked for item :", productToPurchase.productIdentifier) 
       let productID = productToPurchase.productIdentifier 

       switch productID { 
       case self.productID: 
        print("Item found") 
        // startValidatingReceipt() 
       default: 
        print("Item not found") 
       } 
       queue.finishTransaction(trans) 
       if self.onInAppPurchaseSuccess != nil { 
        self.onInAppPurchaseSuccess!() 
        self.startValidatingReceipt() 
       } 
      case .failed: 
       print("buy error") 
       if self.onInAppPurchaseError != nil { 
        self.onInAppPurchaseError!() 

       } 
       queue.finishTransaction(trans) 
       break 

      case .restored: 
       SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction) 
       // break 

      default: 
       print("default") 
       break 
      } 

     } 
    } 
    func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { 
     print("ERROR: \(error.localizedDescription)") 
     if onRestorePurchaseError != nil { 
      onRestorePurchaseError! (error.localizedDescription) 
     } 
    } 

    func restorePurchase() { 
     SKPaymentQueue.default().add(self) 
     SKPaymentQueue.default().restoreCompletedTransactions() 

    } 



    func startValidatingReceipt() { 
     if let isExists = try? self.getReceiptURL()?.checkResourceIsReachable(), isExists == true { 
      do { 
      let data = try Data(contentsOf: self.getReceiptURL()!) 
       // self.startValidatingData(data: data) 
       self.sendReceiptToLocalServer(data: data) 
      }catch { 
       let appReceiptRefreshRequest = SKReceiptRefreshRequest(receiptProperties: nil) 
       appReceiptRefreshRequest.delegate = self 
       appReceiptRefreshRequest.start() 
      } 
     }else { 
     print("No receipt for this purchase") 
     } 
    } 
    func getReceiptURL() -> URL? { 
     return Bundle.main.appStoreReceiptURL 
    } 


    enum receiptValidationURLs:String { 
     case sandbox = "https://sandbox.itunes.apple.com/verifyReceipt" 
     case production = "https://buy.itunes.apple.com/verifyReceipt" 

     static var url:URL{ 
      if isDebug { 
      return URL.init(string: self.sandbox.rawValue)! 
      }else{ 
      return URL.init(string: self.production.rawValue)! 
      } 
     } 
    } 
    func sendReceiptToLocalServer(data:Data) { 
     let base64encodedReceipt = data.base64EncodedString() 

     if self.appEnvironment != nil { 
      self.appEnvironment! (base64encodedReceipt,isDebug) 
     } 
    } 
    func startValidatingData(data:Data){ 


     let base64encodedReceipt = data.base64EncodedString() 
     print(base64encodedReceipt) 
     let requestDictionary = ["receipt-data":base64encodedReceipt] 
     guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return } 
     do { 
      let requestData = try JSONSerialization.data(withJSONObject: requestDictionary) 
     //  let validationURLString = "https://sandbox.itunes.apple.com/verifyReceipt" // this works but as noted above it's best to use your own trusted server 
      NSLog("The Environment is: %@", receiptValidationURLs.url.absoluteString) 
      guard let validationURL = URL(string: receiptValidationURLs.url.absoluteString) else { print("the validation url could not be created, unlikely error"); return } 
      let session = URLSession(configuration: URLSessionConfiguration.default) 
      var request = URLRequest(url: validationURL) 
      request.httpMethod = "POST" 
      request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData 
      let task = session.uploadTask(with: request, from: requestData) { (data, response, error) in 
       if let data = data , error == nil { 
        do { 
         let appReceiptJSON = try JSONSerialization.jsonObject(with: data) 
         print((appReceiptJSON as AnyObject).count) 
         print("success. here is the json representation of the app receipt: \(appReceiptJSON)") 
         NSLog("Receipt is: %@", appReceiptJSON as! NSDictionary) 
         if let environment = (appReceiptJSON as? NSDictionary)?["environment"]{ 

         if self.appEnvironment != nil { 
          self.appEnvironment! (environment as? String ?? "No value",isDebug) 
         } 
         } 
        } catch let error as NSError { 
         print("json serialization failed with error: \(error)") 
        } 
       } else { 
        print("the upload task returned an error: \(error)") 
       } 
      } 
      task.resume() 
     } catch let error as NSError { 
      print("json serialization failed with error: \(error)") 
     } 
    } 

// func requestDidFinish(_ request: SKRequest) { 
//  // a fresh receipt should now be present at the url 
//  do { 
// 
//    
// 
//  } catch { 
//   // still no receipt, possible but unlikely to occur since this is the "success" delegate method 
//  } 
// } 

    func request(_ request: SKRequest, didFailWithError error: Error) { 
     print("app receipt refresh request did fail with error: \(error)") 
     // for some clues see here: https://samritchie.net/2015/01/29/the-operation-couldnt-be-completed-sserrordomain-error-100/ 
     if self.onReceiptVarificationError != nil { 
      self.onReceiptVarificationError!() 
     } 

    } 


} 
+1

請問您可以在這裏發佈您的IAP代碼...我認爲您的觀察員處理過程中出現問題 – AlexWoe89

+0

代碼已更新並已發佈 – danu

回答

0

這可能不是答案,但將是一種解決方法。最好的辦法是創建一個新的沙箱用戶,註銷舊沙箱並放入新沙箱。