1. 程式人生 > >ios迴圈請求資料的正確方法

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,主要想要理解的還是這裡面相互迴圈獲取資料的一個方式