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

时间:2015-02-06 07:30:10

标签: objective-c swift closures

我在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)
{

}]

我尝试过迅速将它转换为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);

1 个答案:

答案 0 :(得分:3)

你快到了。您不需要类型,因为您可以在函数定义中指定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闭包,但如果你让自动完成它的东西,你会得到更长的形式,这可能更具可读性。