尝试将 Objective C 完成块移植到 Swift 时出现问题
Problems trying to port an Objective C completion block into Swift
我正在使用 objective 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)
我收到这个错误:
Cannot invoke 'manageServerResponse' with an argument list of type
'(NSURLResponse?, NSData: NSData?, andNSError: NSError?, onComplete:
ResponseCompletedBlock)'
如果我将最后一句替换为
responseManager.manageServerResponse(response,
NSData: data,
andNSError: error,
onComplete: nil)
一切正常,所以我认为问题出在块结构上,但我已尝试更改所有内容,但错误仍然存在。
你能帮忙吗?
typealias
和 completedResponseMethod
是您的程序运行所必需的吗?如果没有,这可能会解决您的问题:
responseManager.manageServerResponse(response, NSData: data, andNSError: error, onComplete: {
[=10=], in
self.onComplete([=10=], jsonResponse: )
}
如您的错误所示,错误是由于类型不匹配造成的。如果您使用默认的本地参数,您将能够解决该特定问题。
NSDictionary *
映射到 Swift 作为 [NSObject : AnyObject]!
,
因此响应块的类型应该是
typealias ResponseCompletedBlock = (Int, [NSObject : AnyObject]!) -> Void
因此
let completedResponseMethod = {(kindOfError: Int, jsonResponse: [NSObject : AnyObject]!) -> Void in
// ...
}
找出正确的 Swift 函数签名的一种方法是使用 Xcode 中的 自动完成 :
您开始输入
responseManager.manageServerResponse(
和Xcode建议
根据 Apple docs:
When you bridge from an NSDictionary
object to a Swift dictionary, the resulting dictionary is of type [NSObject: AnyObject]
.
此外,除非 Objective-C 代码被注释为空性,否则 Swift 字典是一个隐式展开的可选。因此你的类型别名应该是这样的:
typealias ResponseCompletedBlock = (NSInteger, [NSObject : AnyObject]!) -> Void
我还建议将 NSInteger
更改为 Int
。
我正在使用 objective 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)
我收到这个错误:
Cannot invoke 'manageServerResponse' with an argument list of type '(NSURLResponse?, NSData: NSData?, andNSError: NSError?, onComplete: ResponseCompletedBlock)'
如果我将最后一句替换为
responseManager.manageServerResponse(response,
NSData: data,
andNSError: error,
onComplete: nil)
一切正常,所以我认为问题出在块结构上,但我已尝试更改所有内容,但错误仍然存在。
你能帮忙吗?
typealias
和 completedResponseMethod
是您的程序运行所必需的吗?如果没有,这可能会解决您的问题:
responseManager.manageServerResponse(response, NSData: data, andNSError: error, onComplete: {
[=10=], in
self.onComplete([=10=], jsonResponse: )
}
如您的错误所示,错误是由于类型不匹配造成的。如果您使用默认的本地参数,您将能够解决该特定问题。
NSDictionary *
映射到 Swift 作为 [NSObject : AnyObject]!
,
因此响应块的类型应该是
typealias ResponseCompletedBlock = (Int, [NSObject : AnyObject]!) -> Void
因此
let completedResponseMethod = {(kindOfError: Int, jsonResponse: [NSObject : AnyObject]!) -> Void in
// ...
}
找出正确的 Swift 函数签名的一种方法是使用 Xcode 中的 自动完成 : 您开始输入
responseManager.manageServerResponse(
和Xcode建议
根据 Apple docs:
When you bridge from an
NSDictionary
object to a Swift dictionary, the resulting dictionary is of type[NSObject: AnyObject]
.
此外,除非 Objective-C 代码被注释为空性,否则 Swift 字典是一个隐式展开的可选。因此你的类型别名应该是这样的:
typealias ResponseCompletedBlock = (NSInteger, [NSObject : AnyObject]!) -> Void
我还建议将 NSInteger
更改为 Int
。