ios迴圈請求資料的正確方法
在使用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,主要想要理解的還是這裡面相互迴圈獲取資料的一個方式