在使用AFNewWorking做数据解析时,有时会需要对得到的数据进行判断,满足条件时会根据得到的参数继续请求,也就是需要通过循环的方式一层一层的向下获取,而且每一层都有我们需要的数据,但是不完整,需要进行到最后一层时,才能得到我们所需的完整数据。这个时候,单纯的使用for循环或者forin循环,会出现各种的问题,在这里记录一些我遇到需要逐层多次请求时用到的方法。
举个例子,比如说你写一个看书的应用,从某些应用中抓取的书籍章节列表一次只能返回50章,这时候你由于某些原因,无法用刷新的方式一次次去得到这些章节列表,要求一次性的传回所有的列表,在类似这种情况下的解决方法。
想要一次性传回所有的数据,而且是在多层AFNetWotking下得到我们想要的,我想到最好的方法就是block回调,将得到数据一层一层的村道一个数组中,通过在请求里判断,只要满足某些条件,直接block();
首先,创建一个无返回值的方法,类似如下
+ (void)GetDataArrayTask:(void (^)(NSMutableArray *urlArray, NSError *error))block NeedUrl_ArrWithJsonTypeUrlString:(NSString *)needUrl Cookie:(NSString *)ac_cookie ServerID:(NSInteger)serverID
将所需要的参数添加进来,然后block回调的数组,就是最终得到的包含全部数据的完整数组;
然后,还需要创建一个类似的方法,多次循环的时候去用,类似如下
+ (void )nextData_Arr:(void(^)(NSMutableArray *urlArray))black NeedUrl:(NSString *)needUrl Cookie:(NSString *)ac_cookie ServerID:(NSInteger)serverID
通过这两个方法得到的数据一次次进行累加,最终的到完整的数据,由于使用的是类方法,这时需要声明一个全局的单例
static NSMutableArray *imageUrlArr = nil;创建你需要将得到数据存入的一个数组,在第一个方法里进行初始化
总体实现的原理是在外部调用第一个方法,正在block中得到完整的数据,在第一个方法中通过判断调用第二个方法,然后再在第二个方法中判断,满足条件时继续调用第二个方法,知道得到完整的数据,然后返回给第一个方法,最后第一个方法中block();所有的数据
代码如下:
以获取图片为例,代码可能不是很完整,主要记录的是整体的思路和流程
+ (void)GetDataArrayTask:(void (^)(NSMutableArray *urlArray, NSError *error))block NeedUrl_ArrWithJsonTypeUrlString:(NSString *)needUrl Cookie:(NSString *)ac_cookie ServerID:(NSInteger)serverID
{
//由于使用的类方法,故访问全局的在上面声明一个单例
if (!imageUrlArr)
{
imageUrlArr = [[NSMutableArray alloc] init];
}else{
if (imageUrlArr.count > 0)
{
[imageUrlArr removeAllObjects];
}
}
__block AFHTTPRequestOperationManager *getImageArrayManager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer * getImageArrayRequestSerializer = [AFJSONRequestSerializer serializer];
getImageArrayRequestSerializer.timeoutInterval = TIMEOUTINTERVAL;
getImageArrayManager.requestSerializer = getImageArrayRequestSerializer;
getImageArrayManager.responseSerializer = [AFHTTPResponseSerializer serializer];
//第一次的请求,此请求只走一次,为了最终将完整的图片地址返回给需要的地方
[getImageArrayManager GET:needUrl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (responseObject) {
id dataId = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil]nil;
if ([dataId isKindOfClass:[NSArray class]])
{
if (满足条件将图片存入数组)
{
for (NSDictionary *dict in (NSArray *)dataId) {
[imageUrlArr addObject:imageUrlStr];
//里面先加入一部分图片的地址,此时如果不完整,继续走另一个方法
}
}
}
if (数据不完整时)
{
NSString *NextUrl = 下一页的地址;//请求需要的下一页地址
[Common nextComicImageUrl_Arr:^(NSMutableArray *imageArray) {
block(imageArray , nil);//这里等到第二个方法有返回的时候才会走,此时已经将所有的图片都存储到数组中,然后返回
} ComicStrUrl:NextUrl SearchCookie:ac_cookie ServerID:serverID];
}else{
if (block) {
block(imageUrlArr , nil);//如果已经完整,直接返回
}
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (block) {
block([NSMutableArray array] , nil);
}
});
}];
}
获取下一页网址的图片数据
+ (void )nextData_Arr:(void(^)(NSMutableArray urlArray))black NeedUrl:(NSString )nextUrl Cookie:(NSString *)ac_cookie ServerID:(NSInteger)serverID
{
__block AFHTTPRequestOperationManager *getImageArrayManager = [AFHTTPRequestOperationManager manager];
AFJSONRequestSerializer * getImageArrayRequestSerializer = [AFJSONRequestSerializer serializer];
getImageArrayRequestSerializer.timeoutInterval = TIMEOUTINTERVAL;
getImageArrayManager.requestSerializer = getImageArrayRequestSerializer;
getImageArrayManager.responseSerializer = [AFHTTPResponseSerializer serializer];
[getImageArrayManager GET:nextUrl parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (responseObject) {
id dataId = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil]nil;
if ([dataId isKindOfClass:[NSArray class]])
{
if (serverConfig.downloadOfChooseList.downloadOfIsJson.downloadInfoObjectForKey_KeysArray.count > 4)
{
for (NSDictionary *dict in (NSArray *)dataId) {
[imageUrlArr addObject:imageUrlStr];//继续将图片地址存入数组中
}
}
}
if (数据不完整时)
{
NSString *NextUrl = 下一页的地址;
//当获得的数据不完整,继续调用此方法
[Common nextComicImageUrl_Arr:^(NSMutableArray *imageArray) {
if (满足数据完整时) {
black(imageUrlArr);//数据完整,直接返回给上一个方法,由上一个方法回调给需要使用的地方
}
} ComicStrUrl:comicStrUrl SearchCookie:ac_cookie ServerID:serverID];
}else{
if (block) {
block(imageUrlArr);//数据完整了就进行返回
}
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (block) {
block([NSMutableArray array] , nil);
}
});
}];
}
这里使用的还是AF2.X,主要想要理解的还是这里面相互循环获取数据的一个方式