在Swift 3中实现收据验证

编程入门 行业动态 更新时间:2024-10-10 00:26:26
本文介绍了在Swift 3中实现收据验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在开发Swift 3中的iOS应用程序并尝试按照本教程实现收据验证: savvyapps/blog/how-setup-test-auto-renewable-subscription-ios-app 。但是,该教程似乎是使用早期版本的Swift编写的,因此我不得不进行一些更改。这是我的receiptValidation()函数:

I am developing an iOS app in Swift 3 and trying to implement receipt validation following this tutorial: savvyapps/blog/how-setup-test-auto-renewable-subscription-ios-app. However, the tutorial seems to have been written using an earlier version of Swift, so I had to make several changes. Here is my receiptValidation() function:

func receiptValidation() { let receiptPath = Bundle.main.appStoreReceiptURL?.path if FileManager.default.fileExists(atPath: receiptPath!){ var receiptData:NSData? do{ receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped) } catch{ print("ERROR: " + error.localizedDescription) } let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) let postString = "receipt-data=" + receiptString! + "&password=" + SUBSCRIPTION_SECRET let storeURL = NSURL(string:"sandbox.itunes.apple/verifyReceipt")! let storeRequest = NSMutableURLRequest(url: storeURL as URL) storeRequest.httpMethod = "POST" storeRequest.httpBody = postString.data(using: .utf8) let session = URLSession(configuration:URLSessionConfiguration.default) let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in do{ let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)! self.updateIAPExpirationDate(date: expirationDate) } catch{ print("ERROR: " + error.localizedDescription) } } task.resume() } }

问题出现了当我尝试调用expirationDateFromResponse()方法时。事实证明,传递给此方法的jsonResponse仅包含: status = 21002; 。我查了一下,这意味着收据数据属性中的数据格式错误或丢失。但是,我正在测试的设备有一个活动的沙盒订阅产品,除了这个问题,订阅似乎正常工作。我还需要做些什么来确保receiveData值被正确读取和编码,或者其他一些可能导致此问题的问题?

The problem shows up when I try to call the expirationDateFromResponse() method. It turns out that the jsonResponse that gets passed to this method only contains: status = 21002;. I looked this up and it means "The data in the receipt-data property was malformed or missing." However, the device I'm testing on has an active sandbox subscription for the product, and the subscription seems to work correctly aside from this issue. Is there something else I still need to do to make sure the receiptData value will be read and encoded correctly, or some other issue that might be causing this problem?

编辑:

我尝试了另一种设置storeRequest.httpBody的方法:

I tried an alternate way of setting storeRequest.httpBody:

func receiptValidation() { let receiptPath = Bundle.main.appStoreReceiptURL?.path if FileManager.default.fileExists(atPath: receiptPath!){ var receiptData:NSData? do{ receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped) } catch{ print("ERROR: " + error.localizedDescription) } let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) //.URLEncoded let dict = ["receipt-data":receiptString, "password":SUBSCRIPTION_SECRET] as [String : Any] var jsonData:Data? do{ jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted) } catch{ print("ERROR: " + error.localizedDescription) } let storeURL = NSURL(string:"sandbox.itunes.apple/verifyReceipt")! let storeRequest = NSMutableURLRequest(url: storeURL as URL) storeRequest.httpMethod = "POST" storeRequest.httpBody = jsonData! let session = URLSession(configuration:URLSessionConfiguration.default) let task = session.dataTask(with: storeRequest as URLRequest) { data, response, error in do{ let jsonResponse:NSDictionary = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary let expirationDate:NSDate = self.expirationDateFromResponse(jsonResponse: jsonResponse)! self.updateIAPExpirationDate(date: expirationDate) } catch{ print("ERROR: " + error.localizedDescription) } } task.resume() } }

然而,当我使用此代码运行应用程序,它会在到达 jsonData = try JSONSerialization.data(withJSONObject:dict,options:.prettyPrinted)行时挂起。它甚至没有进入捕获块,它只是停止做任何事情。从我在网上看到的,其他人似乎在使用JSONSerialization.data在Swift 3中设置请求httpBody时遇到了麻烦。

However, when I run the app with this code, it hangs upon reaching the line jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted). It doesn't even make it to the catch block, it just stops doing anything. From what I've seen online, other people seem to have trouble using JSONSerialization.data to set the request httpBody in Swift 3.

推荐答案

它与Swift 4正常工作

Its working correctly with Swift 4

func receiptValidation() { let SUBSCRIPTION_SECRET = "yourpasswordift" let receiptPath = Bundle.main.appStoreReceiptURL?.path if FileManager.default.fileExists(atPath: receiptPath!){ var receiptData:NSData? do{ receiptData = try NSData(contentsOf: Bundle.main.appStoreReceiptURL!, options: NSData.ReadingOptions.alwaysMapped) } catch{ print("ERROR: " + error.localizedDescription) } //let receiptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) let base64encodedReceipt = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions.endLineWithCarriageReturn) print(base64encodedReceipt!) let requestDictionary = ["receipt-data":base64encodedReceipt!,"password":SUBSCRIPTION_SECRET] guard JSONSerialization.isValidJSONObject(requestDictionary) else { print("requestDictionary is not valid JSON"); return } do { let requestData = try JSONSerialization.data(withJSONObject: requestDictionary) let validationURLString = "sandbox.itunes.apple/verifyReceipt" // this works but as noted above it's best to use your own trusted server guard let validationURL = URL(string: validationURLString) 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("success. here is the json representation of the app receipt: \(appReceiptJSON)") // if you are using your server this will be a json representation of whatever your server provided } 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)") } } }

更多推荐

在Swift 3中实现收据验证

本文发布于:2023-11-26 09:07:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1633494.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:收据   Swift

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!