AFNetWorking用法及緩存處理

nwbg 9年前發布 | 31K 次閱讀 Objective-C IOS

AFNetWorking 在IOS開發中是一個經常會用的第三方開源庫,其最好處是維護及時,源碼開源。

常用GET與POST請求方法:

POST請求:

//初始化一個請求對象 
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
  NSString * url = @"你的請求地址";
  //dic 為參數字典
 [manager POST:url parameters:dic success:^(AFHTTPRequestOperation *operation, id responseObject) {
    //請求成功的回調
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    //請求失敗的回調    
    }];

GET請求:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
 NSString * url = @"你的請求地址";
   [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    //請求成功的回調
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    //請求失敗的回調   
    }];

這里有一個地方需要注意,

[AFHTTPRequestOperationManager manager]

這個類方法我們點進源碼可以發現:

+ (instancetype)manager {
    return [[self alloc] initWithBaseURL:nil];
}

這里初始化了一個返回了一個新的對象,并不是單例。

使用這樣的下載方法,下載完成后的數據AFNetWorking會幫我們自動解析,但是有時候服務器給的數據并不標準,這時我們需要加上這個設置:


manager.responseSerializer = [AFHTTPResponseSerializer serializer];

這樣我們將得到原始的HTTP返回給我們數據。

我們再來探究一下,下載成功后,回調方法里的參數到底是什么東西


success:^(AFHTTPRequestOperation *operation, id responseObject)

其中,第二個參數 responseObject 是下載下來的data數據,可直接進行JSON等解析。

第一個參數,是個AFHTTPRequestOperation對象,來看源文件

@interface AFHTTPRequestOperation : AFURLConnectionOperation

@property (readonly, nonatomic, strong) NSHTTPURLResponse *response;

@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;

@property (readonly, nonatomic, strong) id responseObject;

@end

可以發現,里面有一個成員便是responseObject,同時,AFHTTPRequestOperation是繼承于AFURLConnectionOperation,我們在看看AFURLConnectionOperation這個類:

@interface AFURLConnectionOperation : NSOperation <NSURLConnectionDelegate, NSURLConnectionDataDelegate, NSSecureCoding, NSCopying>

@property (nonatomic, strong) NSSet *runLoopModes;

@property (readonly, nonatomic, strong) NSURLRequest *request;

@property (readonly, nonatomic, strong) NSURLResponse *response;

@property (readonly, nonatomic, strong) NSError *error;

@property (readonly, nonatomic, strong) NSData *responseData;

@property (readonly, nonatomic, copy) NSString *responseString;

@property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding;

@property (nonatomic, assign) BOOL shouldUseCredentialStorage;

@property (nonatomic, strong) NSURLCredential *credential;

@property (nonatomic, strong) AFSecurityPolicy *securityPolicy;

@property (nonatomic, strong) NSInputStream *inputStream;

@property (nonatomic, strong) NSOutputStream *outputStream;

@property (nonatomic, strong) dispatch_queue_t completionQueue;

@property (nonatomic, strong) dispatch_group_t completionGroup;

@property (nonatomic, strong) NSDictionary *userInfo;

- (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER;

- (void)pause;

- (BOOL)isPaused;

- (void)resume;

看到這里,就離AFNETWorking封裝的源頭很近了,里面的成員非常多,其中包含了大部分我們需要的信息,可以通過點語法取到,其中有輸入輸出流,錯誤信息,請求到的Data數據,以及請求到的字符串數據 

responseString

我們可以通過

NSLog ( @"operation: %@" , operation. responseString );

來打印查看請求到的原始信息。

幾點注意:

1.關于崩潰url為nil

大多數這樣的原因是url中有特殊字符或者中文字符,AFNETWorking并沒有做UTF8的轉碼,需要:

url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

2.添加HttpHead字段的方法

 //為這個下載任務HTTP頭添加@"User-Agent"字段
 [manager.requestSerializer setValue:_scrData forHTTPHeaderField:@"User-Agent"];
 //打印頭信息
    NSLog(@"%@",manager.requestSerializer.HTTPRequestHeaders);

在下載請求中,經常會請求一些不長變化的數據,如果每次APP啟動都進行請求,會消耗許多資源,并且有時候緩存的處理,可以大大改善用戶體驗。

在AFNETWorking中,并沒有提供現成的緩存方案,我們可以通過寫文件的方式,自行做緩存。

在下載方法中:

[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        //寫緩存
        NSString *cachePath = @"你的緩存路徑";//  /Library/Caches/MyCache
        [data writeToFile:cachePath atomically:YES];
                succsee(data);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

然后在每次下載前,進行如下判斷:

 NSString * cachePath = @"你的緩存路徑";
        if ([[NSFileManager defaultManager] fileExistsAtPath:cachePath]) {
            //從本地讀緩存文件
            NSData *data = [NSData dataWithContentsOfFile:cachePath];
            }

有時,我們的下載請求可能是用戶的動作觸發的,比如一個按鈕。我們還應該做一個保護機制的處理,

//初始化一個下載請求數組
NSArray * requestArray=[[NSMutableArray alloc]init];
//每次開始下載任務前做如下判斷
for (NSString * request in requestArray) {
        if ([url isEqualToString:request]) {
            return;
        }
    }
 [requestArray addObject:url];
 //下載成功或失敗后
 [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        [requestArray removeObject:url]
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [requestArray removeObject:url]
    }];

至此,一個比較完成AFNETWorking請求使用流程就完成了。




 本文由用戶 nwbg 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!