iOS AFNetworking 以及参数Cookie 详解

1> GET 请求:

NSString *url = @"[http://gank.io/api/history/content/2/1](http://gank.io/api/history/content/2/1)";

AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];

[manager GET:url

         parameters:nil

         progress:^(NSProgress * _Nonnull downloadProgress)

         {

         }

         success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject)

         {

             NSLog(@"这里打印请求成功要做的事");

             // 获取所有数据报头信息

             NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)task.response;

             NSDictionary *fields = [HTTPResponse allHeaderFields];// 原生NSURLConnection写法

             NSLog(@"fields = %@", [fields description]);

             // 获取cookie方法1

             NSArray *cookies = [NSHTTPCookiecookiesWithResponseHeaderFields:fields forURL:[NSURLURLWithString:url]];

             for(NSHTTPCookie *cookie in cookies)

             {

                 NSLog(@"cookie1 -> %@", cookie);

             }

             // 获取cookie方法2

             NSString *cookieString = [[HTTPResponse allHeaderFields] valueForKey:@"Set-Cookie"];

             NSLog(@"cookie2 -> %@", cookieString);

             // 获取cookie方法3

             NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStoragesharedHTTPCookieStorage];

             for(NSHTTPCookie *cookie in [cookieJar cookies])

             {

                 NSLog(@"cookie3 -> %@", cookie);

             }

         }

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

         {

             NSLog(@"%@",error);// 这里打印错误信息

         }];

2> POST请求:

AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
NSMutableDictionary *parameters = @{@"":@"", @"":@""};
[manager POST:URL
         parameters:parameters
         progress:^(NSProgress * _Nonnull uploadProgress)
         {
         }
         success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject)
         {
         }
         failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error)
         {
         }];

3> 下载

// 1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
manage.requestSerializer = [AFHTTPRequestSerializerserializer];
manage.requestSerializer.stringEncoding = NSUTF8StringEncoding;
manage.requestSerializer.timeoutInterval = 10;
manage.responseSerializer = [AFHTTPResponseSerializerserializer];
manage.responseSerializer.stringEncoding = NSUTF8StringEncoding;
manage.responseSerializer.acceptableContentTypes = [NSSetsetWithObject:@"text/html"];
// 2.确定请求的URL地址
NSURL *url = [NSURLURLWithString:@""];
// 3.创建请求对象
NSURLRequest *request = [NSURLRequestrequestWithURL: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 [NSURLURLWithString:filePath];
                                          }
                                          completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error)
                                          {
                                              // 下载完成调用的方法
                                              NSLog(@"下载完成:");
                                              NSLog(@"%@--%@",response,filePath);
                                          }];
// 开始启动任务
[task resume];

4> 上传
第一种方法是通过工程中的文件进行上传

// 1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
// 2.上传文件
NSDictionary *dict = @{@"":@""};
NSString *urlString = @"";
[manager POST:urlString
         parameters:dict
         constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData)
         {
             // 上传文件参数
             UIImage *iamge = [UIImageimageNamed:@"123.png"];
             NSData *data = UIImagePNGRepresentation(iamge);
             // 这个就是参数
             [formData appendPartWithFileData:data name:@"file"fileName:@"123.png"mimeType:@"image/png"];
         }
         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);
         }];

第二种是通过URL来获取路径,进入沙盒或者系统相册等等

// 1.创建管理者对象
AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];
// 2.上传文件
NSDictionary *dict = @{@"":@""};
NSString *urlString = @"";
[manager POST:urlString
         parameters:dict
         constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData)
         {
             [formData appendPartWithFileURL:[NSURLfileURLWithPath:@"文件地址"] 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);
        }];

5> 设置 Cookie 中的值

方法1:

AFHTTPSessionManager *manager = [AFHTTPSessionManagermanager];

[manager.requestSerializersetHTTPShouldHandleCookies:YES];

[manager.requestSerializer setValue:[NSString stringWithFormat:@"%@=%@", [cookie name], [cookie value]] forHTTPHeaderField:@"Cookie"];

方法2:

