https://www.jianshu.com/p/ab246881efa9
AFNetWorking的介紹(給沒使用過的讀者看的)
- AFNetWorking是目前iOS開發者網絡庫中最多的選擇
- AFNetWorking是對NSURLConnection和NSURLSession的封裝,iOS 9(AFN3.0版本)之后刪除了NSURLConnection的API的所有支持,完全基於NSURLSession 的API.
介紹下2.0版本跟3.0版本使用的區別
2.0版本:
使用 AFHTTPRequestOperationManager這個網絡管理者
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"需要請求的url" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"請求成功"); } failure:^(AFHTTPRequestOperation *operation, NSError*error) { NSLog(@"請求失敗"); }];
3.0版本:
使用 AFHTTPSessionManager 這個網絡管理者
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
[session GET:@"需要請求的url" parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"請求成功"); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"請求失敗"); }];
為什么會廢棄NSURLConnection而使用NSURLSession這個網絡類呢?
- 從iOS7之后,蘋果就推出了NSURLSession , AFN跟隨着蘋果的腳步,加入了對其的支持
- NSURLSession推出后蘋果大力推廣,但是其效果和NSURLConnection效果差不多,為什么NSURLConnection還會被廢棄呢?
- 因為:2015年的WWDC大會,HTTP2.0時代的到來,(1.1版本是99年),HTTP2.0比之前的版本速度更快
- iOS9(Xcode7)之后, NSURLSession開始正式支持HTTP2.0,所以相比速度快差不多4倍, NSURLSession將NSURLConnection甩開了距離
- 純屬個人理解
AFNetWorking的使用(直接上代碼)
- GET請求
-(void)get { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.封裝參數 NSDictionary *dict = @{ @"username":@"Lion", @"pwd":@"1314", @"type":@"JSON" }; //3.發送GET請求 /* 第一個參數:請求路徑(NSString)+ 不需要加參數 第二個參數:發送給服務器的參數數據 第三個參數:progress 進度回調 第四個參數:success 成功之后的回調(此處的成功或者是失敗指的是整個請求) task:請求任務 responseObject:注意!!!響應體信息--->(json--->oc)) task.response: 響應頭信息 第五個參數:failure 失敗之后的回調 */ [manager GET:@"需要請求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"success--%@--%@",[responseObject class],responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"failure--%@",error); }]; }
- POST請求和GET請求一樣,只需要換成POST請求方法
[manager POST:@"需要請求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"success--%@--%@",[responseObject class],responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"failure--%@",error); }];
- 下載操作(不是離線下載,離線下載需要自己手動處理)
-(void)download { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.確定請求路徑 NSURL *url = [NSURL URLWithString:@"需要請求的URL"]; //3.創建請求對象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //4.發送網絡請求下載文件 /* 第一個參數:請求對象 第二個參數:progress 進度回調 downloadProgress @property int64_t totalUnitCount; @property int64_t completedUnitCount; 第三個參數:destination 讓我們告訴系統應該把文件存放到什么地方 內部自動的完成剪切處理 第四個參數: completionHandler 完成之后的回調 response 響應頭信息 filePath 文件最終的存儲路徑 error 錯誤信息 */ [[manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) { NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount); } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { //拼接文件的全路徑 NSString *fullpath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename]; NSLog(@"fullpath == %@",fullpath); return [NSURL fileURLWithPath:fullpath]; } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { NSLog(@"%@",filePath); }] resume]; }
- 上傳操作
-(void)upload { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.發送請求上傳文件 /* 第一個參數:請求路徑(NSString) 第二個參數:非文件參數 第三個參數:constructingBodyWithBlock 拼接數據(告訴AFN要上傳的數據是哪些) 第四個參數:progress 進度回調 第五個參數:success 成功回調 responseObject:響應體 第六個參數:failure 失敗的回調 */ [manager POST:@"需要請求的URL" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { NSData *data = [NSData dataWithContentsOfFile:@"/Users/apple/Desktop/Snip20160409_148.png"]; //拼接數據 /* 第一個參數:文件參數 (二進制數據) 第二個參數:參數名~file 第三個參數:該文件上傳到服務器以什么名稱來保存 第四個參數: */ [formData appendPartWithFileData:data name:@"file" fileName:@"123.png" mimeType:@"image/png"]; } progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"success--%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"failure -- %@",error); }]; }
NSURLSessionConfiguration配置信息
- 作用:
- 統一配置session的信息,每個session可以發送多個請求
- 設置蜂窩網絡,隱私信息,超時時間\
@property (strong, nonatomic) NSURLSession *session; //將session設置為全局的屬性,方便發送網絡請求 //在懶加載里面設置配置的信息,達到統一設置 #pragma makr - 懶加載 -(NSURLSession *)session { if (_session == nil) { //設置配置信息 NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; //統一設置請求超時 config.timeoutIntervalForRequest = 15.0; //設置是否允許蜂窩網絡訪問 config.allowsCellularAccess = YES; _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; } return _session; }
AFNetWorking的序列化
- AFNetWorking默認是JSON解析(因為開發中百分之90都是JSON數據)
默認情況:JSON AFJSONResponseSerializer
XML:AFXMLParserResponseSerializer
既不是XML也不是JSON:AFHTTPResponseSerializer
- JSON
//1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; /* 1)afn內部默認已經完成了JSON解析工作 優點:方便 缺點:如果服務器返回的數據不是JSON會報錯 */ NSDictionary *dict = @{@"type":@"JSON"}; //2.發請求 [manager GET:@"需要請求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@--%@",[responseObject class],responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@---",error); }];
- XML
-(void)xml { <NSXMLParserDelegate>代理協議 //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //設置以XML的方式來解析數據 manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; NSDictionary *dict = @{@"type":@"XML"}; //2.發請求 [manager GET:@"需要請求的URL" parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@--%@",[responseObject class],responseObject); //1.創建解析器 NSXMLParser *parser = (NSXMLParser *)responseObject; //2.設置代理 parser.delegate = self; //3.開始解析 [parser parse]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@---",error); }]; }
- OtherHttpData
-(void)otherHttpData { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //設置不做處理 manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //2.發請求 [manager GET:@"需要請求的URL" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"%@--%@",[responseObject class],responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"%@---",error); }]; } #pragma mark NSXMLParserDelegate -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict { NSLog(@"%@--%@",elementName,attributeDict); }
- 檢測網絡的狀態
-(void)networkStatusChangeAFN { //1.獲得一個網絡狀態監聽管理者 AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; //2.監聽狀態的改變(當網絡狀態改變的時候就會調用該block) [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { /* AFNetworkReachabilityStatusUnknown = -1, 未知 AFNetworkReachabilityStatusNotReachable = 0, 沒有網絡 AFNetworkReachabilityStatusReachableViaWWAN = 1, 3G|4G AFNetworkReachabilityStatusReachableViaWiFi = 2, WIFI */ switch (status) { case AFNetworkReachabilityStatusReachableViaWiFi: NSLog(@"wifi"); break; case AFNetworkReachabilityStatusReachableViaWWAN: NSLog(@"3G|4G"); break; case AFNetworkReachabilityStatusNotReachable: NSLog(@"沒有網絡"); break; case AFNetworkReachabilityStatusUnknown: NSLog(@"未知"); break; default: break; } }]; //3.手動開啟 開始監聽 [manager startMonitoring]; }
AFN使用技巧
1.在開發的時候可以創建一個工具類,繼承自我們的AFN中的請求管理者,再控制器中真正發請求的代碼使用自己封裝的工具類。 2.這樣做的優點是以后如果修改了底層依賴的框架,那么我們修改這個工具類就可以了,而不用再一個一個的去修改。 3.該工具類一般提供一個單例方法,在該方法中會設置一個基本的請求路徑。 4.該方法通常還會提供對GET或POST請求的封裝。 5.在外面的時候通過該工具類來發送請求 6.單例方法:+ (instancetype)shareNetworkTools{ static XMGNetworkTools *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 注意: BaseURL中一定要以/結尾 instance=[[selfalloc]initWithBaseURL:[NSURL URLWithString:@"請求的URL"]]; }); return instance; }
作者:會跳舞的獅子
鏈接:https://www.jianshu.com/p/ab246881efa9
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。