我们正在使用Realm作为模型/数据库来构建iOS应用,但我们希望设计客户端,以便它可以轻松适应将来可能发生的REST-ful API中的更改。可以说,我们正在为体育比赛组织开发一款可容纳不同事件的应用程序。每个事件都有不同类型的事件类型,具体取决于所进行的体育运动。目前,API仅返回足球,棒球和足球,但将来可能会扩展到包括篮球。以后可能会消除棒球。我已经设计了Realm对象,以便使用如下所示的一对多关系将事件与事件类型分离:

class EventTypeGroup: Object {
    dynamic var name = ""
    let eventTypes = List<EventType>()
}

class EventType: Object {
    dynamic var name = ""
    dynamic var descriptionText = ""
}

EventTypeGroup是描述事件类型(在这种情况下,是哪种运动)的类。我之所以使用这种设计,是因为Realm不支持字典,在Realm中我们可以存储带有相关属性集的事件类型。

为了使模型适应API将来的更改,以防添加或删除特定组织的运动,我使用了如下的抽象工厂模式。这样,如果不使用符合现代Swift设计原则的枚举就无法创建事件。我遇到的问题是,假设我们仅在用户打开应用程序后才检查事件类型(体育)的API是否发生了更改,如何在已打开应用程序的情况下更改模型?如果这些字段发生更改,是否需要迁移数据库?
protocol EventTypeGroupFactory {

    func createEventTypeGroup(List<EventType>) -> EventTypeGroup

}

protocol EventTypeFactory {

    func createEventTypes() -> List<EventType>

}

class SportEventGroupFactory: EventTypeGroupFactory {
    func createEventTypeGroup(withEventTypes: List<EventType>) ->
    EventTypeGroup {
        //implement logic to create an EventTypeGroup for the SportEventGroup

    }
}

class SportEventTypeFactory: EventTypeFactory {
    EventTypeGroup {
    func createEventType() -> EventType  {
        //implement logic to create an EventType for the SportEventType
    }
}


class EventTypeGroup: Object {

    let eventTypes = List<Int>
    enum EventType  {
    }
}

class EventType: Object {

    var type: Int?
    name: String?
    description: String?
}

class Event: Object {

    static enum EventType
    init(eventTypeWithRawValue:) {

    }
}

另外,如果我不知道如何定义它们,我将如何在我现在编写的代码中引用这些类的不同变体。我猜想抽象工厂模式可能不是解决此问题的最佳方法,但是不确定我应该考虑哪些其他选项,或者不确定如何解决基于API更改的模型中类型易于扩展的问题。

最佳答案

我认为您太复杂了。只需在事件模型中添加一个名为“eventType”的字符串属性即可。

例如,通常,如果不需要保持动态变化,则可以执行以下操作:

enum EventType {
    case soccer
    case baseball
    case football
}

// Your Event model
struct Event {
    var date: Date
    var eventType: EventType // a static type :)
}

但就您而言,您可以执行以下操作:
// Your Event model without any enums
struct Event {
    var date: Date
    var eventType: String // a dynamic type :(
}

然后,属性eventType可以是“足球”或“棒球”或“足球”。 (但是编译器现在无法帮助您捕获错误。)至于持久性存储,只需在其中有一个eventType类型的字段并存储字符串即可。

考虑到静态Swift的出色表现,动态类型让我感到难过,但它可以满足您的需求。只要确保考虑到极端情况。为了避免出现不确定的行为,例如,如果您遇到磁盘上的事件类型不再受REST API支持的情况,请考虑一下应用程序应该做什么。

例如,假设您有一个/eventTypes端点,以便您的应用程序的用户可以添加事件并进行相应的分类,并且它一直在返回“足球”,“棒球”和“足球”,并且您的用户一直在添加这些事件类型,已经将它们存储在磁盘上(在Realm或CoreData中或其他任何形式)。但是有一天,后端(或通过后端)上的某人将“足球”重命名为“美国足球”,我们希望没有人也将“足球”重命名为“足球”。 (因此,现在您无法确定某个事物是否已重命名或删除,以及是否添加了另一个事物。)然后,您是否将/eventTypes端点返回的事件类型与磁盘上的内容结合起来?您是否让用户添加仍保留在磁盘上但REST API不再支持的旧事件类型,或者仅显示它们?

对于活跃的用户,如果后端人员重命名事件类型或删除事件类型(而不是简单地添加事件类型),则可能会遇到这种极端情况。只需与您的利益相关者讨论行为应该是什么。

关于ios - 如何基于REST-ful API中的更改使MVC for iOS应用中的模型动态化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45335354/

10-11 22:43
查看更多