2014-09-25 44 views
-2

我有一些问题,了解如何使用完成块调用方法为NSURLSessionTask。想知道如何正确调用方法getForecastAndConditionsForZipCode而不出错。谢谢!Objective-C完成块

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

import“Api.h”

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

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

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

} 
+1

说真的,你可以改变你的问题的标题? – gnasher729 2014-09-25 23:13:23

+0

@ gnasher729,你对他的头衔有“异议”?我没有提出你的反对意见。 :) – 2014-09-26 00:46:14

回答

2

在Xcode中使用代码完成来简化。

类型:

NSURLSessionDataTask *test = [weatherApiClient getForecast 

,并选择匹配方法的名称。然后在withCompletionBlock:后标签到占位符并按回车。神奇地你会结束:

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

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

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]; 
+0

这基本上就是我所做的。唯一的问题是xcode不允许你填写它,你需要实际输入它手动工作。谢谢,我有它的工作? – jKraut 2014-09-26 12:17:03