iOS体系结构:具有许多可选对象的对象

时间:2018-11-05 10:01:57

标签: ios swift model-view-controller master-detail

这是一个相当具体的情况,所以我将尽力解释尽可能多的细节。

我正在制作一个应获取预订列表的应用程序,可以在其中添加新内容,也可以点按现有的预订,并获得有关该预订的“详细”视图,在该视图中,可编辑预订详细信息,然后保存它的选项。

REST API已使用C#完成,并且没有关于什么可以为null或不能为null的文档(在Swift中为null)。所以我最后得到了:

    struct Reservation: Codable {
var objectID: String?
var objectName: String?
var objectPrefix: String?
var reservationNumber: String?
var grownUPS: Int?
var teens: Int?
var children: Int?
var babies: Int?
var reservationDate: String?
var dateInserted: String?
var toDate:String?
var fromDate: String?
var price: Int?
var owner: String?
var note: String?
var agencyName: String?
var renterNote: String?
var reservationID: String?
    // 20 more properties

init(objectID: String? = nil,
         partnerID: String? = nil,
         objectName: String? = nil,
    // 20 more properties        
    )
    {

    self.objectID = objectID
    self.objectName = objectName
 // 20 more properties

}

因此,当我点击一个对象时,我会传递一个Reservation对象,检查每个字段,如果不是nil,则将其设置为TextField。单击“保存”后,我将更新所有TextField,DatePickers等中的模型,然后根据是新的保留还是编辑现有的内容进行网络发布或放置请求。

如果点击添加,则会传递一个空的Reservation对象,因此“详细信息”页面上的所有字段均为空,并在单击“保存”按钮时进行验证。

到目前为止,它仍然有效,但是周围看起来都是“ Anti-Swift”。大量的可选项目,大量的防护/展开,“主”视图和“详细信息”视图之间的紧密耦合,设置从网络中检索到的数据处于关闭状态(实际上Alamofire调用是隐藏的,但我不确定这将是什么,所以我必须通过nil-check / chaining将每个属性设置为其TextField。

任何关于如何改善这一点的建筑技巧? 所有与此相关的教程都采用了一种简单的,本地的,非可选的方法,使所有内容看起来都很光鲜。

请记住,我没有任何文档可以允许为空(以前通过网络或内部桌面应用程序输入的数据)。

3 个答案:

答案 0 :(得分:1)

我可以想到的一件事是通过定义默认值(例如var babies: Int = 0)来消除某些属性的可选性,或者如果您使用Swift的可解码功能,则可以执行以下操作< / p>

babies = (try? container.decode(Int.self, forKey: .babies)) ?? 0

因此您不必将babies变量设为可选

基于评论的修改:又名合并nil运算符将尝试解开左侧的可选值,如果为nil,它将返回右侧的值,在这种情况下为0

答案 1 :(得分:1)

我认为您不应该为可选组件和可选组件的包装感到困扰。

可选的权力之一是,使用您的代码的任何人都知道,这件事可能以nil作为其价值

解包逻辑,可以使用guardsnil合并,也可以使用任何其他解包技术来描述您的业务逻辑。 IMO是拥有“大”模型的事实,这是应该接受的事实。直到您的代码保持可靠,可读性,可测试性和可理解性,不会造成不必要的副作用等等,这都是可以的。

您可以通过在展开等方面添加另一个抽象级别来“解决”此问题。但是,海事组织,应该非常谨慎地进行此操作,并且仅在实际利益的情况下进行。

答案 2 :(得分:0)

SwiftyJson可以完全解决您面临的问题。它非常有效且以一种快速的方式来处理可选对象的大量对象的可选链接和展开。

如果某种类型转换失败,它不会中断,但是会提供一个空值,这样您的应用程序就可以工作,而无需检查每个变量。

这里是提供的基本转换示例。有关详细信息,请阅读其文档。

// Getting a double from a JSON Array
let name = json[0].double

// Getting an array of string from a JSON Array
let arrayNames =  json["users"].arrayValue.map({$0["name"].stringValue})

// Getting a string from a JSON Dictionary
let name = json["name"].stringValue

// Getting a string using a path to the element
let path: [JSONSubscriptType] = [1,"list",2,"name"]
let name = json[path].string

// Just the same
let name = json[1]["list"][2]["name"].string

// Alternatively
let name = json[1,"list",2,"name"].string