Swift 中的协议和枚举与 Apollo



我在iOS应用程序中使用Apollo for Swift。我有多个类型,它们都表示同一个对象。这些类型是从架构文件自动生成的,如下所示。

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
...
}
}

然而,当我尝试构造一个用户对象时,这种方法给了我一个错误,告诉我"类型MyUser不符合用户协议"。如果我试图用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不像其他语言那样是鸭子类型的,因此在你声明之前,不会UserProtocol具有成员var id: String的类型。

如果出于某种原因,您需要对 Apollo 类型进行一些转换以适应将来的应用程序模型,那么这些扩展也是一个好地方。

最新更新