使用Swift Codable协议提取JSON片段

可编码协议确实有助于简化开发人员的生活。 它使我们能够将JSON响应转换为模型对象,而无需经历解析每个对象的繁琐过程。

我们如何在Swift中使用Codable协议?

为了更好地理解这个概念,让我们开始尝试一些编码示例:

Flickr 搜索JSON示例:

  { 
“ title”:“最近上传带标签的searchtag”,
“链接”:“ https:\ / \ /
www.flickr.com \ / photos \ / tags \ / searchtag \ /“,
“描述”:“”,
“已修改”:“ 2014–05–06T05:45:56Z”,
“生成器”:“ https:\ / \ /
www.flickr.com”,
“项目”:[{
“ title”:“ Bird \ / Pleasanton-CA”,
“链接”:“ https:\ / \ /
www.flickr.com \ / photos \ / geziyozbiz \ / 14140039213 \ /“,
“媒体”:{
“ m”:“ https:\ / \ / farm8.staticflickr.com \ / 7440 \ /14140039213_fe9c6fd0aa_m.jpg”
},
“ date_taken”:“ 2014–05–04T11:48:29–08:00”,
“说明”:“

<a href = \” https:\ / \ /
www.flickr.com \ / people \ / geziyozbiz \ / \“> geziyozbiz 发布了一张照片:

\” ”,
“已发布”:“ 2014–05–06T05:45:56Z”,
“作者”:“
nobody@flickr.com(\“ geziyozbiz \”)“,
“ author_id”:“ 122145083 @ N05”,
“ tags”:“索尼观鸟赏鸟lazyon searchtag a6000 55210mm e55210mmf4563oss”
}]
}

让我们继续为上述json实现可编码协议。 Flickr feed响应具有一个词典,该词典包含标题,链接,描述,修改的内容,生成器和项目列表。

  struct FlickrSearch:可编码{ 标题:字符串?  链接:字符串?  描述:字符串?  让我们修改:字符串?  let generator:字符串?  物品:[物品]?  枚举 CodingKeys:字符串,CodingKey { 案例标题=“标题” 案例链接=“链接” 案例描述=“描述” 案例修改=“已修改” 案例生成器=“发电机” 案例项目=“物品”} init (来自解码器:解码器) 抛出 { 值= 尝试解码器.container(keyedBy:CodingKeys。self)标题= 尝试值.decodeIfPresent(String。self,forKey:.title)链接= 尝试值 .decodeIfPresent(String。self,forKey:.link)描述= try values.decodeIfPresent(String。self,forKey:.description)modified = 尝试 values.decodeIfPresent(String。self,forKey:.modified)generator = try values.decodeIfPresent(String。self,forKey:.generator)items = try values.decodeIfPresent([Items]。self,forKey:.items)}} 

同样,一个项目是一个字典,它具有一些属性和媒体字典,如下所示:

  struct项目:可编码{ 标题:字符串?  链接:字符串?  媒体:媒体?   date_taken:字符串?  描述:字符串?  发布:字符串?  作者:字符串?   author_id:字符串?  let标签:字符串?  枚举 CodingKeys:字符串,CodingKey { 案例标题=“标题” 案例链接=“链接” 案例媒体=“媒体” 案例 date_taken =“ date_taken” 案例描述=“描述” 案例发布=“已发布” 案例作者=“作者” 案例 author_id =“ author_id” 案例标签=“ tags”} 初始化 (来自解码器:解码器) 引发 { let values = try variables.container(keyedBy:CodingKeys。self)title = try values.decodeIfPresent(String。self,forKey:.title )link = 尝试值 .decodeIfPresent(String。self,forKey:.link)media = 尝试值 .decodeIfPresent(Media。self,forKey:.media)date_taken = 尝试值 .decodeIfPresent(String。self,forKey:.date_taken)描述= 尝试值 .decodeIfPresent(String。self,forKey:.description)已发布= 尝试值 .decodeIfPresent(String。self,forKey:.published)author = 尝试值 .decodeIfPresent(String。self,forKey:.author)author_id = 尝试 values.decodeIfPresent(String。self,forKey:.author_id)tags = 试试 values.decodeIfPresent(String。self,forKey:.tags)}} 

媒体字典到Swift媒体可编码模型对象的转换

 struct Media:可编码{  m:字符串?  枚举 CodingKeys:字符串,CodingKey { case m =“ m”} 初始化 (来自解码器:Decoder) 抛出 { let值= 尝试解码器.container(keyedBy:CodingKeys。self)m = 尝试 values.decodeIfPresent(String。self,forKey: .m)}} 

基础对象FlickrSearch是JSON的完整表示,我们将使用基础对象将JSON映射到Swift模型:

 让url = URL(字符串:“ https://api.flickr.com/services/feeds/photos_public.gne?tags=%22%20+%20searchTag%20+%20%22&format=json&nojsoncallback=1”) 
let task = URLSession.shared.dataTask(with:url!){(数据,响应,错误)在
让jsonDecoder = JSONDecoder()

让responseModel =试试jsonDecoder.decode(FlickrSearch.self,来自:数据!) }
task.resume()

按照上面的示例,我们可以编写从JSON到Swift模型的对象映射,并轻松地将完整的JSON解码为模型对象,但是,如果我们不需要仅完整对象的一部分,该怎么办。 假设我们只需要JSON响应中的items数组。 知道如何实现吗?

我们如何使用Codable协议提取JSON的一部分?

您可能会想,如果我们只需要JSON的一部分,为什么不能按照要求将JSON分解成几个部分。 是的,如果我们将JSON响应分成小部分,那就太好了。 它将使用低数据带宽。

仅当您使用内部实现的API时,以上解决方案才有可能。 但是,如果您正在使用第三方API,该怎么办。

我们是否需要使用Codable协议编写完整的JSON结构?

不,我们可以在没有完整的JSON对象映射的情况下实现此目标。 编写Items和Media的映射对象并转换Item的映射列表,如下所示:

 让url = URL(字符串:“ https://api.flickr.com/services/feeds/photos_public.gne?tags=%22%20+%20searchTag%20+%20%22&format=json&nojsoncallback=1”) 
let task = URLSession.shared.dataTask(with:url!){(数据,响应,错误)在
让jsonDecoder = JSONDecoder()

让dictionaryFromJSON =试试JSONSerialization.jsonObject(with:data !, options:.allowFragments)as! [String:Any]
让jsonItem = dictionaryFromJSON [“ items”]为? NSArray
让jsonData =尝试JSONSerialization.data(withJSONObject:jsonItem !,选项:[])
让responseModel =试试jsonDecoder.decode([Items] .self,来自:jsonData!)
}
task.resume()

正如我们在上面的代码中看到的,首先,我们需要将数据转换为JSON字典并将项目列表提取为NSArray。 将项目列表转换成数据,然后再次将数据解码到项目列表中。

希望你喜欢阅读!!! 学得很好…

如果您从本文中学到一点,对我来说将是一件很棒的事。 请拍拍手以表示支持!! 这将激励我写更多……。

有什么建议吗? 在下面的评论中提及。 我很乐意为他们工作。