我们正在使用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/