Swift 中的协议和枚举与 Apollo
Protocols and Enums in Swift with Apollo
我在 iOS 应用程序中为 Swift 使用 Apollo。我有多种类型,它们都代表同一个对象。这些类型是从模式文件自动生成的,看起来像这样。
struct CurrentUser {
var id: String
...
}
struct MyUser {
var id: String
...
}
基本上,Apollo 会为相同的基础数据类型生成多个 Swift 类型(每个查询一个)。
我想创建一个统一这些类型的新结构。
我想做这样的事情:
protocol UserProtocol {
var id: String { get }
}
struct User {
var id: String
...
init(_ data: UserProtocol) {
self.id = data.id
...
}
}
然而,当我尝试构造用户对象时,这种方法给我一个错误,告诉我“Type MyUser does not conform to UserProtocol”。如果我尝试使用 data as! UserProtocol
强制类型,我会崩溃。
我找到的唯一解决方案如下:
enum UserType {
case .currentUser(CurrentUser)
case .myUser(MyUser)
}
struct User {
var id: String
...
init(_ data: UserType) {
switch data {
case .myUser(let user):
self.id = data.id
...
case .currentUser(let user):
self.id = data.id
...
}
}
}
这种方法可行,但会导致 init
函数中出现大量重复代码。在 Swift 中有更好的方法吗?
我怀疑问题是您需要明确地使 Apollo 生成的类型符合您的协议:
extension CurrentUser: UserProtocol { }
extension MyUser: UserProtocol { }
请记住 Swift 是 不是 像其他一些语言一样的鸭子类型,因此具有成员 var id: String
的类型不是 UserProtocol
直到你这样声明它。
如果出于某种原因您需要对 Apollo 类型进行一些转换以适应将来的应用程序模型,这些扩展也是执行此操作的好地方。
我在 iOS 应用程序中为 Swift 使用 Apollo。我有多种类型,它们都代表同一个对象。这些类型是从模式文件自动生成的,看起来像这样。
struct CurrentUser {
var id: String
...
}
struct MyUser {
var id: String
...
}
基本上,Apollo 会为相同的基础数据类型生成多个 Swift 类型(每个查询一个)。
我想创建一个统一这些类型的新结构。
我想做这样的事情:
protocol UserProtocol {
var id: String { get }
}
struct User {
var id: String
...
init(_ data: UserProtocol) {
self.id = data.id
...
}
}
然而,当我尝试构造用户对象时,这种方法给我一个错误,告诉我“Type MyUser does not conform to UserProtocol”。如果我尝试使用 data as! UserProtocol
强制类型,我会崩溃。
我找到的唯一解决方案如下:
enum UserType {
case .currentUser(CurrentUser)
case .myUser(MyUser)
}
struct User {
var id: String
...
init(_ data: UserType) {
switch data {
case .myUser(let user):
self.id = data.id
...
case .currentUser(let user):
self.id = data.id
...
}
}
}
这种方法可行,但会导致 init
函数中出现大量重复代码。在 Swift 中有更好的方法吗?
我怀疑问题是您需要明确地使 Apollo 生成的类型符合您的协议:
extension CurrentUser: UserProtocol { }
extension MyUser: UserProtocol { }
请记住 Swift 是 不是 像其他一些语言一样的鸭子类型,因此具有成员 var id: String
的类型不是 UserProtocol
直到你这样声明它。
如果出于某种原因您需要对 Apollo 类型进行一些转换以适应将来的应用程序模型,这些扩展也是执行此操作的好地方。