Foundation对象转为JSON数据
首先要注意,能转为JSON的Foundation对象必须满足:
- 顶层对象必须是NSArray或NSDictionary。也就是说字符串、NSNumber类型是不能转为JSON的。
- 所有的对象必须是NSString,NSNumber,NSArray,NSDictionary或者NSNull。
- 所有字典的key必须是NSString类型。
- 所有的NSNumber不能为非数字或无穷大。
let aDic = ["key1":100, "key2":"一天"] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: aDic, options: [])
print(jsonData)
}
catch {
print(error)
}
代码说明:
- 对象转JSON的options貌似只有一个prettyPrinted,当然我这里直接空着了。
- aDic如果不是字典或数组,按理说应该抛出异常,为什么我直接奔溃了。
- 生成的JSONdata是utf8的。
我们可以使用下面代码判断一个对象是否能转为JSON:
if JSONSerialization.isValidJSONObject(strangeString) {
print("是是是")
}
JSON对象转Foundation对象
下面就是将一个json data转为Foundation对象的过程:
do {
let dic = try JSONSerialization.jsonObject(with: data, options:.allowFragments)
print(dic)
}
catch {
print(error)
}
options说明:
NSJSONReadingAllowFragments:
表示data的最外层数据非字典或数组的情况下也可以成功。如果是数组或字典也会成功的。如:
let string = "123"
let data = string.data(using:.utf8)!
do {
let dic = try JSONSerialization.jsonObject(with: data, options:.allowFragments)
print(dic)
}
catch {
print("异常了")
}
输出:
123
mutableContainers:
表示将data数据转为可变的数组或字典,如果data数据既不是数组也不是字典,或者说格式错误,那么返回nil并抛出错误。
let string = "123"
let data = string.data(using:.utf8)!
do {
let dic = try JSONSerialization.jsonObject(with: data, options:.mutableContainers)
print(dic)
}
catch {
print("异常了")
}
输出:
异常了
NSJSONReadingMutableLeaves:
:表示如果data是字典或数组的前提下,将data转为可变字符串。
let string = "[123]"
let data = string.data(using:.utf8)!
do {
let dic = try JSONSerialization.jsonObject(with: data, options:.mutableLeaves)
print(dic)
}
catch {
print("异常了")
}
输出:
(123)
一般使用NSJSONReadingAllowFragments
和mutableContainers
就行了。
特殊情况处理:
在和js后台交换数据时,会出现这么种情况:字典的key不是String类型的。要知道js的json允许这么做,但是IOS的JSONSerialization是不允许的。于是会出现这么种数据:
"{Items:2,total:2}"
这个数据我们解析的时候回抛出异常,因为这顶层是{}包围的字典格式,但是内部却不是我们要求的key是字符串。
解决方法:地址
找到一个在Swift里使用的js解释器:WKWebView
。
import WebKit
class JavascriptJSONjavascript: NSObject {
private static let webView = WKWebView()
class func parse(jsonString: String, completionHandler: @escaping (Any?, Error?) -> Void) {
self.webView.evaluateJavaScript(jsonString, completionHandler: completionHandler)
}
}
func doLeftAction() {
let str = "{Items:2,total:2}"
JavascriptJSONjavascript.parse(jsonString: "tmp = \(str)", completionHandler: { (result, error) in
guard error == nil else {
print(error!)
return
}
if let dict = result as? [String: AnyObject] {
print(dict)
}
else {
print("Can't convert to Dictionary")
}
})
}
网友评论