AFNetWorking用法及缓存处理

作者: 26b5cc676194 | 来源:发表于2017-05-03 10:18 被阅读485次

    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请求使用流程就完成了。

    相关文章

      网友评论

        本文标题:AFNetWorking用法及缓存处理

        本文链接:https://www.haomeiwen.com/subject/arlktxtx.html