我的应用程序从我们的服务器接收二进制数据。在我的旧的Objective-C代码中,我按如下方式处理响应数据:
1.使用NSJSON序列化将NSData转换为NSDictionary,包含如下数据:{“code”:“0”,“Info”:{“user_id”:123456}},
1.编写MTLModel子类
1.使用Mantle接口将上面的INFO字典{“user_id”:123456}转换成我的模型
现在我想用SWIFT来做这件事,我刚刚了解到可编码协议是多么的方便。但是,看起来实现了这个协议,我只能用Data/NSData进行转换,这使得上面的程序变成了这样:
1.同上
1.编写符合可编码协议的结构/类
1.使用NSJSON序列化将INFO字典{“user_id”:123456}重新编码为data/NSData
1.使用JSONDecoder将这些数据解码到我的模型中
所以我的问题是,一个可编码的对象可以直接从词典中派生出来吗?
编辑:
谢谢你们的回答,但让我稍微澄清一下。虽然响应JSON格式有些固定,但是有很多不同的请求和响应,所以INFO部分是不同的。例如:
- r1:{“CODE”:“0”,“INFO”:{“USER_ID”:123456}}是用户id请求的响应
- r2:{“code”:“0”,“Info”:{“Temperature”:20,“Country”:“London”}}是天气温度请求的响应
因此,可编码的类/结构应该只从信息部分构造,而不是从整个响应数据构造,这就是为什么我不能简单地应用步骤2和4来完成这一点。
4条答案
按热度按时间kxxlusnw1#
看起来您的JSON如下所示:
和如下所示的“信息”类型:
我假设有一个解码器来执行SnakeCase转换(您可以通过实现CodingKeys或其他任何方式来替换它):
鉴于此,您需要一个泛型响应类型:
这样,您就可以直接从JSON对象解码响应:
k5hmc34c2#
使用JSON解码器将JSON字符串转换为数据,然后转换为可编码的结构
knpiaxh13#
不,不是直接的,是的,有点。困惑?我会解释的。
Codable
用于对Data
进行编码/解码,其中JSON是目前最流行的编码方式,但您也可以使用PLIST或编写您自己的编解码器。但是坚持使用标准编码器,如果您希望从
Dictionary
转换为符合Decodable
的类型(包括符合Codable
的任何内容),您可以通过将Dictionary
编码为JSON(或plist),然后将生成的Data
解码为Decodable
来实现。这基本上就是你所描述的过程。注意,如果Dictionary
的键和值类型都是Codable
(例如[String: Int]
),则可以使用JSONEncoder/Decoder而不是JSONSerialization
。但是,如果它是例如[String: Any]
,则需要使用JSONSerialization
,因为Any
不符合Codable
。这样说来,您可以扩展
Decodable
以包括一个接受Dictionary
的失败或抛出的初始值设定项,在该初始值设定项中,您将字典编码为Data
,然后使用JSONDecoder
进行解码。它仍然是您已经在执行的过程,只是Decodable
的任何内容都将自动使其可用,以便于使用。但听起来你实际上并不需要任何可编码的东西才能从
Dictionary
初始化,只需要你的型号。在这种情况下,与其扩展Decodable
,不如扩展您的模型。如果词典中有
Any
或其他非Codable
值,则可以对JSONSerialization
执行类似的操作:要使用它:
gzszwxb44#
因此,正如上面所讨论的,只要您的结构匹配,您就可以在一个步骤中完成此操作。
例如:
或者:
然后简单地