天天看點

AFNetworking3的常用操作

前言

導入的最新版的

AFNetworking3.1.0

,突然發現找不到

AFHTTPRequestOperationManager

了。

剛開始以為是cocoapods沒有給我導進去,後來發現也沒有這

NSURLConnection

了,被

棄用

了,突然意識到,這個就是

AFHTTPRequestOperationManager

找不到的原因了,它是基于

NSURLConnection

封裝的!!

于是找了一下,現在都用的是

NSURLSession

了,

AFNetworking

中用的是

AFHTTPSessionManager

測試版本

AFNetworking3.1.0

官方文檔

GET/POST請求

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSMutableDictionary *parametersDic = [NSMutableDictionary dictionary];
//往字典裡面添加需要送出的參數
[parametersDic setObject:@"psvmc" forKey:@"username"];
[parametersDic setObject:@"123456" forKey:@"password"];

//GET/POST
[manager GET:@"http://www.psvmc.cn/login.json"
   parameters:parametersDic
   progress:^(NSProgress * _Nonnull downloadProgress) {
    
   }
   success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
    NSLog(@"---擷取到的json格式的字典--%@",resultDic);
       
    NSString *resultStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    NSLog(@"---擷取到的NSString格式的結果--%@",resultStr);
   }
   failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull   error) {
    NSLog(@"%@",error);  //這裡列印錯誤資訊
   }];           

複制

添加認證頭

[manager.requestSerializer setValue:[NSString stringWithFormat:@"%@ %@", @"Bearer", @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"] forHTTPHeaderField:@"Authorization"];           

複制

指定Request的序列化方式

NSMutableDictionary *parametersDic = [NSMutableDictionary dictionary];
//往字典裡面添加需要送出的參數
[parametersDic setObject:@"psvmc" forKey:@"username"];
[parametersDic setObject:@"123456" forKey:@"password"];
NSURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:@"http://www.psvmc.cn/login.json" parameters:parametersDic error:nil];
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
   NSString *resultStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
   NSLog(@"---擷取到的NSString格式的結果--%@",resultStr);
}];
[dataTask resume];           

複制

Request序列化的方式有三種 (上面示例的就是方式1)

  • GET一種 也就是預設的方式
  • POST兩種 預設的方式 和JSON方式

假如要請求的URL 和參數如下

NSString *URLString = @"http://example.com";
NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]};           

複制

1) 方式1 GET請求預設的方式

HTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil];           

複制

實際請求的樣子

GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3           

複制

2) 方式2 POST請求預設的方式

[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];           

複制

實際請求的樣子

POST http://example.com/
Content-Type: application/x-www-form-urlencoded

foo=bar&baz[]=1&baz[]=2&baz[]=3           

複制

3) 方式3 POST請求JSON形式的方式

[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil];           

複制

實際請求的樣子

POST http://example.com/
Content-Type: application/json

{"foo": "bar", "baz": [1,2,3]}           

複制

指定Response的序列化方式

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];           

複制

如果不指定

預設如果傳回的格式是

json

類型 傳回的

responseObject

就是

NSDictionary

類型 可以類似這樣取值

responseObject[@"msg"]

如果不是

json

格式 就為

nil

如果傳回格式不固定 或者自己處理 就添加上面的序列化方式

建議

如果結果确定為JSON 就不添加上面的代碼

不确定 自己處理就需要添加

自己序列化的代碼

NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"---擷取到的json格式的字典--%@",resultDic);
  
NSString *resultStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
NSLog(@"---擷取到的NSString格式的結果--%@",resultStr);           

複制

是以還是建議添加序列化方式 自己處理

設定cookie

思路

  • 請求之前設定cookie
  • 請求回調之後儲存cookie

代碼如下

//儲存cookie
- (void)saveCookies{
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject: cookiesData forKey: @"sessionCookies"];
    [defaults synchronize];
}

//設定cookie
- (void)loadCookies{
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"sessionCookies"]];
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
    for (NSHTTPCookie *cookie in cookies){
        [cookieStorage setCookie: cookie];
    }
}           

