Swift json解析致命错误:在展开Optional值时意外发现nil

时间:2016-02-18 16:59:08

标签: ios json swift

Hello当我解析json数据时,我的代码在这里给出了致命的错误

let queue = NSOperationQueue();
NSURLConnection.sendAsynchronousRequest(storeRequest, queue: queue, completionHandler: { (response : NSURLResponse?, data : NSData?, error : NSError?) -> Void in

    if(error != nil){
        //Handle Error
    }
    else{


        var jsonResponse: NSMutableDictionary?
        do{
            jsonResponse = try NSJSONSerialization.JSONObjectWithData(data!,
                                                                      options: NSJSONReadingOptions.AllowFragments) as? NSMutableDictionary;


            print(jsonResponse)

            let info : NSArray =  jsonResponse!.valueForKey("latest_receipt_info") as! NSArray
            let transaction_id: String? = info[0].valueForKey("transaction_id") as? String
            let web_order_line_item_id: String? = info[0].valueForKey("web_order_line_item_id") as? String

    // ...

错误输出

 fatal error: unexpectedly found nil while unwrapping an Optional value                        

致命错误时标记此行

let info : NSArray =  jsonResponse!.valueForKey("latest_receipt_info") as! NSArray

我尝试但我不解决它

也是我的json值

{
    environment = Sandbox;
    receipt =     {
        "adam_id" = 0;
        "app_item_id" = 0;
        "application_version" = "3.8";
        "bundle_id" = "com.bla.bla";
        "download_id" = 0;
        "in_app" =         (
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2016-02-18 15:56:23 Etc/GMT";
                "original_purchase_date_ms" = 1455810983000;
                "original_purchase_date_pst" = "2016-02-18 07:56:23 America/Los_Angeles";
                "original_transaction_id" = 1000000194749934;
                "product_id" = "com.bla.ShowMaps";
                "purchase_date" = "2016-02-18 15:56:23 Etc/GMT";
                "purchase_date_ms" = 1455810983000;
                "purchase_date_pst" = "2016-02-18 07:56:23 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000194749934;
            },
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2016-02-18 15:58:37 Etc/GMT";
                "original_purchase_date_ms" = 1455811117000;
                "original_purchase_date_pst" = "2016-02-18 07:58:37 America/Los_Angeles";
                "original_transaction_id" = 1000000194750377;
                "product_id" = "com.bla.ApiSupport";
                "purchase_date" = "2016-02-18 15:58:37 Etc/GMT";
                "purchase_date_ms" = 1455811117000;
                "purchase_date_pst" = "2016-02-18 07:58:37 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000194750377;
            },
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2016-02-18 17:13:03 Etc/GMT";
                "original_purchase_date_ms" = 1455815583000;
                "original_purchase_date_pst" = "2016-02-18 09:13:03 America/Los_Angeles";
                "original_transaction_id" = 1000000194763153;
                "product_id" = "com.bla.Limit";
                "purchase_date" = "2016-02-18 17:13:03 Etc/GMT";
                "purchase_date_ms" = 1455815583000;
                "purchase_date_pst" = "2016-02-18 09:13:03 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000194763153;
            },
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2016-02-18 15:57:43 Etc/GMT";
                "original_purchase_date_ms" = 1455811063000;
                "original_purchase_date_pst" = "2016-02-18 07:57:43 America/Los_Angeles";
                "original_transaction_id" = 1000000194750331;
                "product_id" = "com.bla.BarcodeSupport";
                "purchase_date" = "2016-02-18 15:57:43 Etc/GMT";
                "purchase_date_ms" = 1455811063000;
                "purchase_date_pst" = "2016-02-18 07:57:43 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000194750331;
            }
        );
        "original_application_version" = "1.0";
        "original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
        "original_purchase_date_ms" = 1375340400000;
        "original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
        "receipt_creation_date" = "2016-02-18 17:13:03 Etc/GMT";
        "receipt_creation_date_ms" = 1455815583000;
        "receipt_creation_date_pst" = "2016-02-18 09:13:03 America/Los_Angeles";
        "receipt_type" = ProductionSandbox;
        "request_date" = "2016-02-18 17:13:05 Etc/GMT";
        "request_date_ms" = 1455815585353;
        "request_date_pst" = "2016-02-18 09:13:05 America/Los_Angeles";
        "version_external_identifier" = 0;
    };
    status = 0;
}

我怎样才能进入json响应示例,让product_id = mysender值?所以;

像这样?

info = jsonResponse["receipt"]!["in_app"] 

由于

2 个答案:

答案 0 :(得分:2)

除了未指定的JSON结构,假设它并不总是正确返回,您需要通过不隐式展开JSON对象来解释它。您还应该使用纯Swift数组而不是NSArray s,它们在需要时桥接到Objective-C。

在可能的情况下使用下标也是一种很好的风格。

if let jsonResponse = jsonResponse,
  info = jsonResponse["latest_receipt_info"] {
  // Makes sense to check if count > 0 if you're not sure, but...
  let transaction_id = info[0]["transaction_id"] as? String
  let web_order_line_item_id = info[0]["web_order_line_item_id"] as? String
  // Do whatever else you need here
}

如果我正确理解了第二个问题,你可以通过解析数组并迭代对象来获得product_id s来获得该值,如下所示:

if let receipt = jsonResponse["receipt"],
  info = receipt["in_app"] as? [Dictionary<String, AnyObject>] {
  for object in info {
    print(object["product_id"])
  }
}

...或沿着这些行的东西,因为info是一个对象数组。你可能需要按摩它才能达到你的目的。

答案 1 :(得分:0)

看起来你的jsonResponse(或者#34; latest_receipt_info&#34;键)是零。在这种情况下,您无法使用&#39;!&#39;因为这意味着你确定任何一个都不会是零。相反,在进行任何操作之前,首先检查它们是否存在。