我对iOS应用内购买有疑问,具体针对"自动续订订阅" 我开发的应用程序包含免费功能和付费功能: 基于"每月订阅和&amp ;;的付费功能用户有一个免费试用1周"
并且所有流程都很好:我们将获取产品和产品用户可以购买&我们将验证收据(我知道食谱包含“is_trial ..”和“Purchase_date”的标志......)...... ..
请注意:我在购买后或恢复后称之为“验证食谱”但我有以下问题: 我怎么知道以下内容:
1-如果用户第二次打开应用程序,我怎么知道用户是否还在试用期?
2-如果用户在1个月后打开应用程序:我怎么知道订阅是否已过期...(所以如果订阅过期,我将再次购买电话......)
,每当用户打开应用程序时,我会称之为“验证食谱”的解决方案,因此我可以知道用户是否处于付费或付费期后(已过期)......
或者我会在本地保存购买日期(例如:用户默认)&当用户打开应用程序时,我会将当前日期与购买日期进行比较,实际上我认为这不是一个真正的答案,因为用户可能会更改设备日期....
请建议......
代码belwo:所以现在打开app时: 我要求产品:
SKPaymentQueue.default().add(self)
if(SKPaymentQueue.canMakePayments()) {
print("IAP is enabled, loading")
let productID: NSSet = NSSet(objects: "test.test1.test2.11")
let request: SKProductsRequest = SKProductsRequest(productIdentifiers: productID as! Set<String>)
request.delegate = self
request.start()
} else {
print("please enable IAPS")
}
收到产品时:
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
print("product request")
let myProduct = response.products
for product in myProduct {
list.append(product)
}
}
现在,当用户按下按钮时:
for product in self.list {
let prodID = product.productIdentifier
if(prodID == "test.test1.test2.11") {
self.p = product
self.buyProduct()
}
}
下面的方法将调用
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
print("add payment")
for transaction: AnyObject in transactions {
let trans = transaction as! SKPaymentTransaction
switch trans.transactionState {
case .purchased:
receiptValidation()
queue.finishTransaction(trans)
break
case .failed:
print("buy error")
queue.finishTransaction(trans)
break
default:
print("Default")
break
}
}
}
&安培;我将验证收据:
func receiptValidation() {
if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
do {
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
let dict = ["receipt-data" : receiptString, "password" : "xxxxxxxxxxx"] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)
if let sandboxURL = Foundation.URL(string:"https://sandbox.itunes.apple.com/verifyReceipt") {
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
if let receivedData = data,
let httpResponse = response as? HTTPURLResponse,
error == nil,
httpResponse.statusCode == 200 {
do {
if let jsonResponse = try JSONSerialization.jsonObject(with: receivedData, options: JSONSerialization.ReadingOptions.mutableContainers) as? Dictionary<String, AnyObject> {
} else { print("Failed to cast serialized JSON to Dictionary<String, AnyObject>") }
}
catch { print("Couldn't serialize JSON with error: " + error.localizedDescription) }
}
}
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 { print("Couldn't read receipt data with error: " + error.localizedDescription) }
}
}
答案 0 :(得分:1)
Highly recommended you store the user premium state and do receipt validation server-side. This way YOU keep meta-data about the user, their subscription expiration, free trial status etc. on your server and just refresh THAT on startup. You can then setup intelligent polling to Apple's servers for receipt validation/expiration checks (should also be done server-side) based on the users start/end dates. This will maintain their premium or non-premium state and allow you trigger the necessary client UI.