0

我正在开发订阅 IAP。我设置了所有购买,他们的详细信息恢复正常,我可以在沙盒中进行购买并获得所有消息。我现在遇到的问题是检查收据。我总是得到一个正常返回的 URL,但是当我尝试阅读它时,我不断收到文件不存在的错误。所以我尝试用SKReceiptRefreshRequest. 再试一次,还是一样。

我已经卸载了模拟器和两个真实设备上的应用程序,从新安装重试,同样的问题。我意识到的一件事是,其中一台真实设备显示密码提示请求并提及 [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
    }
}

这是运行应用程序的调试输出。收据URL在模拟器/真实设备之间有所不同,但除此之外一切都保持不变。

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

为什么我无法创建或找到收据?是设备问题、错误还是我忘记了什么?

4

2 回答 2

1

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

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

于 2017-04-25T12:07:10.180 回答
0

在进一步研究的过程中,我发现了以下文章,它解决了这个问题

文章

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

于 2017-04-25T14:03:39.727 回答