Swifts对JSON的解释

时间:2019-02-13 06:32:40

标签: swift

我正在编写一个基本的JSON解析器,面对这个奇怪的问题,即从文件加载的json与经过硬编码的json不同。

这是我正在使用的json文件的内容

{
    "details": {
        "date": "2019-02-08T11:08:38Z",
        "busId": 4,
        "end_date": {
            "date": "2019-02-13T18:30:00Z",
            "flex": 0,
            "timezone": "Asia/Calcutta",
            "hasTime": false,
            "userDate": "2019-02-14T00:00:00Z"
        }
    }
}

,在Swift中加载json的代码是

func jsonFromFile(_ name: String) -> [String : Any] {
    let path = Bundle.main.path(forResource: name, ofType: "json")!
    let data = try! Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
    let jsonObj = try! JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
    return jsonObj
}

这就是我在Swift中创建文字JSON的方式

let data: [String : Any] = [
                "details": [
                    "date": "2019-02-08T11:08:38Z",
                    "busId": 4,
                    "end_date": [
                        "date": "2019-02-13T18:30:00Z",
                        "flex": 0,
                        "timezone": "Asia/Calcutta",
                        "hasTime": false,
                        "userDate": "2019-02-14T00:00:00Z"
                    ]
                ]
        ]

我在解析时遇到一个奇怪的问题。挖掘之后,我发现从文件中的JSON创建的Dictionary的内部表示形式与从字典文字创建的JSON不同。  这是从文件加载时的调试输出 This is how the dictionary looks when loaded from file

,并且是从文字Swift字典创建的

From literal dictionary


尽管它们的类型为[String:Any],但是它们具有不同的内部表示形式(请注意第一张图中的大括号)。 我认为可能的问题之一是JSONSerialization.jsonObject将返回类型为NSDictionary的对象而不是[String : Any]。尽管它们是桥接的,但它们可能具有不同的内部实现。

所以, 无论如何从哪里加载,如何确保在[String : Any]中得到相同的JSON表示形式。


更新: 我尝试在调试器中使用type(of:)。第一种情况的类型是__NSDictionaryI,其他的情况是Swift.Dictionary<Swift.String, Any>,因此很明显内部类型是不同的。我是否会立即寻找将NSDictionary转换为Swift.Dictionary的解决方案?

注意:问这个问题的原因是,尽管它们在大多数情况下的行为相同,但在将变量转换为协议类型时遇到了一些问题。它适用于Swift.Dictionary,但代码适用于NSDictionary(即从JSON文件加载的对象) 这是协议

protocol Countable {
    var count: Int { get }
}

extension Array: Countable where Element: Any {
}

extension Dictionary: Countable where Key == String, Value == Any {
}

因此,对于同一个变量,当我写if var1 is Countable时,第一种情况返回true,第二种情况返回false。尽管如果我为[Any]和[String:Any]编写单独的类型检查,它也可以正常工作

1 个答案:

答案 0 :(得分:1)

不用担心,它们具有相同的内部结构,反之亦然。唯一的区别是它们用于存储的类或结构(调试器向您显示了描述方法的输出。因此,大括号是该描述方法的产物,而不是更多)。 您可以尝试使用isEqual(to :)方法在代码中对它们进行比较,然后您会发现它们相等。它比较了馆藏的内部结构和内容。