общий enum с переключателем swift - PullRequest
0 голосов
/ 20 сентября 2018

У меня есть следующее перечисление

enum MoneyCupUsersBackEndRouter: URLRequestConvertible {

    case getInfo
    case postUserConnection(ConnectionData)
    case postPersonalInfo(UserUpdatePersonalInformationsRequest)
    case postKycAnswers(QuestionnaireAnswers)

    switch self {
        case .postUserConnection(let parameters):
            let r = parameters.encode()
            print(r)

        case .postPersonalInfo(let parameters):
            let r = parameters.encode()
            print(r)

        case .postKycAnswers(let parameters):
            let r = parameters.encode()
            print(r)

        default:
            break
        }

Этот код довольно уродливый, мне приходилось дублировать регистры в коммутаторе, поскольку каждый раз параметры различного типа.Но все параметры следуют протоколу Codable.

Должен быть способ избежать этого, используя некие универсальные типы.

Все функции кодирования объявлены так, как показано ниже:

func encode() -> [String: Any] {
   return ["id": id, "data": data]
}

Возвращенный словарь содержит структурированные поля.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Если все связанные типы соответствуют общему протоколу Foo (в качестве требования используется метод encode()), вы можете использовать шаблон as Foo для связанных значений, чтобы объединить все случаи в один.

Вот отдельный пример (протестирован с Xcode 10 / Swift 4.2):

protocol Foo {
    func encode() -> [String: Any]
}

class A: Foo {
    func encode() -> [String: Any] { return ["A": 1] }
}

class B: Foo {
    func encode() -> [String: Any] { return ["B": 2] }
}

class C: Foo {
    func encode() -> [String: Any] { return ["C": 3] }
}

enum MyEnum {

    case a(A)
    case b(B)
    case c(C)

    func test() {
        switch self {
        case .a(let parameters as Foo),
            .b(let parameters as Foo),
            .c(let parameters as Foo):

            let r = parameters.encode()
            print(r)

        }
    }
}

MyEnum.a(A()).test() // ["A": 1]
MyEnum.b(B()).test() // ["B": 2]
MyEnum.c(C()).test() // ["C": 3]
0 голосов
/ 20 сентября 2018

Если все, что вам нужно, это кодируемый параметр, вы можете попробовать это -

case getInfo
case postUserConnection(Codable)
case postPersonalInfo(Codable)
case postKycAnswers(Codable)

Затем -

func stuff() {
    switch self {
    case .postUserConnection(let parameters), .postPersonalInfo(let parameters), .postKycAnswers(let parameters):
        let r = try? parameters.encode()
        print(r as Any)
    default:
        break
    }
}

Но, конечно, вам могут понадобиться различные типы, которые у вас есть в настоящее время, каксвязанные значения, тогда это было бы невозможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...