2017-04-25 39 views
0

我正在订阅IAP。我将所有购买项目设置完毕,细节恢复得很好,我可以在沙箱中购物并获取所有消息。我现在的问题是检查收据。我总是收到一个URL,但是当我尝试阅读它时,我总是收到文件不存在的错误。所以我试着用SKReceiptRefreshRequest刷新。再试一次,依然如此。收据验证iOS - 文件无法打开,因为没有这样的文件

我已经在模拟器和两个真实设备上卸载应用程序,再次尝试从新安装和相同的问题。有一件事我意识到,其中一个真实的设备显示密码提示请求[Sandbox]提及。但经过两次提示(包括接受密码),而不是购买完成后,我得到一个“用户/密码不匹配”的消息。在模拟器上,当提示输入iTunes帐户和密码时,所有消息都会通过,但实际的购买确认从未到来(我等了4分钟,稳定的互联网连接)。

这是验证过程(我已经改变了它好几次,从不同的教程和其他人的问题)

let receiptURL = Bundle.main.appStoreReceiptURL 
func receiptValidation() { 
    print("1") 
     print("2", receiptURL) 
     do { 
      print("3") 
      let receiptData = try Data(contentsOf: receiptURL!, options: .alwaysMapped) 
      print(receiptData) 
      let receiptString = receiptData.base64EncodedString(options: []) 
      let dict = ["receipt-data" : receiptString, "password" : "\(password)"] as [String : Any] 

      do { 
       print("4") 
       let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) 

       if let sandboxURL = Foundation.URL(string:"https://sandbox.itunes.apple.com/verifyReceipt") { 
        print("5") 
        var request = URLRequest(url: sandboxURL) 
        request.httpMethod = "POST" 
        request.httpBody = jsonData 
        let session = URLSession(configuration: URLSessionConfiguration.default) 
        let task = session.dataTask(with: request) { data, response, error in 
         print("6") 
         if let receivedData = data, 
          let httpResponse = response as? HTTPURLResponse, 
          error == nil, 
          httpResponse.statusCode == 200 { 
          print("7") 
          do { 
           print("8") 
           if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject> { 
            print(jsonResponse, jsonResponse.count) 
            // parse and verify the required informatin in the jsonResponse 

           } else { print("Failed to cast serialized JSON to Dictionary<String, AnyObject>") } 
          } 
          catch { print("Couldn't serialize JSON with error: " + error.localizedDescription) } 
         } 
        } 
        print("51") 
        task.resume() 
       } else { print("Couldn't convert string into URL. Check for special characters.") } 
      } 
      catch { print("Couldn't create JSON with error: " + error.localizedDescription) } 
     } 
     catch { 
      let appReceiptRefreshRequest = SKReceiptRefreshRequest(receiptProperties: nil) 
      appReceiptRefreshRequest.delegate = self 
      appReceiptRefreshRequest.start() 
      print("Couldn't read receipt data with error: " + error.localizedDescription) } 
    } 

func requestDidFinish(_ request: SKRequest) { 
    print("???") 
    do { 
     let receipt = try Data(contentsOf: receiptURL!) //force unwrap is safe here, control can't land here if receiptURL is nil 
     print(receipt) 
    } catch { 
     print("WTF NO RECEIPT") 
     // still no receipt, possible but unlikely to occur since this is the "success" delegate method 
    } 
} 

这是从运行应用程序输出的调试。 receiptURL在模拟器/真实设备之间有所不同,但其他则保持不变。

1 
2 Optional(file:///Users/apple/Library/Developer/CoreSimulator/Devices/47EA3293-9B13-4808-BD0B-13D884D14BFE/data/Containers/Data/Application/2F1B7E4E-C523-4270-BF46-6D77F7A2220C/StoreKit/receipt) 
3 
Couldn't read receipt data with error: The file “receipt” couldn’t be opened because there is no such file. 
??? 
WTF NO RECEIPT 
??? 
WTF NO RECEIPT 

为什么我无法获得创建或找到的收据?这是一个设备问题,一个错误还是我忘记了什么?

回答

1

整个IAP过程异步工作,因此除非整个过程已成功完成,否则您将不会收到收据数据。根据上述问题粘贴的内容,我无法看到整个代码,但如果您试图通过按钮或类似的操作立即访问收据数据,您将无法获得。

访问收据数据的正确方法是尝试根据您的IAP请求的成功完成处理程序回调访问收据。提交IAP请求后,会有一个服务器端进程负责处理IAP,然后触发IAP SKPaymentTransactionObserver类的回调处理程序。使用此类中的通知处理程序,您可以将更新发送到ViewController以检查收据数据。

+0

所以你说什么时候付款完成,我得到一个transaction.state的购买,我应该下载收据?我认为收据会在购买时自动下载。即便如此,为什么SKReceiptRefreshRequest不起作用,并且每次分配一个appStoreReceiptURL,但在阅读时都会失败? –

0

虽然进一步研究,我发现下面的文章,它解决了这个问题

article

重要提示:如果您错误地使用沙盒测试帐户登录到生产环境中测试设备而不是您的测试环境,则沙箱帐户将变为无效,并且不能再次使用。如果发生这种情况,请用新的电子邮件地址创建一个新的沙盒测试人员帐户。

相关问题