我如何根据 REST-ful API 的变化在 MVC 中为 iOS 应用创建动态模型?
How do I make model in MVC for iOS app dynamic based on changes in REST-ful API?
我们正在构建一个 iOS 应用程序,使用 Realm 作为我们的模型/数据库,但我们想要设计客户端,以便它可以轻松适应 REST-ful API 中可能发生的变化未来。假设我们正在为体育比赛组织开发一个应用程序,以适应不同的事件。根据正在进行的运动项目,每个事件都有不同类型的事件类型。目前 API 只有 returns 足球、棒球和橄榄球,但将来它可能会扩展到包括篮球。后来它可能会淘汰棒球。我设计了 Realm 对象,以便使用如下一对多关系将事件与事件类型分离:
class EventTypeGroup: Object {
dynamic var name = ""
let eventTypes = List<EventType>()
}
class EventType: Object {
dynamic var name = ""
dynamic var descriptionText = ""
}
EventTypeGroup 是 class 描述将在活动中进行的活动类型(在本例中为哪些运动)。我使用这种设计是因为 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:) {
}
}
此外,如果我不知道如何定义它们,我将如何在我现在编写的代码中引用 classes 的不同变体。我猜抽象工厂模式可能不是解决这个问题的最佳方式,但我不确定我应该考虑哪些其他选项或如何解决使类型在基于 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
可以是 "soccer" 或 "baseball" 或 "football"。 (但编译器现在无法帮助您捕获错误。)至于您的持久存储,只需在那里有一个 eventType
类型的字段并存储字符串。
动态类型让我很伤心,因为静态 Swift 非常好,但它可以满足您的需求。只要确保考虑边缘情况即可。为了不以未定义的行为结束,请提前考虑您的应用程序应该做什么,例如,如果您最终在磁盘上使用 REST 不再支持的事件类型 API.
例如,假设您有一个 /eventTypes
端点,以便您应用的用户可以添加事件并相应地对其进行分类,并且它一直在返回 "soccer"、"baseball" 和 "football" 并且您的用户一直在添加这些类型的事件,并且您一直在将它们存储在磁盘上(在 Realm 或 CoreData 或其他地方)。但是有一天后端(或通过后端)有人将 "football" 重命名为 "american football",希望没有人也将 "soccer" 重命名为 "football"。 (所以现在你无法判断一个东西是否被重命名或删除并添加了另一个。)然后你是否将你的 /eventTypes
端点 returns 的事件类型与你在磁盘上找到的东西结合起来?您是否让用户添加仍然存在于磁盘上但不再受您的 REST API 支持或仅显示它们的旧事件类型?
对于活跃用户,如果您的后端人员重命名事件类型或删除事件类型(而不是简单地添加它们),您可能会遇到这些边缘情况。只需与您的利益相关者讨论行为应该是什么。
我们正在构建一个 iOS 应用程序,使用 Realm 作为我们的模型/数据库,但我们想要设计客户端,以便它可以轻松适应 REST-ful API 中可能发生的变化未来。假设我们正在为体育比赛组织开发一个应用程序,以适应不同的事件。根据正在进行的运动项目,每个事件都有不同类型的事件类型。目前 API 只有 returns 足球、棒球和橄榄球,但将来它可能会扩展到包括篮球。后来它可能会淘汰棒球。我设计了 Realm 对象,以便使用如下一对多关系将事件与事件类型分离:
class EventTypeGroup: Object {
dynamic var name = ""
let eventTypes = List<EventType>()
}
class EventType: Object {
dynamic var name = ""
dynamic var descriptionText = ""
}
EventTypeGroup 是 class 描述将在活动中进行的活动类型(在本例中为哪些运动)。我使用这种设计是因为 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:) {
}
}
此外,如果我不知道如何定义它们,我将如何在我现在编写的代码中引用 classes 的不同变体。我猜抽象工厂模式可能不是解决这个问题的最佳方式,但我不确定我应该考虑哪些其他选项或如何解决使类型在基于 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
可以是 "soccer" 或 "baseball" 或 "football"。 (但编译器现在无法帮助您捕获错误。)至于您的持久存储,只需在那里有一个 eventType
类型的字段并存储字符串。
动态类型让我很伤心,因为静态 Swift 非常好,但它可以满足您的需求。只要确保考虑边缘情况即可。为了不以未定义的行为结束,请提前考虑您的应用程序应该做什么,例如,如果您最终在磁盘上使用 REST 不再支持的事件类型 API.
例如,假设您有一个 /eventTypes
端点,以便您应用的用户可以添加事件并相应地对其进行分类,并且它一直在返回 "soccer"、"baseball" 和 "football" 并且您的用户一直在添加这些类型的事件,并且您一直在将它们存储在磁盘上(在 Realm 或 CoreData 或其他地方)。但是有一天后端(或通过后端)有人将 "football" 重命名为 "american football",希望没有人也将 "soccer" 重命名为 "football"。 (所以现在你无法判断一个东西是否被重命名或删除并添加了另一个。)然后你是否将你的 /eventTypes
端点 returns 的事件类型与你在磁盘上找到的东西结合起来?您是否让用户添加仍然存在于磁盘上但不再受您的 REST API 支持或仅显示它们的旧事件类型?
对于活跃用户,如果您的后端人员重命名事件类型或删除事件类型(而不是简单地添加它们),您可能会遇到这些边缘情况。只需与您的利益相关者讨论行为应该是什么。