swiftclosuresalamofirereactive-cocoa-3

Why are these context variables not visible?


I'am using Swift 1.2 with ReactiveCocoa 3.0, SwiftyJSON 2.2.1 and Alamofire 1.3.1. I am building a reactive network manager.

Why is the following not working?

func sendRequest(request: ApiRequest) -> SignalProducer<JSON, NSError> {

    return SignalProducer { sink, disposable in
        alamofireManager.request(request.method, request.url, parameters:request.parameters, encoding: .JSON).responseJSON
            { (request, response, data, error) in
                if let error = error {
                    // sendError(sink, error)
                } else {
                    NSLog("Successful network request")
                    // sendNext(observer, JSON(data!))
                    // sendCompleted(sink)
                }
        }
    }
}

sendError, sendNext and sendCompleted are not compiling. When they are uncommented the compiler says:

Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

When debugging I see that sink and disposable are not visible inside the Alamofire closure. Strangest thing: This used to work some hours ago.


Solution

  • Wow, after hours of searching I found the solution.

    It seems the outer closure does not persist variables (here: sink and disposable) if not assigned to a variable explicitly. I did this with

    let sink = sink
    

    The following works:

    func sendRequest(request: ApiRequest) -> SignalProducer<JSON, NSError> {
        return SignalProducer { sink, disposable in
            let sink = sink
    
            self.alamofireManager.request(request.method, request.url, parameters:request.parameters, encoding: .JSON).responseJSON
                { (request, response, data, error) in
                    if let error = error {
                        sendError(sink, error)
                    } else {
                        sendNext(sink, JSON(data!))
                        sendCompleted(sink)
                    }
            }
        }
    }
    

    Maybe anyone can explain this a bit more general? I thought the outer closure with its parameters will be available inside the inner closure automatically. Might this be a bug in the swift compiler?