我想知道如何避免所有那些嵌套的if / success块?因此,我对如何改进/封装此架构的任何建议感到满意
- (void)findLocation {
// Show loader.png
[self.searchButton setImage:[UIImage imageNamed:@"loader"] forState:UIControlStateNormal];
// Request url
NSString *url = [NSString stringWithFormat:@"http://api.domain.com/someendpoint/"];
// Send http request
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:url parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// If API returned error
if([responseObject objectForKey:@"error"]) {
// Show an error
// Hide loader
[self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];
// Skip everything else
return;
}
// If API returned data
// Init location object
Location * location = [[Location alloc] init];
location.name = [responseObject objectForKey:@"name"];
location.image_url = [responseObject objectForKey:@"image_url"];
location.url = [responseObject objectForKey:@"url"];
location.address = [responseObject objectForKey:@"address"];
// Calculate long/lat from address (API does not provide this information
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location.address completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
// Show error
} else {
// Save geo-location to location object
CLPlacemark *place = [placemarks lastObject];
location.location = CLLocationCoordinate2DMake(place.location.coordinate.latitude, place.location.coordinate.longitude);
// Present ResultViewController
ResultViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"ResultView"];
controller.location = location;
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:controller animated:YES completion:nil];
// Initialize region to monitor
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:location.location radius:150.0 identifier:[[NSUUID UUID] UUIDString]];
// Start monitoring new region
[self.locationManager startMonitoringForRegion:region];
// Stop UpdatingLocation
[self.locationManager stopUpdatingLocation];
// Hide loader
[self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];
}];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Show error
// Hide loader
[self.searchButton setImage:[UIImage imageNamed:@"some_button"] forState:UIControlStateNormal];
}
];
}
答案 0 :(得分:0)
在Show error
部分之后,从函数返回。这样,您可以将其余代码放在else
子句之外。
答案 1 :(得分:0)
正如S. McConnel建议的那样,首先使用if来处理成功的场景 - 这使得代码阅读更容易。
正如zmbq建议的那样,将它包装成一个函数。
obj c中的块并不是真正的“十大”因为它们的美丽,只是与它们一起使用:)
Google的Objective C代码风格的一些提示:
http://google-styleguide.googlecode.com/svn/trunk/objcguide.xml#Blocks
作为功能的变体:
- (void)findLocation {
// Show loader.png
[self.searchButton setImage:[UIImage imageNamed:@"loader"] forState:UIControlStateNormal];
// Request url
NSString *url = [NSString stringWithFormat:@"http://api.domain.com/someendpoint/"];
// Send http request
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:url parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// If API returned data
if([[responseObject objectForKey:@"ErrorCode"] intValue] == 0) {
[self setupLocation:responseObject];
// If API returned error
}
else { // Show an error
// Hide loader
[self.searchButton setImage:[UIImage imageNamed:@"surpriseme_button"] forState:UIControlStateNormal];
}
}];
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Hide loader
[self.searchButton setImage:[UIImage imageNamed:@"surpriseme_button"] forState:UIControlStateNormal];
}
];
}