展开可选值错误 - 检查应用内购买的收据响应
unwrapping an Optional value error - Checking Receipt Response For In App Purchase
在应用程序启动时,我正在检查应用程序购买中自动续订的收据状态:
应用程序委托
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
println("Check for receipt on background queue")
self.CheckReciptStatus()
}
func CheckReciptStatus(){
var response: NSURLResponse?
var error: NSError?
var receiptUrl = NSBundle.mainBundle().appStoreReceiptURL
println("reciptUrl: '\(receiptUrl)'")
//
// Nil error on this line
//
var receipt: NSData = NSData(contentsOfURL:receiptUrl!, options: nil, error: nil)!
//
var receiptdata: NSString = receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
println(receiptdata)
var request = NSMutableURLRequest(URL: NSURL(string: "http://www.someurl.uk/verifyReceipt.php")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = receiptdata.dataUsingEncoding(NSASCIIStringEncoding)
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
if(err != nil)
{
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
//
// ---Recipt data ---
//
if let parseJSON = json {
if parseJSON["status"] as? Int == 0 {
println("Sucessfully returned purchased receipt data")
}
else{
println("Receipt error")
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "subscribed")
}
// Get latest expiry date
if let receiptInfo: NSArray = parseJSON["latest_receipt_info"] as? NSArray {
let lastReceipt = receiptInfo.lastObject as! NSDictionary
// Get last recipt
println("LAST RECIPT INFORMATION \n",lastReceipt)
// Format date
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
// Get Expiry date as NSDate
let subscriptionExpirationDate: NSDate = formatter.dateFromString(lastReceipt["expires_date"] as! String) as NSDate!
println("\n - DATE SUBSCRIPTION EXPIRES = \(subscriptionExpirationDate)")
println(" - CURRENT DATE = \(NSDate())")
//
// --- Subscription Status ----
//
if subscriptionExpirationDate.timeIntervalSinceNow < 0.0 {
// Date has passed
println("\n -> SUBSCRIPTION EXPIRED \n ")
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "subscribed")
}
else{
println("\n -> SUBSCRIBED \n")
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "subscribed")
}
}
}
else {
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Receipt Error: \(jsonStr)")
}
}
})
task.resume()
}
}
获取收据信息
var receiptUrl = NSBundle.mainBundle().appStoreReceiptURL
打印:
reciptUrl:
'Optional(file:///private/var/mobile/Containers/Data/Application/D0C4DAF0-952F-4C29-9D94-B68DB1FF036F/StoreKit/sandboxReceipt)'
var receipt: NSData = NSData(contentsOfURL:receiptUrl!, options: nil, error: nil)!
产生错误
unexpectedly found nil while unwrapping an Optional value
即使我得到 storekit receipt url
。所以这导致相信这是因为 var receipt
中的力展开。好的,所以当我尝试将行更改为
var receipt: NSData = NSData(contentsOfURL:receiptUrl?, options: nil, error: nil)?
我刚刚被告知 NSData
没有展开 did I mean "!" or "??"
后缀 !
导致 强制展开。
后缀 ?
用于 可选链接 。这意味着,如果 ?
之前的表达式的结果不是 nil
,将计算链中的下一个表达式。可选链的结果始终是 Optional
,因为链上的任何表达式都可能导致 nil
.
因此,在一个表达式上使用后缀 ?
运算符是无用的,因为它 returns 表达式本身。
??
是 nil 合并运算符。这个运算符是语法糖,用三元运算符替换了一个常见的模式:
return myOptional ?? defaultResult
等同于:
return (myOptional != nil) ? myOptional! : defaultResult
与以下相同:
if myOptional != nil {
return myOptional!
} else {
return defaultResult
}
如果您想使用此运算符,则必须提供一个默认值,如果您的 Optional
实际上是 nil
.
,则使用该默认值
使用
检查收据是否存在
var fileExists = NSFileManager.defaultManager().fileExistsAtPath(receiptUrl!.path!)
if fileExists {
println("Appstore Receipt already exists")
}
排序
在应用程序启动时,我正在检查应用程序购买中自动续订的收据状态:
应用程序委托
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
println("Check for receipt on background queue")
self.CheckReciptStatus()
}
func CheckReciptStatus(){
var response: NSURLResponse?
var error: NSError?
var receiptUrl = NSBundle.mainBundle().appStoreReceiptURL
println("reciptUrl: '\(receiptUrl)'")
//
// Nil error on this line
//
var receipt: NSData = NSData(contentsOfURL:receiptUrl!, options: nil, error: nil)!
//
var receiptdata: NSString = receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
println(receiptdata)
var request = NSMutableURLRequest(URL: NSURL(string: "http://www.someurl.uk/verifyReceipt.php")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var err: NSError?
request.HTTPBody = receiptdata.dataUsingEncoding(NSASCIIStringEncoding)
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var err: NSError?
var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves, error: &err) as? NSDictionary
if(err != nil)
{
println(err!.localizedDescription)
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Error could not parse JSON: '\(jsonStr)'")
}
else {
//
// ---Recipt data ---
//
if let parseJSON = json {
if parseJSON["status"] as? Int == 0 {
println("Sucessfully returned purchased receipt data")
}
else{
println("Receipt error")
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "subscribed")
}
// Get latest expiry date
if let receiptInfo: NSArray = parseJSON["latest_receipt_info"] as? NSArray {
let lastReceipt = receiptInfo.lastObject as! NSDictionary
// Get last recipt
println("LAST RECIPT INFORMATION \n",lastReceipt)
// Format date
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
// Get Expiry date as NSDate
let subscriptionExpirationDate: NSDate = formatter.dateFromString(lastReceipt["expires_date"] as! String) as NSDate!
println("\n - DATE SUBSCRIPTION EXPIRES = \(subscriptionExpirationDate)")
println(" - CURRENT DATE = \(NSDate())")
//
// --- Subscription Status ----
//
if subscriptionExpirationDate.timeIntervalSinceNow < 0.0 {
// Date has passed
println("\n -> SUBSCRIPTION EXPIRED \n ")
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "subscribed")
}
else{
println("\n -> SUBSCRIBED \n")
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "subscribed")
}
}
}
else {
let jsonStr = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Receipt Error: \(jsonStr)")
}
}
})
task.resume()
}
}
获取收据信息
var receiptUrl = NSBundle.mainBundle().appStoreReceiptURL
打印:
reciptUrl: 'Optional(file:///private/var/mobile/Containers/Data/Application/D0C4DAF0-952F-4C29-9D94-B68DB1FF036F/StoreKit/sandboxReceipt)'
var receipt: NSData = NSData(contentsOfURL:receiptUrl!, options: nil, error: nil)!
产生错误
unexpectedly found nil while unwrapping an Optional value
即使我得到 storekit receipt url
。所以这导致相信这是因为 var receipt
中的力展开。好的,所以当我尝试将行更改为
var receipt: NSData = NSData(contentsOfURL:receiptUrl?, options: nil, error: nil)?
我刚刚被告知 NSData
没有展开 did I mean "!" or "??"
后缀 !
导致 强制展开。
后缀 ?
用于 可选链接 。这意味着,如果 ?
之前的表达式的结果不是 nil
,将计算链中的下一个表达式。可选链的结果始终是 Optional
,因为链上的任何表达式都可能导致 nil
.
因此,在一个表达式上使用后缀 ?
运算符是无用的,因为它 returns 表达式本身。
??
是 nil 合并运算符。这个运算符是语法糖,用三元运算符替换了一个常见的模式:
return myOptional ?? defaultResult
等同于:
return (myOptional != nil) ? myOptional! : defaultResult
与以下相同:
if myOptional != nil {
return myOptional!
} else {
return defaultResult
}
如果您想使用此运算符,则必须提供一个默认值,如果您的 Optional
实际上是 nil
.
使用
检查收据是否存在var fileExists = NSFileManager.defaultManager().fileExistsAtPath(receiptUrl!.path!)
if fileExists {
println("Appstore Receipt already exists")
}
排序