我正在编写一个基本的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不同。 这是从文件加载时的调试输出
,并且是从文字Swift字典创建的
尽管它们的类型为[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]编写单独的类型检查,它也可以正常工作
答案 0 :(得分:1)
不用担心,它们具有相同的内部结构,反之亦然。唯一的区别是它们用于存储的类或结构(调试器向您显示了描述方法的输出。因此,大括号是该描述方法的产物,而不是更多)。 您可以尝试使用isEqual(to :)方法在代码中对它们进行比较,然后您会发现它们相等。它比较了馆藏的内部结构和内容。