我正在编写一个基本的 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 的解决方案?
注意:问这个问题的原因是,虽然它们在大多数情况下表现相同,但我在将变量转换为协议(protocol)类型时遇到了一些问题。它适用于 Swift.Dictionary,但代码会中断 NSDictionary(即从 JSON 文件加载的对象) 这是协议(protocol)
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] 编写单独的类型检查它工作正常
最佳答案
别担心,它们具有相同的内部结构,您可以反过来使用它们。唯一的区别是它们用于存储的类或结构(调试器向您显示描述方法的输出。因此,大括号是此描述方法的产物,而不是更多。)。 您可以尝试在代码中使用 isEqual(to:) 方法比较它们,您会发现它们是相等的。它比较集合的内部结构和内容。
关于JSON 的 Swifts 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54663965/