我有一个处理与外部API交互的类,我正在尝试找出将它们分解为descreat块的最佳方法。
目前,它看起来像这样:
- (BOOL) testCredentialsWithUsername:(NSString *)username password:(NSString *)password {
acUsername = username;
acPassword = password;
[self loadLoginPage];
return YES;
}
- (void)loadLoginPage {
[NSURLConnection sendAsynchronousRequest:...
completionHandler:^(...) {
[self logIntoMyAPI:response];
}];
}
- (void)logIntoMyAPI:(NSURLResponse *)response {
[NSURLConnection sendAsynchronousRequest:...
completionHandler:^(...) {
[self recieveLoginResponse:response data:data];
}];
}
- (void)recieveLoginResponse:(NSURLResponse *) response data:(NSData *)data {
if (...) {
NSLog(@"Logged into MyAPI!");
} else if (...) {
NSLog(@"Invalid username or password");
} else if (...) {
NSLog(@"Locked account");
} else {
NSLog(@"An unexpected error");
}
}
基本上,我想从我的View Controller中调用testCredtionalsWithUsername:password:
,并且可能使用成功/失败块,知道结果。
如果不将回调与测试testCredtionalsWithUsername:password:
方法联系起来,最好的方法是什么?
答案 0 :(得分:1)
在得到测试结果之前,您需要等待服务器响应,因此从testCredentialsWithUsername:password中返回BOOL没有任何意义。似乎。
一个优雅的解决方案是拥有一个在你有答案时被调用的completionBlock。像这样:
- (void) testCredentialsWithUsername:(NSString *)username password:(NSString *)password completion:(void (^)(BOOL success, NSError *error))completion {
acUsername = username;
acPassword = password;
_validationCompletion = completion; // Save this as an instance variable
[self loadLoginPage];
}
从服务器获得结果时:
- (void)recieveLoginResponse:(NSURLResponse *) response data:(NSData *)data {
BOOL success = data != nil; //or whatever you criteria is.
if (_completion != nil) {
NSError = success ? nil : [NSError new]; // create an appropriate error object
_completion(success, error)
_completion = nil;
}
}
答案 1 :(得分:0)
您可以将成功阻止和失败阻止的两个属性添加到该类,并在请求完成时调用它。在视图控制器中分配此类的实例并将两个块传递给此参数。 您还可以将initWithSuccessBlock:failureBlock:方法添加到该类,并在视图控制器中初始化此类时调用此方法。
希望得到这个帮助。