尝试将Objective C完成块移植到Swift中的问题

时间:2015-05-28 09:11:16

标签: objective-c swift objective-c-blocks

我使用目标C编写的第三方库使用以下方法:

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

当我将其移植到swift时,我会执行以下操作:

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)

我收到此错误:

  

无法调用' manageServerResponse'使用类型的参数列表   '(NSURLResponse?,NSData:NSData?,andNSError:NSError?,onComplete:   ResponseCompletedBlock)'

如果我替换

的最后一句话
responseManager.manageServerResponse(response, 
    NSData: data, 
    andNSError: error, 
    onComplete: nil)

一切正常,所以我认为问题出在块结构上,但我试图改变一切,错误仍然存​​在。

你能帮忙吗?

3 个答案:

答案 0 :(得分:4)

NSDictionary *映射到Swift为[NSObject : AnyObject]!, 因此,响应块的类型应为

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

因此

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

找出函数的正确Swift签名的一种方法是在Xcode中使用自动完成: 你开始输入

 responseManager.manageServerResponse(

和Xcode建议

enter image description here

答案 1 :(得分:1)

Apple docs

  

当您从NSDictionary对象桥接到Swift词典时,生成的词典的类型为[NSObject: AnyObject]

此外,除非Objective-C代码注释为可空性,否则Swift字典是一个隐式解包的可选项。因此,您的类型应如下所示:

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

我还建议将NSInteger更改为Int

答案 2 :(得分:0)

typealiascompletedResponseMethod对于您的程序是否绝对必要?如果没有,这可能会解决您的问题:

responseManager.manageServerResponse(response, NSData: data, andNSError: error, onComplete: { 
    $0, $1 in
    self.onComplete($0, jsonResponse: $1)
}

正如您的错误所示,错误是由于类型不匹配造成的。如果您使用默认的本地参数,您将能够解决该特定问题。