Swift 中的协议和枚举与 Apollo

Posted

技术标签:

【中文标题】Swift 中的协议和枚举与 Apollo【英文标题】:Protocols and Enums in Swift with Apollo 【发布时间】:2021-12-22 16:29:57 【问题描述】:

我在 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
    ...
  

但是,当我尝试构造用户对象时,这种方法给了我一个错误,告诉我“Type MyUser 不符合 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 中有没有更好的方法来做到这一点?

【问题讨论】:

【参考方案1】:

我怀疑问题在于您需要明确地使 Apollo 生成的类型符合您的协议:

extension CurrentUser: UserProtocol  
extension MyUser: UserProtocol  

请记住,Swift 像其他一些语言一样是鸭子类型的,因此具有成员 var id: String 的类型不是 UserProtocol,除非您将其声明为这样。

如果由于某种原因您需要对 Apollo 类型进行一些转换以适应未来的应用模型,那么这些扩展也是一个很好的选择。

【讨论】:

以上是关于Swift 中的协议和枚举与 Apollo的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中正确实现不同视图控制器之间的协议和委托?

说说开发中常用的USART的协议和工作原理

Swift学习笔记-协议和扩展

支持的协议和封装协议

Windows Server Failover Cluster 使用的协议和端口

iOS-swift-协议和拓展