即使一个API失败,加载视图控制器

问题描述:

我有三个API的我从我的ViewController.m内拉UITableView,并将其放入UITableView即使一个API失败,加载视图控制器

如果其中一个网站未加载,是否还有办法让UITableView加载?

现在,ViewController.m只是不加载,如果所有3个来源没有按我的方法加载。

这是我使用的方法:在ViewController.mUITableView

- (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不加载,API2API3仍然会加载和显示。

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

我明白你的意思,谢谢你画出一幅清晰的图画。我不确定在新的'loadOneWithCompletion:'我在哪里放置'[self.eObjectManager getObjectsAtPath:路径参数:无成功:失败:失败];''我以前有过的部分,或者我该怎么做把它变成你有'callSomeExternalLibrary'的部分? – Realinstomp 2014-11-21 00:20:32

+0

@Realinstomp - 我一定错过了你发布的如何调用外部API。请参阅建议具体更改的编辑。 – danh 2014-11-21 01:18:28

+0

这是有道理的,快速的问题,我会把'[self sortCombinedModel];'和'[self.tableView reloadData];'?我无法弄清楚它的最佳工作点。以前它在'loadMedia'内部的'loadThreeWithSuccess'中。 – Realinstomp 2014-11-21 01:59:30

也许你可以尝试这样的事情,首先要定义树布尔变量: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]; 
    } 
} 
+0

感谢您的回应!这看起来不错,谢谢你的答案! – Realinstomp 2014-11-21 13:16:46