aehlke
aehlke

Reputation: 15840

What does this Swift type error mean? It reads like what's expected is already the case

I'm stuck on a compilation error that I'm having trouble interpreting. The expected argument type appears identical to what I've passed to it, so I'm not sure what to make of it. Probably best to just paste the error and relevant bits of code.

Here's where it fails:

static func DefaultProvider() -> ReactiveManabiAPIProvider<ManabiAPI> {
    return ReactiveManabiAPIProvider(endpointClosure: endpointsClosure,
        requestClosure: endpointResolver(),
        stubClosure: StubBehaviour,
        plugins: APIProvider.plugins)
}

And the error message:

error: cannot convert value of type '(ManabiAPI) -> Endpoint' to expected argument type '_ -> Endpoint<_>' return ReactiveManabiAPIProvider(endpointClosure: endpointsClosure, ^~~~~~~~~~~~~~~~

And some of the other relevant code referenced above:

enum ManabiAPI {
[...]
}

extension ManabiAPI : TargetType {
    var baseURL: NSURL { return NSURL(string: "[...]")! }    
    var path: String {
    [...]
    }
    var parameters: [String: AnyObject]? {
    [...]
    }
    var method: ReactiveMoya.Method {
    [...]
    }
    [...]
}

public class ReactiveManabiAPIProvider<Target where Target: TargetType> : ReactiveCocoaMoyaProvider<Target> {
    var appController: AppController
    var requestErrors: RACSubject

    override init(endpointClosure: MoyaProvider<Target>.EndpointClosure = MoyaProvider.DefaultEndpointMapping,
        requestClosure: MoyaProvider<Target>.RequestClosure = MoyaProvider.DefaultRequestMapping,
        stubClosure: MoyaProvider<Target>.StubClosure = MoyaProvider.NeverStub,
        manager: Manager = Alamofire.Manager.sharedInstance,
        plugins: [PluginType] = [], stubScheduler: DateSchedulerType? = nil) {
            let appDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
            appController = appDelegate.appController!

            requestErrors = RACSubject()

            super.init(endpointClosure: endpointClosure, requestClosure: requestClosure, stubClosure: stubClosure, manager: manager, plugins: plugins)
    }
    [...]
}

Please let me know if it'd be useful to see anything else.

Upvotes: 0

Views: 470

Answers (2)

CrimeZone
CrimeZone

Reputation: 230

That's the code where I have exactly the same problem (i'm using Moya 6.5.0)

public protocol ApiService {
    var apiProvider: ReactiveCocoaMoyaProvider<ApiRouter> { get }
    func request(token: ApiRouter) -> SignalProducer<Response, NSError>
}

public class ApiServiceImpl: ApiService {
    private let application: UIApplication
    public var apiProvider: ReactiveCocoaMoyaProvider<ApiRouter>

    public init(stubbing: Bool, application: UIApplication) {
        self.application = application
        if stubbing == false {
            let endpointsClosure = { (target: ApiRouter) -> Endpoint<ApiRouter> in
                return Endpoint<ApiRouter>(
                    URL: ApiServiceImpl.url(target),
                    sampleResponseClosure: { .NetworkResponse(200, target.sampleData) },
                    method: target.method,
                    parameters: target.parameters
                )
            }
            let networkActivityPlugin = NetworkActivityPlugin { type in
                switch type {
                case .Began : application.networkActivityIndicatorVisible = true
                case .Ended : application.networkActivityIndicatorVisible = false
                }
            }

            let networkLoggerPlugin = NetworkLoggerPlugin(verbose: true, responseDataFormatter: JSONResponseDataFormatter)
            let plugins = [networkActivityPlugin, networkLoggerPlugin]

            apiProvider = ReactiveCocoaMoyaProvider<ApiRouter>(endpointClosure: endpointsClosure, plugins: plugins)
        } else {
            apiProvider = ReactiveCocoaMoyaProvider<ApiRouter>(stubClosure: { _ in .Immediate })
        }
    }

    public func request(token: ApiRouter) -> SignalProducer<Response, NSError> {
        return apiProvider
            .request(token)
            .filterSuccessfulStatusAndRedirectCodes()
    }

    private static func url(route: TargetType) -> String {
        return route.baseURL.URLByAppendingPathComponent(route.path).absoluteString
    }
}

And i fixed that error by just adding [PluginType] to plugins array definition line, so it becomes

let plugins: [PluginType] = [networkActivityPlugin, networkLoggerPlugin]

Upvotes: 0

dfrib
dfrib

Reputation: 73206

I have a difficult time trying this solution in a playground as your example above is still a bit too non-minimal. But I suspect you need to explicitly state the generic Target type (under type constraint TargetType) in the ReactiveManabiAPIProvider initializer in the return clause of your function DefaultProvider(). E.g.:

static func DefaultProvider() -> ReactiveManabiAPIProvider<ManabiAPI> {
    return ReactiveManabiAPIProvider<ManabiAPI>(endpointClosure: endpointsClosure,
        requestClosure: endpointResolver(),
        stubClosure: StubBehaviour,
        plugins: APIProvider.plugins)
}

Otherwise your return initializes a ReactiveManabiAPIProvider without an associated generic, and naturally the following return cast fails as function return expects a ReactiveManabiAPIProvider instance with generic Target type ManabiAPI.

Upvotes: 1

Related Questions