美文网首页
对AFNetWorking进行二次封装

对AFNetWorking进行二次封装

作者: 骑蜗牛兜风 | 来源:发表于2017-08-29 16:39 被阅读36次

    预期效果:方便、简单调用,能够定位具体的请求并cancel;
    思路:类A做具体的请求事件,类B调用类A处理一些业务逻辑:网络或者数据的加工等。


    定义类A:QYNetwork 处理具体的请求

    • 单列模式,方便调用
    + (instancetype)sharedInstance {
        static dispatch_once_t onceToken;
        static QYNetwork *sharedInstance = nil;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[QYNetwork alloc] init];
        });
        return sharedInstance;
    }
    
    • 发起请求
    - (NSInteger)callGETWithParams:(NSDictionary *)params
                        methodName:(NSString *)methodName
                           success:(CallBackBlock)success
                              fail:(CallBackBlock)fail {
        __block NSURLSessionDataTask *dataTask = nil;
        
        kWeakSelf(self);
        dataTask = [self.sessionManager GET:methodName parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            kStrongSelf(self);
            
            ///请求完成---移除
            [self.dispatchTable removeObjectForKey:@([dataTask taskIdentifier])];
            
            [self processingResponseObject:responseObject success:success fail:fail];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            kStrongSelf(self);
            
            [self.dispatchTable removeObjectForKey:@([dataTask taskIdentifier])];
            
            [self processingError:error fail:fail];
        }];
        
        self.dispatchTable[@([dataTask taskIdentifier])] = dataTask;
        return dataTask.taskIdentifier;
    }
    
    

    以task的taskIdentifier作为键保存task,方便针对单个的请求进行cancel,请求完成后remove掉;在请求回调里面进行数据的解析和错误的预处理;

    ///对API返回的数据进行初始判断
    - (void)processingResponseObject:(id)responseObject
                             success:(CallBackBlock)success
                                fail:(CallBackBlock)fail {
        
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
        
        //TODO:解析code,返回具体数据,具体业务具体处理
        NSInteger code = [json[@"code"] integerValue];
        if (code == 200) {
            !success ?: success(code, json);
        }else {
            !fail ?: fail(code,json[@"message"]);
        }
    }
    
    ///处理错误事件
    - (void)processingError:(NSError *)error
                       fail:(CallBackBlock)fail {
        //TODO:提示
        if (error.code == NSURLErrorTimedOut) {
            //超时
            !fail ?: fail(error.code,@"超时");
        }else if (error.code == NSURLErrorCancelled){
            //取消
    
        }else if (error.code == NSURLErrorNetworkConnectionLost){
            //网络
            !fail ?: fail(error.code,@"无网络");
        }
        //...
    }
    
    • 请求cancel,根据tast的taskIdentifier取消task
    - (void)cancelRequestWithRequestID:(NSNumber *)requestID {
       NSURLSessionDataTask *requestOperation = self.dispatchTable[requestID];
       [requestOperation cancel];
       [self.dispatchTable removeObjectForKey:requestID];
    }
    

    定义类QYNetManager 让上层调用

    • 单列模式,方便调用
    + (instancetype)sharedInstance {
        static dispatch_once_t onceToken;
        static QYNetManager *sharedInstance = nil;
        dispatch_once(&onceToken, ^{
            sharedInstance = [[QYNetManager alloc] init];
        });
        return sharedInstance;
    }
    
    • 定义请求的类型:get、post...
    • 网络的监听,AFNetWorking自带,这里用RealReachability
    • 上层的调用,返回task的taskIdentifier,业务层可以自处理
    - (NSInteger)loadDataWithParameters:(NSDictionary *)parameters
                                   path:(NSString *)path
                             methodType:(QYRequestType)methodType
                                success:(successBlock)success
                                failure:(failureBlock)failure {
        NSInteger requestId = 0;
        
        if ([self isReachability]) {//网络状态
            switch (methodType) {
                case QYRequestType_GET:
                    QYCallAPI(GET,requestId);
                    break;
                    
                case QYRequestType_POST:
                    QYCallAPI(POST,requestId);
                    break;
                    
                default:
                    break;
            }
        }
        
        return requestId;
    }
    

    定义的宏:

    #define QYCallAPI(REQUEST_METHOD, REQUEST_ID)                                                   \
    {                                                                                               \
    REQUEST_ID = [[QYNetwork sharedInstance] call##REQUEST_METHOD##WithParams:parameters methodName:path success:^(NSInteger code,id responseObject) {                                                          \
    success(responseObject);\
    } fail:^(NSInteger code,id responseObject) {                                                                                 \
    failure(responseObject);\
    }];                                                                                         \
    [self.requestIdList addObject:@(REQUEST_ID)];                                               \
    }
    

    Demo

    相关文章

      网友评论

          本文标题:对AFNetWorking进行二次封装

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