使用JSONSerialization进行foundation对象和json的互转

郝原
2023-12-01

Foundation对象转为JSON数据

首先要注意,能转为JSON的Foundation对象必须满足:

  1. 顶层对象必须是NSArray或NSDictionary。也就是说字符串、NSNumber类型是不能转为JSON的。
  2. 所有的对象必须是NSString,NSNumber,NSArray,NSDictionary或者NSNull。
  3. 所有字典的key必须是NSString类型。
  4. 所有的NSNumber不能为非数字或无穷大。
        let aDic = ["key1":100, "key2":"一天"] as [String : Any]
        
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: aDic, options: [])
            print(jsonData)
        }
        catch {
            print(error)
        }

代码说明:

  1. 对象转JSON的options貌似只有一个prettyPrinted,当然我这里直接空着了。
  2. aDic如果不是字典或数组,按理说应该抛出异常,为什么我直接奔溃了。
  3. 生成的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)

一般使用NSJSONReadingAllowFragmentsmutableContainers就行了。

特殊情况处理:

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


作者:桃花流水鳜鱼肥
链接:http://www.jianshu.com/p/f557c1bfdfe8
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 类似资料: