Objective-C完成块

时间:2014-09-25 23:04:03

标签: ios objective-c

我有一些问题需要了解如何将带有完成块的方法调用为NSURLSessionTask。想知道如何在没有错误的情况下正确调用方法getForecastAndConditionsForZipCode。谢谢!

Api.h:

 typedef void (^WeatherAPICompletionBlock)(BOOL success, NSDictionary *result, NSError *error);

 - (NSURLSessionDataTask *)getForecastAndConditionsForZipCode:(NSString *)zipCode withCompletionBlock:(WeatherAPICompletionBlock)completionBlock;

Api.m

 - (NSURLSessionDataTask *)getForecastAndConditionsForZipCode:(NSString *)zipCode withCompletionBlock:(WeatherAPICompletionBlock)completionBlock
 {
if (!self.APIKey) {
    NSAssert(NO, @"API Key not set", nil);
    completionBlock(NO, nil, [self missingAPIKeyError]);
    return nil;
}

if (![NSThread isMainThread]) {
    NSAssert(NO, @"API client method must be called on the main thread", nil);
    completionBlock(NO, nil, [self genericError]);
    return nil;
}

// Create the path
NSString *pathString = [NSString stringWithFormat:@"/api/%@%@/q/%@.json", self.APIKey, kWeatherAPIConditionsPath, zipCode];

// To avoid a retain cycle
__weak __typeof(self)weakSelf = self;

// Start the request

return [self GET:pathString parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
 if (!responseObject || ![responseObject isKindOfClass:[NSDictionary class]] || [responseObject count] == 0) {
        DLog(@"Invalid responseObject: %@", responseObject);
        completionBlock(NO, nil, [weakSelf genericError]);
        return;
    }
    completionBlock(YES, responseObject, nil);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    DLog(@"Error with getForcastForLocation response: %@", error);
    completionBlock(NO, nil, error);
}];

}

ViewController.m(这里我不知道如何调用getForecastAndConditionsForZipCode方法

导入" Api.h"

 - (IBAction)runApi:(UIButton *)sender {

  WeatherAPIClient *weatherApiClient = [[WeatherAPIClient alloc] init];

  NSURLSessionDataTask *test =  [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(YES, result, error)];

 }

1 个答案:

答案 0 :(得分:2)

使用Xcode中的代码完成来简化这一过程。

类型:

NSURLSessionDataTask *test =  [weatherApiClient getForecast

并选择匹配的方法名称。然后在withCompletionBlock:后选中占位符并按回车键。可悲的是,你最终会得到:

NSURLSessionDataTask *test =  [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(BOOL success, NSDictionary *result, NSError *error) {
}];

现在你需要填写花括号之间的部分。这是处理完成时要调用的块。您将获得successresulterror的值。你可能想要这样的东西:

NSURLSessionDataTask *test =  [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(BOOL success, NSDictionary *result, NSError *error) {
    if (success) {
        // do something with result
    } else {
        NSLog(@"Uh oh - error getting forecast: %@", error);
    }
}];

顺便说一下 - 你的getForecastAndConditionsForZipCode:withCompletionBlock:的实现不应该假设传入了一个完成块。确保你保护所有对完成块的调用:

if (completionBlock) {
    completionBlock(YES, someResult, nil); // or whatever values you need to send
}

如果有人打电话,此代码可确保您的应用不会崩溃:

NSURLSessionDataTask *test =  [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:nil];