接下来,我们就要使用NSJSONSerialization将这些数据解析成JSON了。
let jsonObj:NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.allZeros, error: nil) as? NSDictionary
这里我们JSONObjectWithData方法将传入的NSData数据解析成 JSON 对象,如果我们的JSON根节点是以对象形式存放的,那么我们得到的就是一个NSDictionary。而如果是以数组形式存放的,那么我们得到的就是一个NSArray了。后面还有两个参数options代表 JSON 读取选项,这个我们稍后会讲到,error参数表示 JSON 读取中的错误,如果传入nil表示不接受错误消息。
我们得到了解析出来的 JSON 后,我们就可以像访问普通集合对象那样得到里面的信息了:
if let weathers:NSArray = jsonObj["weather"] as? NSArray { var weatherSummary = "北京天气情况:" for weather in weathers { if let desc:String = weather["description"] as? String { weatherSummary += desc + " " } } print(weatherSummary) }我们这里将天气情况读取出来,并打印到屏幕上,以我们上面的数据为例,打印到屏幕上就是这个样子:
北京天气情况:阵雨 薄雾
NSJSONSerialization 的读取选项就在刚刚,我们使用NSJSONSerialization成功的解析了 JSON 数据,觉得用起来很爽吧。仔细回想一下,我们刚才还注意到有一个options参数我们没有详细介绍。这个我们可以把它叫做读取选项,这个参数的类型是NSJSONReadingOptions,它的取值可以是以下几种:
MutableContainers: 让返回的 JSON 数据中的数组和字典是可更改的。 AllowFragments: 允许 JSON 返回的数据有多个根节点。 MutableLeaves: 使 JSON 返回的字符串是可更改的。相信部分胆大心细的朋友会发现。。。
我靠,这说的都是什么那,我还是不明白!
所以。。客官莫急,听我一一道来。
MutableContainers首先,MutableContainers这个选项就让返回的 JSON 集合可更改,让我们来看一个例子就一目了然了:
var jsonString:NSString = "{\"names\":[\"James\",\"Jobs\",\"Tom\"]}" as NSString let jsonData = jsonString.dataUsingEncoding(NSUTF8StringEncoding) if let jsonObj:NSDictionary = NSJSONSerialization.JSONObjectWithData(jsonData!, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSDictionary { //操作之前 print(jsonObj) //James, Jobs, Tom if let nameArray:NSMutableArray = jsonObj["names"] as? NSMutableArray { nameArray.addObject("Cook") } //操作之后 print(jsonObj) //James, Jobs, Tom, Cook }我们看一下吧,上面的代码,我们在JSONObjectWithData方法调用的时候,加入了NSJSONReadingOptions.MutableContainers读取参数, 这样一来我们就可以更改我们的结果集了,我们注意到上面的这段代码:
if let nameArray:NSMutableArray = jsonObj["names"] as? NSMutableArray { nameArray.addObject("Cook") }取得names数组,并在里面增加一个新的项。随后我们再次打印jsonObj对象,这次显示的结果就是我们更改过的了。
如果我们在调用JSONObjectWithData方法的时候将NSJSONReadingOptions.MutableContainers选项去掉的话,我们就不能更改这里面任何数组的元素了。
第一个选项MutableContainers我们看完啦。 我们继续
AllowFragments还有另外一个选项参数,就是AllowFragments这个参数的官方解释是允许被解析的 JSON 数据的根层级,不是数组和对象。
额。。 听起来怪怪的不好理解是吧。
这个选项确实容易引起歧义,包括他的名称AllowFragments,翻译成中文叫允许碎片, 什么叫允许碎片呢,我再自己实践研究过这个之前我一直是这么认为的。。。
AllowFragments的意思,是不是可以解析这样的 JSON?
{"name":"Jobs"},{"name":"Ive"}一段时间以来我的思维里是这么想的。可惜完全不是那么回事儿,如果你将这样的 JSON 数据传给JSONObjectWithData方法,你将得到一个无情的解析错误。。。
那么,这东西到底是干什么用的呀~
其实官方文档上面说的清清楚楚,可以让跟节点不是对象或者数组。在 JSON 中只有三种类型,对象,数组,值。
其实说白了就是这样,允许你的 JSON 数据是一个字面值,比如字符串,数字,等等。
比如我们可以传入一个原始的字符串
"something wrong about api"