在通用函数中使用枚举

时间:2017-02-02 09:17:29

标签: ios iphone swift generics swift3

我想用enum作为泛型参数创建一个泛型函数。 我有以下通用功能:

func buildProvider<T>(service: T) -> RxMoyaProvider<T> {

    let endpointClosure = { (target: T) -> Endpoint<T> in
        let url = target.baseURL.appendingPathComponent(target.path).absoluteString
        let endpoint = Endpoint<T>(URL: url, sampleResponseClosure: {.networkResponse(200, target.sampleData)}, method: target.method, parameters: target.parameters)
        return endpoint
    }

    return RxMoyaProvider<T>(endpointClosure: endpointClosure)
}

我称之为:

self.userProvider = buildProvider(service: UserService)

下面你看到userProvider的声明:

var userProvider:RxMoyaProvider?

下面你看到UserService的一个例子:

import Foundation
import Moya

enum UserService {
    case login(qrKey: String, language: String, fcmToken: String)
}

extension UserService: TargetType {

    var baseURL: URL {
        let appConfig = AppConfig()
        let hostname = try! appConfig.hostname()

        return URL(string: hostname)!
    }
    var path: String {
        switch self {
        case .login(_,_,_):
            return "/v1/login"
        }
    }
    var method: Moya.Method {
        switch self {
        case .login(_,_,_):
            return .post
        }
    }
    var parameters: [String: Any]? {
        switch self {
        case .login(let qrKey, let language, let fcmToken):
            let params = ["qr-key": qrKey, "language": language, "os": "ios", "fcm-token": fcmToken]
            return params
        }
    }
    var sampleData: Data {
        switch self {
        case .login(_, _, _):
            return "".data(using: .utf8)!
        }
    }
    var task: Task {
        return .request
    }
}

我收到以下错误:

 Cannot convert value of type 'UserService.Type' to expected argument type 'UserService'

有人可以帮我这个吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我没有Moya的经验,也无法确定它是如何工作的以及你想要实现的目标,但似乎你正试图将类型传递给函数。如果是这样,你必须做类似的事情:

func buildProvider<T>(service: T.Type) -> RxMoyaProvider<T> {

    ...

    return RxMoyaProvider<T>(endpointClosure: endpointClosure)
}

并使用.self

进行调用
self.userProvider = buildProvider(service: UserService.self)

但这不是你唯一的问题。如何在没有上下文的情况下知道<T>类型具有baseURL属性:

let endpointClosure = { (target: T) -> Endpoint<T> in
    let url = target.baseURL.appendingPathComponent(target.path).absoluteString

好像你已经搞乱了整体架构,我强烈建议重新考虑它。