在Swift中更轻松地使用JSON和POP编码

让我们从符合Codable的简单类型开始。 在这种情况下,我们将使用微博帖子,因为这是我现在花费太多精力的原因。

  struct Post:可编码{ 
让标题:字符串?
让内容:字符串
}

目前,我们大多数人都在像这样对JSON进行编码和解码。

  let aPost = Post(title:nil, 
内容:“一些非常有趣的评论”)//编码为JSON数据
让coder = JSONEncoder()
让数据=尝试? coder.encode(aPost)//从JSON Datalet解码器解码= JSONDecoder()
让restorePost =尝试吗? coder.decode(Post.self,来自:数据!)

这很好并且相对容易,但是每次仍然是相当数量的样板。 首先,您需要一个编码器/解码器,并且必须处理Codable API方法正在抛出方法的事实。 在此示例中,我try? 可选的返回方法。 如果您需要的不仅仅是返回值的可选值,那就更麻烦了。 然后,您将推出do-catch块以捕获和解析错误,如果您从不受控制的Web API消费JSON数据,则应该完全这样做。

借助一点点的POP,面向AKA协议的编程,魔术可以做得更好。 在可选返回值仍然足够的情况下。 将值类型存储到NSUserDefaults或以其他方式存储到磁盘以进行检索就是这种情况。 我们可以肯定地知道我们要存储和检索的内容,因此我们实际上并不需要错误捕获模式。

我们从我们的类型可以遵循的协议开始。 该协议没有任何要求,因为它将使用扩展程序来为这些便利功能提供默认功能。

 协议JSONCodable {} 

我们只希望此默认功能可用于已经符合Codable类型。 我们可以通过将协议作为Codable的扩展来实现这Codable ,但是我希望这些事情更加明确。 我们不想意外地忘记在其他Codable类型上使用这些方法,我们不确定可选返回是否足以满足要求。 为了实现这两个目标,我们将使用我们自己的显式协议JSONCodable并将其扩展JSONCodable也限制为Codable

这是我们的协议扩展。 它包含一些静态变量和2种方法,使其成为简单的代码行即可获取我们类型的JSON Data版本或从JSON Data中还原其实例。

 扩展名JSONCodable其中Self:Codable { 
//我们方便使用的编码器和解码器。
//这些是类型要使用的静态变量
//本身而不是实例。
静态var编码器:JSONEncoder {return JSONEncoder()}
静态var解码器:JSONDecoder {return JSONDecoder()} //一种将实例作为JSON数据返回的便捷方法。
func jsonData()->数据? {
返回尝试? Self.encoder.encode(自我)
} //一种方便的初始化方法,可从JSON数据创建我们类型的实例。
init?(jsonData:Data?){
守护让数据= jsonData,
让anInstance =尝试? Self.decoder.decode(Self.self,来自:数据)
否则{return nil}
自我=一个实例
}
}

现在,我们可以简单地使上面的样本类型符合我们的新协议。

 扩展帖子:JSONCodable {} 

现在获取我们类型实例的JSON数据并从中恢复它们要容易得多。

  //获取我们类型的实例的JSON数据表示形式。 
let newData = aPost.jsonData()//从JSON数据还原我们类型的实例
让newRecoveredPost = Post(jsonData:newData)

这不能满足我们所有的Codable需求,尤其是当您不确定要还原的数据模型JSON数据时。 在这种情况下,您仍然应该使用do-catch块来处理错误,但是在简单的可选返回就足够的情况下,我们确实简化了事情。

POP现在是一个热门词汇,但它不是魔术。 它并不能解决我们所有的设计和体系结构问题,但是在许多情况下,它可以用于向此类示例中添加类型的共享功能。 如果您想看看或在自己的项目中使用它,可以在Github上找到所有这些代码。

随时在Twitter或Micro.blog上向我发送反馈或想法。


最初于 2018 年4月15日 发布在 vichudson1.micro.blog 上。