即使一个API失败,加载视图控制器
我有三个API
的我从我的ViewController.m
内拉UITableView
,并将其放入UITableView
。即使一个API失败,加载视图控制器
如果其中一个网站未加载,是否还有办法让UITableView
加载?
现在,ViewController.m
只是不加载,如果所有3个来源没有按我的方法加载。
这是我使用的方法:在ViewController.m
的UITableView
- (void)loadOneWithSuccess:(void (^)(RKObjectRequestOperation *operation, RKMappingResult *mappingResult))success
failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *tNE = [defaults objectForKey:[NSString stringWithFormat:@"tNE%@", bn]];
NSString *path = [NSString stringWithFormat:@"xx/%@/", tNE];
[self.eObjectManager getObjectsAtPath:path parameters:nil success:success failure:failure];
}
- (void)loadMedia {
self.combinedModel = [NSMutableArray array];
// Here's the #1
[self loadOneWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
// Here's the trick. call API2 here. Doing so will serialize these two requests
[self loadTwoWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
// Here's the trick. call API3 here. Doing so will serialize these two requests
[self loadThreeWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
[self sortCombinedModel];
[self.tableView reloadData];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
}];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
}];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
}];
}
所以如果API1
不加载,API2
和API3
仍然会加载和显示。
的loadOne,loadTwo ...功能有一个缺点是,他们需要两个块参数,一个成功,一个失败。如果您将这些更改为采用处理成功或失败的单个模块,那么发生错误后将更容易进行。
编辑通过不直接传递完成和失败块来改变如何调用eObjectManager。相反,实施这些块和重新排列PARAMS相匹配的单块接口...
- (void)betterLoadOneWithCompletion:(void (^)(RKObjectRequestOperation*, RKMappingResult*, NSError *))completion {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *tNE = [defaults objectForKey:[NSString stringWithFormat:@"tNE%@", bn]];
NSString *path = [NSString stringWithFormat:@"xx/%@/", tNE];
[self.eObjectManager getObjectsAtPath:path parameters:nil success:^(RKObjectRequestOperation *op, RKMappingResult *map) {
// success! pass the operation, map result and no error
completion(op, map, nil);
} failure:^(RKObjectRequestOperation *op, NSError *error) {
// fail. pass the operation, no result and the error
completion(op, nil, error);
}];
}
它仍然可以调用旧的功能或与两个街区的一些外部库,但它的结果组合成一个单独的块。这个调用者期望他们将得到一个好的RKMappingResult和一个nil NSError,或者一个无结果参数和一个错误实例。有了这个api,我们可以轻松修复您的方法,只需记录错误发生时的情况,并继续进行,错误或不...
- (void)loadMedia {
self.combinedModel = [NSMutableArray array];
// changed the loadOneWithCompletion signature to take just a single block, calling it on success or fail
[self betterLoadOneWithCompletion:^(RKObjectRequestOperation *op, RKMappingResult *mappingResult, NSError *error) {
// if it worked, handle the results
if (!error) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
} else {
// if it didn't work, log the error, but execution continues
NSLog(@"No?: %@", error);
}
// even if it didn't work, we can keep going...
[self betterLoadOneWithCompletion:^(RKObjectRequestOperation *op, RKMappingResult *mappingResult, NSError *error) {
// same - handle results
if (!error) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
} else {
// same - log the error if there is one
NSLog(@"No?: %@", error);
}
// same - log the error and keep going
[self betterLoadOneWithCompletion:^(RKObjectRequestOperation *op, RKMappingResult *mappingResult, NSError *error) {
// same...
if (!error) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
} else {
NSLog(@"No?: %@", error);
}
[self sortCombinedModel];
[self.tableView reloadData];
}];
}];
}];
}
也许你可以尝试这样的事情,首先要定义树布尔变量:finish1,finish2和finish3
- (void)loadMedia {
self.combinedModel = [NSMutableArray array];
[self loadOneWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
finish1 = true;
[self reloadTableData]
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
finish1 = true;
[self reloadTableData]
}];
[self loadTwoWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
finish2 = true;
[self reloadTableData]
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
finish2 = true;
[self reloadTableData]
}];
[self loadThreeWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[self.combinedModel addObjectsFromArray:mappingResult.array];
finish2 = true;
[self reloadTableData]
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"No?: %@", error);
finish3 = true;
[self reloadTableData]
}];
}
- (void) reloadTableData {
if (finish1 && finish2 && finish3) {
[self sortCombinedModel];
[self.tableView reloadData];
}
}
感谢您的回应!这看起来不错,谢谢你的答案! – Realinstomp 2014-11-21 13:16:46
我明白你的意思,谢谢你画出一幅清晰的图画。我不确定在新的'loadOneWithCompletion:'我在哪里放置'[self.eObjectManager getObjectsAtPath:路径参数:无成功:失败:失败];''我以前有过的部分,或者我该怎么做把它变成你有'callSomeExternalLibrary'的部分? – Realinstomp 2014-11-21 00:20:32
@Realinstomp - 我一定错过了你发布的如何调用外部API。请参阅建议具体更改的编辑。 – danh 2014-11-21 01:18:28
这是有道理的,快速的问题,我会把'[self sortCombinedModel];'和'[self.tableView reloadData];'?我无法弄清楚它的最佳工作点。以前它在'loadMedia'内部的'loadThreeWithSuccess'中。 – Realinstomp 2014-11-21 01:59:30