简体   繁体   中英

Protocols and Enums in Swift with Apollo

I am using Apollo for Swift in an iOS app. I have multiple types that all represent the same object. These types are auto-generated from a schema file and look something like this.

struct CurrentUser {
  var id: String
  ...
}

struct MyUser {
  var id: String
  ...
}

Basically Apollo generates multiple Swift types (one for each query) for the same underlying data type.

I want to create a new struct that unifies these types.

I would like to do something like this:

protocol UserProtocol {
  var id: String { get }
}

struct User {
  var id: String
  ...

  init(_ data: UserProtocol) {
    self.id = data.id
    ...
  }
}

This approach however gives me an error when I try to construct a user object, telling me that "Type MyUser does not conform to UserProtocol". If I try to coerce the type with data as! UserProtocol data as! UserProtocol I get a crash.

The only solution I've found is the following:

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

This approach works, but it leads to a lot of duplicated code in the init function. Is there a better way to do this in Swift?

I suspect the problem is that you need to explicitly conform the Apollo generated types to your protocol:

extension CurrentUser: UserProtocol { }
extension MyUser: UserProtocol { }

Remember that Swift is not duck-typed like some other languages, so a type with member var id: String is not UserProtocol until you declare it as such.

If for some reason you need to do some transformation of the Apollo types to fit the app models in the future, those extensions are a good place to do that, too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM