Search code examples
objective-cswiftobjective-c-blocks

Problems trying to port an Objective C completion block into Swift


I'm using a third party library written in objective C with the following method:

- (void)manageServerResponse:(NSURLResponse*)response NSData:(NSData*)data andNSError:(NSError*)error onComplete:(void (^)(NSInteger kindOfError, NSDictionary*jsonResponse))onComplete;

when I port it to swift I do the following:

typealias ResponseCompletedBlock = (NSInteger, NSDictionary?) -> Void
...
let completedResponseMethod : ResponseCompletedBlock = {(kindOfError: NSInteger, jsonResponse: NSDictionary?) -> Void in
    self.onComplete(kindOfError, jsonResponse: jsonResponse)}

let responseManager: ResponseManager = ResponseManager.sharedResponseManager() as! ResponseManager
responseManager.manageServerResponse(response, 
    NSData: data, 
    andNSError: error, 
    onComplete: completedResponseMethod)

I'm getting this error:

Cannot invoke 'manageServerResponse' with an argument list of type '(NSURLResponse?, NSData: NSData?, andNSError: NSError?, onComplete: ResponseCompletedBlock)'

and if I replace the last sentence for

responseManager.manageServerResponse(response, 
    NSData: data, 
    andNSError: error, 
    onComplete: nil)

everything works, so I assume that the problem is with the block structure, but I've tried to change everything and the error remains.

Can you help?


Solution

  • NSDictionary * is mapped to Swift as [NSObject : AnyObject]!, therefore the type of the response block should be

    typealias ResponseCompletedBlock = (Int, [NSObject : AnyObject]!) -> Void
    

    and consequently

    let completedResponseMethod = {(kindOfError: Int, jsonResponse: [NSObject : AnyObject]!) -> Void in
        // ...
    }
    

    One method to figure out the correct Swift signature of functions is to use the autocompletion in Xcode: You start typing

     responseManager.manageServerResponse(
    

    and Xcode suggests

    enter image description here