JSONSerialization 序列化错误类型的字典
JSONSerialization serialize dictionary with wrong types
我在将我的模型翻译成字典时遇到了问题。
我的模型继承自 Codable,在使用 JSONSerialization 时,我得到了一个形式为的字典:
(...,"sensors": <__NSArrayI 0x1105324f0>( {
accx = "-0.002471923828125";
accy = "0.011444091796875";
accz = "-1.013595581054688";
gyrox = "-0.029818882093399213";
gyroy = "0.028939506301455049";
gyroz = "0.0044943506556177227"; }, ...)
(请注意,我的键不是字符串,但值是)
实际上想要这个:
(..., "sensors": [ {
"accx" = -0.002471923828125;
"accy" = 0.011444091796875;
"accz" = -1.013595581054688;
"gyrox" = -0.029818882093399213;
"gyroy" = 0.028939506301455049;
"gyroz" = 0.0044943506556177227;} ], ... )
我的模型是:
class Event: NSObject, Codable {
var latitude: Double?
var longitude: Double?
var speed: Double?
var date: String?
var type: String?
var sensors: [Sensor] = []
}
class Sensor: NSObject, Codable {
var accx: Double?
var accy: Double?
var accz: Double?
var gyrox: Double?
var gyroy: Double?
var gyroz: Double?
}
我正在使用它来转换成字典:
extension Encodable {
var dictionary: [String: Any]? {
do{
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
guard let data = try? encoder.encode(self) else { return nil }
let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
print(json)
return json
} catch {
return nil
}
}
}
我被这个问题困住了,我不知道我是否走在正确的道路上。
我应该改变我组织这本词典的方式吗?
你看的是NSDictionary.description
的结果,NSDictionary.description
的结果是不是JSON而且不一定准确包含对象的表示。
解码没有实际问题。示例:
Welcome to Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2). Type :help for assistance.
1> import Foundation
2> let json = "{ \"sensors\": [ { \"accx\": 0.011444091796875 } ] }"
json: String = "{ \"sensors\": [ { \"accx\": 0.011444091796875 } ] }"
3> let d = try! JSONSerialization.jsonObject(with: json.data(using: .utf8)!, options: []) as! [String: Any]
d: [String : Any] = 1 key/value pair {
[0] = {
key = "sensors"
value = {
payload_data_0 = 0x0000000100111ad0
payload_data_1 = 0x0000000000000000
payload_data_2 = 0x0000000000000000
instance_type = 0x00000001014179c8 libswiftCore.dylib`InitialAllocationPool + 4888
}
}
}
当我们打印 JSONSerialization
返回的字典时,我们看到引号中的数字:
4> print(d)
["sensors": <__NSSingleObjectArrayI 0x100111ad0>(
{
accx = "0.011444091796875";
}
)
]
但是当我们真正从嵌套容器中提取数字时,它实际上是一个Double
:
5> ((d["sensors"] as! [Any])[0] as! [String: Any])["accx"] as! Double
$R0: Double = 0.011444091796875
故事的寓意:不要指望对象的 description
是其值的准确序列化。 如果需要准确序列化,请将反对 JSON 或 属性 列表,或在调试器中检查它。
我在将我的模型翻译成字典时遇到了问题。 我的模型继承自 Codable,在使用 JSONSerialization 时,我得到了一个形式为的字典:
(...,"sensors": <__NSArrayI 0x1105324f0>( {
accx = "-0.002471923828125";
accy = "0.011444091796875";
accz = "-1.013595581054688";
gyrox = "-0.029818882093399213";
gyroy = "0.028939506301455049";
gyroz = "0.0044943506556177227"; }, ...)
(请注意,我的键不是字符串,但值是)
实际上想要这个:
(..., "sensors": [ {
"accx" = -0.002471923828125;
"accy" = 0.011444091796875;
"accz" = -1.013595581054688;
"gyrox" = -0.029818882093399213;
"gyroy" = 0.028939506301455049;
"gyroz" = 0.0044943506556177227;} ], ... )
我的模型是:
class Event: NSObject, Codable {
var latitude: Double?
var longitude: Double?
var speed: Double?
var date: String?
var type: String?
var sensors: [Sensor] = []
}
class Sensor: NSObject, Codable {
var accx: Double?
var accy: Double?
var accz: Double?
var gyrox: Double?
var gyroy: Double?
var gyroz: Double?
}
我正在使用它来转换成字典:
extension Encodable {
var dictionary: [String: Any]? {
do{
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
guard let data = try? encoder.encode(self) else { return nil }
let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
print(json)
return json
} catch {
return nil
}
}
}
我被这个问题困住了,我不知道我是否走在正确的道路上。 我应该改变我组织这本词典的方式吗?
你看的是NSDictionary.description
的结果,NSDictionary.description
的结果是不是JSON而且不一定准确包含对象的表示。
解码没有实际问题。示例:
Welcome to Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2). Type :help for assistance.
1> import Foundation
2> let json = "{ \"sensors\": [ { \"accx\": 0.011444091796875 } ] }"
json: String = "{ \"sensors\": [ { \"accx\": 0.011444091796875 } ] }"
3> let d = try! JSONSerialization.jsonObject(with: json.data(using: .utf8)!, options: []) as! [String: Any]
d: [String : Any] = 1 key/value pair {
[0] = {
key = "sensors"
value = {
payload_data_0 = 0x0000000100111ad0
payload_data_1 = 0x0000000000000000
payload_data_2 = 0x0000000000000000
instance_type = 0x00000001014179c8 libswiftCore.dylib`InitialAllocationPool + 4888
}
}
}
当我们打印 JSONSerialization
返回的字典时,我们看到引号中的数字:
4> print(d)
["sensors": <__NSSingleObjectArrayI 0x100111ad0>(
{
accx = "0.011444091796875";
}
)
]
但是当我们真正从嵌套容器中提取数字时,它实际上是一个Double
:
5> ((d["sensors"] as! [Any])[0] as! [String: Any])["accx"] as! Double
$R0: Double = 0.011444091796875
故事的寓意:不要指望对象的 description
是其值的准确序列化。 如果需要准确序列化,请将反对 JSON 或 属性 列表,或在调试器中检查它。