NSMutableDictionary *cookieProperties = [NSMutableDictionarydictionary];

[cookieProperties setObject:@"username"forKey:NSHTTPCookieName];

[cookieProperties setObject:@"my ios cookie"forKey:NSHTTPCookieValue];

[cookieProperties setObject:@"[api.skyfox.org](http://api.skyfox.org/)"forKey:NSHTTPCookieDomain];

[cookieProperties setObject:@"[api.skyfox.org](http://api.skyfox.org/)"forKey:NSHTTPCookieOriginURL];

[cookieProperties setObject:@"/"forKey:NSHTTPCookiePath];

[cookieProperties setObject:@"0"forKey:NSHTTPCookieVersion];

[cookieProperties setObject:[NSDatedateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];//设置失效时间

[cookieProperties setObject:@"0"forKey:NSHTTPCookieDiscard]; //设置sessionOnly

NSHTTPCookie *cookie = [NSHTTPCookiecookieWithProperties:cookieProperties];

[[NSHTTPCookieStoragesharedHTTPCookieStorage] setCookie:cookie];

6> 清空Cookie

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStoragesharedHTTPCookieStorage];
NSArray *cookieArray = [NSArrayarrayWithArray:[cookieJar cookies]];
for(id obj in cookieArray)
{
    [cookieJar deleteCookie:obj];
}

7> Cookie的本地缓存策略

// NSHTTPCookieAcceptPolicyAlways: 保存所有cookie,这个是默认值
// NSHTTPCookieAcceptPolicyNever: 不保存任何响应头中的cookie
// NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: 只保存域请求匹配的cookie
[[NSHTTPCookieStoragesharedHTTPCookieStorage]setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];

8> 手动保存和加载 Cookie

// 保存Cookie
- (void)saveCookies
{
    NSData *cookiesData = [NSKeyedArchiverarchivedDataWithRootObject:[[NSHTTPCookieStoragesharedHTTPCookieStorage] cookies]];
    NSUserDefaults *defaults = [NSUserDefaultsstandardUserDefaults];
    [defaults setObject:cookiesData forKey:@"org.skyfox.cookie"];
    [defaults synchronize];
}

// 加载Cookie 一般都是app刚刚启动的时候
- (void)loadCookies
{
    NSArray *cookies = [NSKeyedUnarchiverunarchiveObjectWithData:[[NSUserDefaultsstandardUserDefaults] objectForKey:@"org.skyfox.cookie"]];
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStoragesharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in cookies)
    {
        [cookieStorage setCookie:cookie];
    }
}

9> 检查网络状态

(1)开启网络监听,一般在程序启动时调用,可以放在 AppDelegate 中
              [[AFNetworkReachabilityManagersharedManager] startMonitoring];
    (2)在需要监测网络的地方调用该方法去获取当前网络状态
        AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManagersharedManager];
         //  枚举里面四个状态  分别对应未知无网络数据 WiFi
         //  typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
        //      AFNetworkReachabilityStatusUnknown          = -1,  未知
         //      AFNetworkReachabilityStatusNotReachable     = 0,   无网络
        //      AFNetworkReachabilityStatusReachableViaWWAN = 1,   蜂窝数据网络
         //      AFNetworkReachabilityStatusReachableViaWiFi = 2,   WiFi
        //  };
        [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
                 {
                     // 这里是监测到网络改变的block
                     switch (status)
                     {
                         caseAFNetworkReachabilityStatusUnknown:
                             NSLog(@"未知网络状态");
                         break;
                         caseAFNetworkReachabilityStatusNotReachable:
                             NSLog(@"无网络");
                         break;
                         caseAFNetworkReachabilityStatusReachableViaWWAN:
                             NSLog(@"蜂窝数据网");
                         break;
                         caseAFNetworkReachabilityStatusReachableViaWiFi:
                             NSLog(@"WiFi网络");
                         break;
                         default:
                         break;
                     }
                 }];

注:如果启动就去检测有可能得到的是 status == AFNetworkReachabilityStatusUnknown,建议延迟在调用或者 在收到监听网络状态回调以后再取