如何解析Json并在Swift / iOS中获取所需的值?

时间:2014-09-09 08:26:47

标签: ios iphone json swift

这是我的Json数据。

 {  
   "products":[  

    {  
         "capacity":4,
         "image":"http:\/\/d1a3f4spazzrp4.cloudfront.net\/car-types\/mono\/mono-uberx.png",
         "display_name":"uberX",
         "product_id":"a1111c8c-c720-46c3-8534-2fcdd730040d",
         "description":"The low-cost Uber"
      },
      {  
         "capacity":6,
         "image":"http:\/\/d1a3f4spazzrp4.cloudfront.net\/car-types\/mono\/mono-uberxl2.png",
         "display_name":"uberXL",
         "product_id":"821415d8-3bd5-4e27-9604-194e4359a449",
         "description":"low-cost rides for large groups"
      },
      {  
         "capacity":4,
         "image":"http:\/\/d1a3f4spazzrp4.cloudfront.net\/car-types\/mono\/mono-black.png",
         "display_name":"UberBLACK",
         "product_id":"d4abaae7-f4d6-4152-91cc-77523e8165a4",
         "description":"The original Uber"
      },
      {  
         "capacity":6,
         "image":"http:\/\/d1a3f4spazzrp4.cloudfront.net\/car-types\/mono\/mono-suv.png",
         "display_name":"UberSUV",
         "product_id":"8920cb5e-51a4-4fa4-acdf-dd86c5e18ae0",
         "description":"Room for everyone"
      },
      {  
         "capacity":4,
         "image":"http:\/\/d1a3f4spazzrp4.cloudfront.net\/car-types\/mono\/mono-taxi.png",
         "display_name":"uberTAXI",
         "product_id":"3ab64887-4842-4c8e-9780-ccecd3a0391d",
         "description":"Taxi without the hassle"
      }
   ]
}

我希望键i.e capacity, image, display_name,product_id, description表示的所有值都保存在下面给出的列表中

    var  array_capacity = Array<Int>();
    var  array_image = Array<String>();
    var  array_display_name = Array<String>();
    var  array_product_id = Array<String>();
    var  array_description = Array<String>(); 

但它崩溃了。我认为这是因为一些铸造问题。

这是我的解析代码。

var responseDict: NSDictionary = NSJSONSerialization.JSONObjectWithData(responseData,options: NSJSONReadingOptions.MutableContainers, error:nil) as NSDictionary

        if(!(responseDict==nil)){

             var products: NSArray = responseDict["products"] as NSArray

                for item in products { // loop through data items
                    let obj = item as NSDictionary
                    for (key, value) in obj {


                       // print(key as String);

                        array_product_id.append(value as String);
                        array_display_name.append(value as String);
                        array_image.append(value as String);
                        array_description.append(value as String);
                        array_capacity.append(value as Int);

                }

            }


        }

日志

    libswiftCore.dylib`swift_dynamicCastObjCClassUnconditional:
0x109c55f30:  pushq  %rbp
0x109c55f31:  movq   %rsp, %rbp
0x109c55f34:  pushq  %rbx
0x109c55f35:  pushq  %rax
0x109c55f36:  movq   %rsi, %rcx
0x109c55f39:  movq   %rdi, %rbx
0x109c55f3c:  xorl   %eax, %eax
0x109c55f3e:  testq  %rbx, %rbx
0x109c55f41:  je     0x109c55f5d               ; swift_dynamicCastObjCClassUnconditional + 45
0x109c55f43:  movq   0x7858e(%rip), %rsi       ; "isKindOfClass:"
0x109c55f4a:  movq   %rbx, %rdi
0x109c55f4d:  movq   %rcx, %rdx
0x109c55f50:  callq  *0x63112(%rip)            ; (void *)0x000000010be04000: objc_msgSend
0x109c55f56:  testb  %al, %al
0x109c55f58:  movq   %rbx, %rax
0x109c55f5b:  je     0x109c55f64               ; swift_dynamicCastObjCClassUnconditional + 52
0x109c55f5d:  addq   $0x8, %rsp
0x109c55f61:  popq   %rbx
0x109c55f62:  popq   %rbp
0x109c55f63:  retq   
0x109c55f64:  leaq   0xecc7(%rip), %rax        ; "Swift dynamic cast failed"
0x109c55f6b:  movq   %rax, 0x7fbe6(%rip)       ; gCRAnnotations + 8
0x109c55f72:  int3   
0x109c55f73:  nopw   %cs:(%rax,%rax)

3 个答案:

答案 0 :(得分:1)

这里的问题是你正在快速迭代NSDictionary。 NSDictionary似乎不符合swift序列,所以你使用键值崩溃对NSDictionary进行迭代。使用NSDictionary的allKeys方法并像定义一样定期提取值,如此,

if  let jsonData = jsonString?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false){

  if let jsonObject = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments, error: nil) as? [String: AnyObject]{

    if let products: AnyObject = jsonObject["products"]{

      for aProduct in products as NSArray{

        for aKey in (aProduct as NSDictionary).allKeys{

          println(aKey)

        }

      }

    }
  }

}

你做错了的一件事是将字典中的值附加到,你使用动态强制转换将其强制转换为字符串或Int。这不是可行的方法,并且会再次崩溃您的代码,您可以选择是否可以使用if将其附加到类型,然后将值附加到数组中。

答案 1 :(得分:1)

可能在这部分中发生了错误:

array_product_id.append(value as String);
array_display_name.append(value as String);
array_image.append(value as String);
array_description.append(value as String);

您可以检查是否可以将值转换为特定对象,如下所示:

if let specificObject = dictionary["key"] as? String
{
    // specificObject has a value of string
} 
else
{
    // dictionary["key"] can't be cast-ed to string
} 

以上示例检查dictionary["key"]的值是否可以转换为String

更新:更改这些行。您正在迭代字典,value的内容可以是字符串并转换为Int或反之亦然导致错误。

for (key, value) in obj {

   array_product_id.append(value as String);
   array_display_name.append(value as String);
   array_image.append(value as String);
   array_description.append(value as String);
   array_capacity.append(value as Int);

}

相反:

 // Remove the for-loop

 array_product_id.append(obj["your_key_here"] as String);
 array_display_name.append(obj["your_key_here"] as String);
 array_image.append(obj["your_key_here"] as String);
 .
 .
 .

答案 2 :(得分:0)

对我来说,投射错误是因为值是整数:

"capacity":4,

将所有值设为字符串:

"capacity":"4",

删除了投射错误:

     for item in products { // loop through data items
                let obj = item as NSDictionary
                for (key, value) in obj {
                println("\"\(key as String)\" : \"\(value as String)\"")
        }

      }

除非您需要在Int中使用该值。 这些对我有用。