複制

檔案下載下傳

/**
 *  AFN3.0 下載下傳
 */
- (void)downLoad{

    //1.建立管理者對象
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    //2.确定請求的URL位址
    NSURL *url = [NSURL URLWithString:@"http://www.psvmc.cn/favicon.ico"];
    
    //3.建立請求對象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    //下載下傳任務
    NSURLSessionDownloadTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //列印下下載下傳進度
        NSLog(@"下載下傳進度:%lf",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        //下載下傳位址
        NSLog(@"預設下載下傳位址:%@",targetPath);
        //設定下載下傳路徑,通過沙盒擷取緩存位址,最後傳回NSURL對象
        NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        return [NSURL URLWithString:filePath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        //下載下傳完成調用的方法
        NSLog(@"下載下傳完成:%@",filePath);
    }];
    
    //開始啟動任務
    [task resume];

}           

複制

檔案上傳

//1.建立管理者對象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.上傳檔案
NSDictionary *dict = @{@"username":@"1234"};

NSString *urlString = @"http://www.psvmc.cn/upload";
[manager POST:urlString parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
   //上傳檔案參數
   UIImage *iamge = [UIImage imageNamed:@"123.png"];
   NSData *data = UIImagePNGRepresentation(iamge);
   //這個就是參數
   [formData appendPartWithFileData:data name:@"file" fileName:@"123.png" mimeType:@"image/png"];
   //方式二
    [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"檔案位址"] name:@"file" fileName:@"1234.png" mimeType:@"application/octet-stream" error:nil];

} progress:^(NSProgress * _Nonnull uploadProgress) {
   //列印下上傳進度
   NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

   //請求成功
   NSLog(@"請求成功:%@",responseObject);

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

   //請求失敗
   NSLog(@"請求失敗:%@",error);
}];           

複制

  • 擷取Task 普通上傳
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

NSURL *URL = [NSURL URLWithString:@"http://www.psvmc.cn/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];

NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
    if (error) {
        NSLog(@"Error: %@", error);
    } else {
        NSLog(@"Success: %@ %@", response, responseObject);
    }
}];
[uploadTask resume];           

複制

  • 擷取Task

    Multi-Part

    Request
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://www.psvmc.cn/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
    } error:nil];

AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

NSURLSessionUploadTask *uploadTask;
uploadTask = [manager
              uploadTaskWithStreamedRequest:request
              progress:^(NSProgress * _Nonnull uploadProgress) {
                  // This is not called back on the main queue.
                  // You are responsible for dispatching to the main queue for UI updates
                  dispatch_async(dispatch_get_main_queue(), ^{
                      //Update the progress view
                      [progressView setProgress:uploadProgress.fractionCompleted];
                  });
              }
              completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
                  if (error) {
                      NSLog(@"Error: %@", error);
                  } else {
                      NSLog(@"%@ %@", response, responseObject);
                  }
              }];

[uploadTask resume];           

複制

監測目前網絡狀态(網絡監聽)

- (void)AFNetworkStatus{

    //1.建立網絡監測者
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];

    /*枚舉裡面四個狀态  分别對應 未知 無網絡 資料 WiFi
     typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
         AFNetworkReachabilityStatusUnknown          = -1,      未知
         AFNetworkReachabilityStatusNotReachable     = 0,       無網絡
         AFNetworkReachabilityStatusReachableViaWWAN = 1,       蜂窩資料網絡
         AFNetworkReachabilityStatusReachableViaWiFi = 2,       WiFi
     };
     */

    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        //這裡是監測到網絡改變的block  可以寫成switch友善
        //在裡面可以随便寫事件
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
                NSLog(@"未知網絡狀态");
                break;
            case AFNetworkReachabilityStatusNotReachable:
                NSLog(@"無網絡");
                break;

            case AFNetworkReachabilityStatusReachableViaWWAN:
                NSLog(@"蜂窩資料網");
                break;

            case AFNetworkReachabilityStatusReachableViaWiFi:
                NSLog(@"WiFi網絡");

                break;

            default:
                break;
        }

    }] ;
}           

複制