我有一些问题需要了解如何将带有完成块的方法调用为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)];
}
答案 0 :(得分:2)
使用Xcode中的代码完成来简化这一过程。
类型:
NSURLSessionDataTask *test = [weatherApiClient getForecast
并选择匹配的方法名称。然后在withCompletionBlock:
后选中占位符并按回车键。可悲的是,你最终会得到:
NSURLSessionDataTask *test = [weatherApiClient getForecastAndConditionsForZipCode:@"55345" withCompletionBlock:^(BOOL success, NSDictionary *result, NSError *error) {
}];
现在你需要填写花括号之间的部分。这是处理完成时要调用的块。您将获得success
,result
和error
的值。你可能想要这样的东西:
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];