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