Objective C 中带回调的块转换为 Swift 中的闭包

Conversion of Block with callback in Objective C to closure in Swift

我在 Objective C

块中有以下回调
typedef void (^COMPLETION_BLOCK)(NSString *response, NSError *errorString);

+ (void)responseFromURL:(NSURL *)url completionBlock:(COMPLETION_BLOCK)completionBlock
{
   __block  NSError *error = nil;    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSString *response = [NSString stringWithContentsOfURL:url
                                                      encoding:NSUTF8StringEncoding
                                                         error:&error];

        dispatch_async(dispatch_get_main_queue(), ^{
                completionBlock(response, error);
        });
    });
}

这是我在 Objective C

中的称呼
[Utilities responseFromURL:NSURL URLWithString:@""] completionBlock:^(NSString *response, NSError *errorString)
{

}]

我试过在 swift 的 Clousers 中转换它 这是代码

class Utilities
{
    typealias COMPLETION_BLOCK = ( response : NSString, error : NSError) -> ()

    func responseFromURL(url: NSURL , completionBlock:COMPLETION_BLOCK)
    {
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        var e : NSError?;

        dispatch_async(dispatch_get_global_queue(priority, 0))
        {
            var content:NSString? = NSString(contentsOfURL: url,
                encoding: NSUTF8StringEncoding,
                error: &e)

            dispatch_async(dispatch_get_main_queue())
            {
                completionBlock(response: content!,error:  e!);
            }
        }
    }
}

我不确定这是否是正确的转换。其次,我应该如何调用 swift 中的块?

var urlString = String(format: BASE_URL + "%d", categoryType);
        var url = NSURL(string :urlString);

你快到了。您不需要类型别名,因为您可以在函数定义中指定 completionBlock。

可能会给您带来问题的一件事是内容的强制解包,其中一个将为零。

这是我的函数版本:

func responseFromURL(url : NSURL, completionBlock : (response : String?, error : NSError?) -> Void) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
        var error : NSError? = nil
        let response = String(contentsOfURL: url, encoding: NSUTF8StringEncoding, error: &error)

        dispatch_async(dispatch_get_main_queue()) {
            completionBlock(response: response, error: error)
        }
    }
}

并调用它:

responseFromURL(myURL) { (response, error) in
    if error != nil {
        // handle error
    }
    else if response != nil {
        // data came back
    }
}

有几点需要注意:

  • 在完成块定义中,我指定响应和错误参数都是可选的。您应该取回一个或另一个,但您需要检查是哪一个。
  • 与 Objective-C 不同,您不必发送指向错误的指针。如果需要,完成处理程序会向您发回错误。
  • 我使用了 Swift 闭包的较短形式,但如果你让自动完成完成它的工作,你会得到更长的形式,这可能更具可读性。