美文网首页
iOS封装AFN的Para参数(仿Masonry)

iOS封装AFN的Para参数(仿Masonry)

作者: _moses | 来源:发表于2019-04-25 00:29 被阅读0次

    一般我们封装AFN,大多都是这个样子

    @interface MSNetwork : AFHTTPSessionManager
    
    + (void)POST:(NSString *)url
            para:(NSDictionary *)para
         success:(void (^)(NSDictionary *dict))success
         failure:(void (^)(NSError *error))failure;
    
    @end
    
    @implementation MSNetwork
    
    + (void)POST:(NSString *)url
            para:(NSDictionary *)para
         success:(void (^)(NSDictionary *dict))success
         failure:(void (^)(NSError *error))failure {
    
        MSNetwork *network = [MSNetwork new];
        network.requestSerializer = [AFHTTPRequestSerializer serializer];
        network.responseSerializer = [AFJSONResponseSerializer serializer];
        [network.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        network.requestSerializer.timeoutInterval = 10;
        [network.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        [network POST:url parameters:para progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success) {
                success(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(error);
            }
        }];
    }
    
    @end
    

    控制器调用的时候这样写

    // 后台需要的参数为name、age、sex、score
    [MSNetwork POST:@"login" para:@{@"name":@"moses",@"age":@18,@"sex":@"男",@"score"@6.66} success:^(NSDictionary *dict) {
        
    } failure:^(NSError *error) {
        
    }];
    

    用多了Masonry就总会闪现一些奇思妙想:用Masonry的链式编程方式将参数字典para传给AFN

    @interface MSNetwork : AFHTTPSessionManager
    
    + (void)POST:(NSString *)url
            para:(void (^)(MSModel *model))para
         success:(void (^)(NSDictionary *dict))success
         failure:(void (^)(NSError *error))failure;
    
    @end
    
    @implementation MSNetwork
    
    + (void)POST:(NSString *)url
            para:(void (^)(MSModel *model))para
         success:(void (^)(NSDictionary *dict))success
         failure:(void (^)(NSError *error))failure {
        NSMutableDictionary *dict;
        if (para) {
            MSModel *model = [MSModel new];
            para(model);
            dict = [model valueForKey:@"_paraDict"];
        }
        NSLog(@"%@", dict);
        MSNetwork *network = [MSNetwork new];
        network.requestSerializer = [AFHTTPRequestSerializer serializer];
        network.responseSerializer = [AFJSONResponseSerializer serializer];
        [network.requestSerializer willChangeValueForKey:@"timeoutInterval"];
        network.requestSerializer.timeoutInterval = 10;
        [network.requestSerializer didChangeValueForKey:@"timeoutInterval"];
        [network POST:url parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success) {
                success(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(error);
            }
        }];
    }
    
    @end
    
    @interface MSModel : NSObject
    
    @property(nonatomic,copy,readonly) MSModel *(^string_name)(NSString *name);
    @property(nonatomic,copy,readonly) MSModel *(^integer_age)(NSInteger age);
    @property(nonatomic,copy,readonly) MSModel *(^float_score)(CGFloat score);
    @property(nonatomic,copy,readonly) MSModel *(^string_sex)(NSString *sex);
    
    @end
    
    #import <objc/runtime.h>
    
    @interface MSModel () {
        NSMutableDictionary *_paraDict;
    }
    
    @end
    
    @implementation MSModel
    
    - (instancetype)init {
        if (self = [super init]) {
            _paraDict = [NSMutableDictionary dictionary];
        }
        return self;
    }
    
    + (void)load {
        unsigned int propertyCount = 0;
        objc_property_t *propertyList = class_copyPropertyList([self class], &propertyCount);
        for (unsigned int i = 0; i < propertyCount; i++) {
            NSString * propertyName = [NSString stringWithUTF8String:property_getName(propertyList[i])];
            if ([propertyName hasPrefix:@"string_"]) {
                class_replaceMethod([self class], NSSelectorFromString(propertyName), (IMP)ms_stringMethod, "@@:");
            } else if ([propertyName hasPrefix:@"integer_"]) {
                class_replaceMethod([self class], NSSelectorFromString(propertyName), (IMP)ms_integerMethod, "@@:");
            } else if ([propertyName hasPrefix:@"float_"]) {
                class_replaceMethod([self class], NSSelectorFromString(propertyName), (IMP)ms_floatMethod, "@@:");
            } else {
                NSAssert(0, @"属性名需要按规则命名");
            }
        }
    }
    
    static id ms_stringMethod(id self, SEL _cmd) {
        return [self getString:[NSStringFromSelector(_cmd) substringFromIndex:7]];
    }
    
    - (MSModel *(^)(NSString *))getString:(NSString *)property {
        return ^(NSString *value) {
            [_paraDict setValue:value forKey:property];
            return self;
        };
    }
    
    static id ms_integerMethod(id self, SEL _cmd) {
        return [self getInteger:[NSStringFromSelector(_cmd) substringFromIndex:8]];
    }
    
    - (MSModel *(^)(NSInteger))getInteger:(NSString *)property {
        return ^(NSInteger value) {
            [_paraDict setValue:@(value) forKey:property];
            return self;
        };
    }
    
    static id ms_floatMethod(id self, SEL _cmd) {
        return [self getFloat:[NSStringFromSelector(_cmd) substringFromIndex:6]];
    }
    
    - (MSModel *(^)(CGFloat))getFloat:(NSString *)property {
        return ^(CGFloat value) {
            [_paraDict setValue:@(value) forKey:property];
            return self;
        };
    }
    
    @end
    

    控制器调用的时候这样写

    // 后台需要的参数为name、age、sex、score
    [MSNetwork POST:@"login" para:^(MSModel *model) {
        model.string_name(@"moses").integer_age(18).string_sex(@"男").float_score(6.66);
    } success:^(NSDictionary *dict) {
        
    } failure:^(NSError *error) {
        
    }];
    
    1. 后台需要什么参数,只管在MSModel.h中添加属性即可,不必关心MSModel.m的实现
    2. (如果觉得string_、integer_、float_这三个前缀碍眼,也可以去掉,只不过需要传进来的参数全部为NSString类型,传的时候需要稍微转换一下)

    相关文章

      网友评论

          本文标题:iOS封装AFN的Para参数(仿Masonry)

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