展开可选值错误 - 检查应用内购买的收据响应

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")
}

排序