【发布时间】:2015-11-10 17:42:51
【问题描述】:
我正在寻找一种干净且正确的方法来快速实例化数据模型。
我一直在寻找一段时间,但我还没有找到明确的答案。我发现了很多用于教学目的的简单示例(例如 Apple 自己提出的here),但不是真实案例。我的意思是:如何从 API 返回的复杂 JSON 实例化数据模型,同时优雅地管理可选项和失败的初始化?
我对纯 swift 风格感兴趣,所以请不要使用 obj-c 解决方案或建议库来轻松处理 JSONS,因为这不是我问题的真正重点。所有东西都有第三方库(我也使用它们),但我在这里寻找的是深入学习 swift 语法并了解其内部模式。
下面我提出了几个我迄今为止采用的解决方案。对您的建议、论点和解释非常感兴趣。
编辑: 我特别关心的一些方面:
1) 假设模型的属性可以设置为nil,那么哪个是最好的属性声明?作为可选?作为未包装的可选?
2) 哪种分配模式效果最好? if let 绑定还是guard 绑定?
3) 如何正确处理作为我的实际模型属性的模型的实例化? (在下面的片段中考虑var myObjects)
对于上面的每个问题,我已经找到了答案,但我对其他观点感兴趣,因为我认为 Swift 是一种非常丰富且具有延展性的语言,而 Apple 官方文档有时对最佳实践缺乏明确性。
//Proposition 2: property as Optionals and use of guard let
struct MyModel {
let a: String?
let b: MyOtherModel? // MyOtherModel is another struct similar to this one
var myObjects = [Object]() // Object is another struct similar to this one
init?(data: AnyObject) {
guard let data = data as? JSON,
let a = json["a"] as? String,
let otherData = json["b"] as AnyObject,
let myObjectsArray = json["objects"] as? [AnyObject] else {
return nil
}
self.a = a
self.b = MyOtherModel(otherData)
for data in myObjectsArray {
if let newObject = Object(data) {
self.myObjects.append(newObject)
}
}
}
}
//Proposition 2: properties as unwrapped Optionals and if let bindings
struct MyModel {
let a: String!
let b: MyOtherModel! // MyOtherModel is another struct similar to this one
var myObjects = [Object]() // Object is another struct similar to this one
init?(data: AnyObject) {
if let data = data as? JSON,
let a = json["a"] as? String,
let otherData = json["b"] as AnyObject,
let myObjectsArray = json["objects"] as? [AnyObject] {
self.a = a
self.b = MyOtherModel(otherData)
for data in myObjectsArray {
if let newObject = Object(data) {
self.myObjects.append(newObject)
}
}
}
else {
return nil
}
}
}
//Proposition 3: properties already initialized, forcing unwrapping of json sub-objects
struct MyModel {
let a = String()
let b = MyOtherModel() // MyOtherModel is another struct similar to this one
var myObjects = [Object]() // Object is another struct similar to this one
init?(data: AnyObject) {
self.a = data["a"]
self.b = MyOtherModel(data["b"]!!)
if let myObjectsArray = data["b"] as [AnyObject] {
for data in myObjectsArray {
if let newObject = Object(data) {
self.myObjects.append(newObject)
}
}
}
if (self.a.isEmpty) {
return nil
}
}
}
}
【问题讨论】:
-
命题 1 是最好的,因为有保护语句和可失败的初始化程序。那么,您还有什么期待呢?
-
什么是反对使用 Swift JSON 库?它使代码更具可读性和简洁性
-
@Darko 我编辑了。对于 Kametrixom:我不反对 JSON 库(我每天都使用它们)。在这里我强调纯 Swift 风格,因为我想了解 Swift 到底以提高我的技能。
-
我希望这个问题得到更多关注。这是我现在从 Objective-C 迁移到 Swift 时问自己的确切问题
标签: ios swift struct swift2 models