美文网首页
基于AFNetworking封装的网络层(一站式解析数据)

基于AFNetworking封装的网络层(一站式解析数据)

作者: huangxiongbiao | 来源:发表于2017-05-12 11:50 被阅读229次

代码地址: https://github.com/huangxiongbiao12/BGNetworking

1、封装AFNetworking基本请求方法

封装原因:当AFNetworking的api改变的时候只需要更改封装的方法,无需大面积改动代码(不封装直接用AFNetworking请求如果AFNetworking的api变化所有用的地方都需要变化)

代码依赖了MBProgressHUD,显示加载图

封装思路接口:
1、主要封装了Get Post请求带HUD和不带HUD的另外一个可以选择是否带HUD的接口
2、将上传图片的单独封装
3、封装了https加载证书验证的方法,只需要设置cer文件的路径名称,以及是否需要https验证

代码如下:
api

#import <Foundation/Foundation.h>
#import "NetStatusData.h"

@interface HttpRequstData : NSObject

+ (void)getUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)getNoHUDUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)postUrl:(NSString*)url parameters:(NSDictionary*)parameters showHUD:(BOOL)show success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)postUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)postNoHUDUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+ (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

+ (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
              constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
                               progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

@end

实现

#import "HttpRequstData.h"

/**
 *  是否开启https SSL 验证
 *
 *  @return YES为开启,NO为关闭
 */
#define openHttpsSSL YES
/**
 *  SSL 证书名称,仅支持cer格式。“app.bishe.com.cer”,则填“app.bishe.com”
 */
#define certificate @"public"

typedef NS_ENUM(NSInteger,HttpType) {
    GET,
    POST
};

static int timeOut = 30;

@interface HttpRequstData ()
{
    NSString *_url;
    NSDictionary *_parameters;
   
}
@property(nonatomic,strong)UILabel *tipsLable;

@end

@implementation HttpRequstData

+(void)getUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure
{
    [[NetStatusData shareNetStatus] checkNetStatus];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = timeOut;
    // 加上这行代码,https ssl 验证。
    if(openHttpsSSL)
    {
        [manager setSecurityPolicy:[self customSecurityPolicy]];
    }
    [MBProgressHUD showMessage:@"加载中..."];
     DDLog(@"parameters:%@",parameters);
    [manager GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        DDLog(@"====%@,%@==url:%@",responseObject,parameters,url);
        [MBProgressHUD hideHUD];
        //登陆成功===================================
        if ([responseObject[@"status"] isEqualToNumber:@500]) {
            [MBProgressHUD showSuccess:@"加载成功"];
            if (success) {
                success(responseObject);
            }
        }else{//登陆失败=============================
            if ([responseObject[@"data"] isKindOfClass:[NSString class]]) {
                [MBProgressHUD showError:responseObject[@"data"]];
            }else{
                [MBProgressHUD showError:@"信息错误"];
            }
            NSError *error1;
            failure(error1);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //         [[NetWorkingStausTipLabel shareNetWorkingStausTipLabel] showDuration:2.0];
        [MBProgressHUD hideHUD];
        [MBProgressHUD showError:@"网络异常"];
        DDLog(@"%s==error--%@",__func__,error);
        if (error) {
            failure(error);
        }

    }];
}

+(void)getNoHUDUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure {
    [[NetStatusData shareNetStatus] checkNetStatus];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = timeOut;
    // 加上这行代码,https ssl 验证。
    if(openHttpsSSL)
    {
        [manager setSecurityPolicy:[self customSecurityPolicy]];
    }
    DDLog(@"parameters:%@",parameters);
    [manager GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        DDLog(@"====%@,%@==url:%@",responseObject,parameters,url);
         [MBProgressHUD hideHUD];
        //登陆成功===================================
        if ([responseObject[@"status"] isEqualToNumber:@500]) {
            if (success) {
                success(responseObject);
            }
        }else{//登陆失败=============================
            if ([responseObject[@"data"] isKindOfClass:[NSString class]]) {
                [MBProgressHUD showError:responseObject[@"data"]];
            }else{
                [MBProgressHUD showError:@"信息错误"];
            }
            NSError *error1;
            failure(error1);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //         [[NetWorkingStausTipLabel shareNetWorkingStausTipLabel] showDuration:2.0];
        DDLog(@"%s==error--%@",__func__,error);
        [MBProgressHUD hideHUD];
        [MBProgressHUD showError:@"网络异常"];
        if (error) {
            failure(error);
        }
        
    }];
}

#pragma mark-------封装请求
+(void)postUrl:(NSString*)url parameters:(NSDictionary*)parameters showHUD:(BOOL)show success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure {
    [[NetStatusData shareNetStatus] checkNetStatus];
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer.timeoutInterval = timeOut;
    // 加上这行代码,https ssl 验证。
    if(openHttpsSSL)
    {
        [manager setSecurityPolicy:[self customSecurityPolicy]];
    }
    if (show) {
        [MBProgressHUD showMessage:@"加载中..."];
    }
    DDLog(@"parameters:%@==url:%@==",parameters,url);
    
    [manager POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        DDLog(@"====%@,%@==url:%@===parameters:%@",responseObject,responseObject[@"data"],url,parameters);
        if (show) {
            [MBProgressHUD hideHUD];
        }
        //登陆成功===================================
        if ([responseObject[@"status"] isEqualToNumber:@500]) {
            if ([responseObject[@"data"] isKindOfClass:[NSArray class]]) {
                if ([responseObject[@"data"] count] < 1) {
                    //                    [MBProgressHUD showSuccess:@"没有更多数据"];
                }else{
                    if (show) {
                        //                        [MBProgressHUD showSuccess:@"加载成功"];
                    }
                }
            }else{
                if (show) {
                    //                    [MBProgressHUD showSuccess:@"加载成功"];
                }
            }
            if (success) {
                success(responseObject);
            }
        }else{//登陆失败=============================
            if ([responseObject[@"data"] isKindOfClass:[NSString class]]) {
                //                if (show) {
                [MBProgressHUD showError:responseObject[@"data"]];
                //                }
            }else{
                //                if (show) {
                [MBProgressHUD showError:@"信息错误"];
                //                }
            }
            NSError *error1;
            failure(error1);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //         [[NetWorkingStausTipLabel shareNetWorkingStausTipLabel] showDuration:2.0];
        if (show) {
            [MBProgressHUD hideHUD];
        }
        //        [MBProgressHUD showError:@"请求失败"];
        DDLog(@"%s==error--%@",__func__,error);
        if (error) {
            failure(error);
        }
    }];
}


+(void)postUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure
{
    [self postUrl:url parameters:parameters showHUD:YES success:success failure:failure];
}

+(void)postNoHUDUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure
{
    [self postUrl:url parameters:parameters showHUD:NO success:success failure:failure];
}


#pragma mark-------上传图片

+(NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block progress:(void (^)(NSProgress *))uploadProgress success:(void (^)(NSURLSessionDataTask *, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError *))failure {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    // 加上这行代码,https ssl 验证。
    if(openHttpsSSL)
    {
        [manager setSecurityPolicy:[self customSecurityPolicy]];
    }
    return [manager POST:URLString parameters:parameters constructingBodyWithBlock:block progress:uploadProgress success:success failure:failure];
}

+(NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id<AFMultipartFormData>))block success:(void (^)(NSURLSessionDataTask *, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError *))failure {
    return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure];
}

#pragma mark========https

+ (AFSecurityPolicy*)customSecurityPolicy
{
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:certificate ofType:@"cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//    AFSSLPinningModeNone、AFSSLPinningModeCertificate
    // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO
    // 如果是需要验证自建证书,需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    
    //validatesDomainName 是否需要验证域名,默认为YES;
    //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
    //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
    //如置为NO,建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
    
    securityPolicy.pinnedCertificates = [[NSSet alloc] initWithObjects:certData,nil];
    return securityPolicy;
}

2、封装网络状态监测

思路:用了一个单例,每次请求接口的时候调用小网络状态监测api
根据不同的网络情况显示提示

#import <Foundation/Foundation.h>

@interface NetStatusData : NSObject

@property(nonatomic,assign)AFNetworkReachabilityStatus status;//网络状态

+(NetStatusData*)shareNetStatus;

-(void)checkNetStatus;//检查网络状态

@end
static NetStatusData *_netStatus = nil;

@implementation NetStatusData

+(NetStatusData *)shareNetStatus {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (!_netStatus) {
            _netStatus = [NetStatusData new];
        }
    });
    return _netStatus;
}

-(void)checkNetStatus {
    AFNetworkReachabilityManager *manager=[AFNetworkReachabilityManager sharedManager];
    __weak AFNetworkReachabilityManager *weakManager = manager;
    [manager startMonitoring];
    //检测网络状态有网络,网络请求数据,没网络提示
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        self.status = status;
        if (!status) {//未连接
            UIWindow *window = [[UIApplication sharedApplication].windows lastObject];
            UILabel *tipsLable;
            if (!tipsLable) {
                tipsLable = [[UILabel alloc] initWithFrame:(CGRect){kScreenWidth/2,kScreenHeight/2+80,110,33}];
                tipsLable.textColor = [UIColor whiteColor];
                tipsLable.textAlignment = NSTextAlignmentCenter;
                tipsLable.centerX = window.centerX;
                tipsLable.backgroundColor = [UIColor blackColor];
                tipsLable.text = @"网络未连接";
            }
            [window addSubview:tipsLable];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [tipsLable removeFromSuperview];
            });
            
            return;
        }else{//连接请求数据
            //            [self requstData:type];
        }
        [weakManager stopMonitoring];
    }];
}

@end

3、数据解析层(核心思想)

注:利用基类做类别封装请求,可以直接用模型请求接口,并且封装解析过程。根据不同的模型及json类型动态解析数据。后期代码免去解析代码

代码分为两部分,一部分代码解析,一部分数据请求

1、数据请求

#import <Foundation/Foundation.h>

@interface NSObject (Request)
//请求数据
+(void)requestUrl:(NSString*)url parameters:(NSDictionary*)parameters showHUD:(BOOL)show success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)requestUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;

+(void)requestNoHUDUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure;
//解析数据
+(id)parseData:(id)responseObject;
//对象转json
-(NSDictionary*)toJson;
//获取属性的类型
+(NSString*)getPropertyType:(NSString*)property;
-(NSString*)getPropertyType:(NSString*)property;

@end
#import "NSObject+Request.h"
#import <objc/runtime.h>

@implementation NSObject (Request)

+(void)requestUrl:(NSString*)url parameters:(NSDictionary*)parameters showHUD:(BOOL)show success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure {
    [HttpRequstData postUrl:url parameters:parameters showHUD:show success:^(id responseObject) {
        id obj = [self parseData:responseObject[@"data"]];
        success(obj);
    } failure:^(NSError *error) {
        failure(error);
    }];
}

+(void)requestUrl:(NSString*)url parameters:(NSDictionary*)parameters success:(void(^)(id responseObject)) success failure:(void(^)(NSError *error)) failure {
    [self requestUrl:url parameters:parameters showHUD:YES success:success failure:failure];
}

+(void)requestNoHUDUrl:(NSString *)url parameters:(NSDictionary *)parameters success:(void (^)(id))success failure:(void (^)(NSError *))failure {
    [self requestUrl:url parameters:parameters showHUD:NO success:success failure:failure];
}

+(id)parseData:(id)responseObject {
    
    id obj;
    //单个对象
    if ([responseObject isKindOfClass:[NSDictionary class]]) {
        obj = [[self alloc]init];
        [obj setValuesForKeysWithDictionary:responseObject];
    }
    //        多个对象
    else if ([responseObject isKindOfClass:[NSArray class]]) {
        obj = [NSMutableArray new];
        for (NSDictionary *dic in responseObject) {
            id o = [[self alloc]init];
            [o setValuesForKeysWithDictionary:dic];
            [obj addObject:o];
        }
    }
    return obj;
}

-(NSDictionary *)toJson
{
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    unsigned  int count = 0;
    Ivar *ivars = class_copyIvarList(self.class, &count);
    for (int i = 0; i < count; i++) {
        const char *cname = ivar_getName(ivars[i]);
        NSString *name = [NSString stringWithUTF8String:cname];
        NSString *key = [name substringFromIndex:1];
        id value = [self valueForKey:key];
        if ([value isKindOfClass:[NSString class]]&&[(NSString*)value length]) {
            [params setValue:value forKey:key];
        }
    }
    return params;
}

#pragma mark-------//获取属性的类型

+(NSString *)getPropertyType:(NSString *)property {
    //获取对象的类型objc_getClass("UserModel")
    objc_property_t p = class_getProperty(self, property.UTF8String);
  if (!p) {
        return nil;
    }
    const char *cname = property_getAttributes(p);
    DDLog(@"%s==",cname);
    // 2.成员类型
    NSString *attrs = @(property_getAttributes(p));
    NSUInteger dotLoc = [attrs rangeOfString:@","].location;
    NSString *code = nil;
    NSUInteger loc = 3;
    if (dotLoc == NSNotFound) { // 没有,
        code = [attrs substringFromIndex:loc];
    } else {
        code = [attrs substringWithRange:NSMakeRange(loc, dotLoc - loc-1)];
    }
    DDLog(@"%@===%@====",code,attrs);
    return code;
}

-(NSString *)getPropertyType:(NSString *)property {
    //获取对象的类型objc_getClass("UserModel")
    objc_property_t p = class_getProperty(self.class, property.UTF8String);
  if (!p) {
        return nil;
    }
    const char *cname = property_getAttributes(p);
    DDLog(@"%s==",cname);
    // 2.成员类型
    NSString *attrs = @(property_getAttributes(p));
    NSUInteger dotLoc = [attrs rangeOfString:@","].location;
    NSString *code = nil;
    NSUInteger loc = 3;
    if (dotLoc == NSNotFound) { // 没有,
        code = [attrs substringFromIndex:loc];
    } else {
        code = [attrs substringWithRange:NSMakeRange(loc, dotLoc - loc-1)];
    }
    DDLog(@"%@===%@====",code,attrs);
    return code;
}


@end
2、数据解析

思路:通过kvc解析数据,判断json的key值是否是json和数组是的话进一步解析。不是的话直接赋值,解决复杂类型的json动态解析。
注意:数据字段的时候需要指明数据放的对象类型

使用时需要解析的模型类需要继承Model类

/*
 *对象中含有的模型数据对应的对象名称例如
 *@{
    @"statuses" : @"Status",===字段有statuses的数组含有的对象为Status类型
 *};
 */
@property(nonatomic,strong)NSDictionary *classInArrayDic;

代码如下

#import <Foundation/Foundation.h>
#import "NSObject+Request.h"

@interface Model : NSObject<NSCoding,NSCopying>

//对象转json
-(NSDictionary*)toJson;
/*
 *对象中含有的模型数据对应的对象名称例如
 *@{
    @"statuses" : @"Status",===字段有statuses的数组含有的对象为Status类型
 *};
 */
@property(nonatomic,strong)NSDictionary *classInArrayDic;

@end
#import "Model.h"

@implementation Model

-(void)setValue:(id)value forKey:(NSString *)key{
    
    if ([value isKindOfClass:[NSNumber class]]) {
        [self setValue:[NSString stringWithFormat:@"%@",value] forKey:key];
    }else if ([value isKindOfClass:[NSArray class]]) {
        
    }else{
        if (!value||[value isKindOfClass:[NSNull class]]) {
            [super setValue:@"" forKey:key];
        }else{
            [super setValue:value forKey:key];
        }
    }
}

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    
        if ([key isEqualToString:@"description"]) {
            [self setValue:value forKey:@"descriptionStr"];
        }else if ([key isEqualToString:@"id"]){
            [self setValue:value forKey:@"Id"];
        }else if([key isEqualToString:@"newPrice"]){
            [self setValue:value forKey:@"price"];
        }else if([key isEqualToString:@"code"]){
            [self setValue:value forKey:@"codePara"];
        }else{
            DDLog(@"没有key==%@",key);
        }
}

-(void)setValuesForKeysWithDictionary:(NSDictionary<NSString *,id> *)keyedValues {
    for (NSString *key in keyedValues) {
        id value = keyedValues[key];
        //对象中含有对象数组
        if ([value isKindOfClass:[NSArray class]]) {
            if (![self.classInArrayDic objectForKey:key]) {
                DDLog(@"请给数组对象对应类型");
                continue;
            }
            //设置数组的值
            NSMutableArray *values = [NSMutableArray new];
            //取出数组含有对象类型
            Class ObjectType = NSClassFromString(self.classInArrayDic[key]);
            DDLog(@"%@",ObjectType);
            for (NSDictionary *dic in value) {
                 //获取对象类型生成实例
                id obj = [[ObjectType alloc]init];
                [obj setValuesForKeysWithDictionary:dic];
                [values addObject:obj];
            }
            [self setValue:values forKey:key];
        }else if ([value isKindOfClass:[NSDictionary class]]) {//对象中含有对象
            //获取对象的类型
            NSString *type = [self getPropertyType:key];
            if (type.length) {
                DDLog(@"请给对象对应类型");
                continue;
            }
            //获取对象类型生成实例
            Class ObjectType = NSClassFromString(type);
            id obj = [[ObjectType alloc]init];
            [obj setValuesForKeysWithDictionary:value];
            [self setValue:obj forKey:key];
        }else {
            [self setValue:value forKey:key];
        }
    }
}

-(NSDictionary *)toJson
{
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    unsigned  int count = 0;
    Ivar *ivars = class_copyIvarList(self.class, &count);
    for (int i = 0; i < count; i++) {
        const char *cname = ivar_getName(ivars[i]);
        NSString *name = [NSString stringWithUTF8String:cname];
        NSString *key = [name substringFromIndex:1];
        id value = [self valueForKey:key];
        if ([value isKindOfClass:[NSString class]]&&[(NSString*)value length]) {
            [params setValue:value forKey:key];
        }
    }
    return params;
}

#pragma mark-------NSCoding,归接档协议,运行时

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    unsigned  int count = 0;
    Ivar *ivars = class_copyIvarList(self.class, &count);
    for (int i = 0; i < count; i++) {
        const char *cname = ivar_getName(ivars[i]);
        NSString *name = [NSString stringWithUTF8String:cname];
        NSString *key = [name substringFromIndex:1];
        id value = [self valueForKey:key];
        [aCoder encodeObject:value forKey:key];
    }
    
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        
        unsigned  int count = 0;
        Ivar *ivars = class_copyIvarList(self.class, &count);
        
        for (int i = 0; i < count; i++) {
            const char *cname = ivar_getName(ivars[i]);
            NSString *name = [NSString stringWithUTF8String:cname];
            NSString *key = [name substringFromIndex:1];
            id value = [aDecoder decodeObjectForKey:key];
            [self setValue:value forKey:key];
        }
    }
    return self;
}

-(id)copyWithZone:(NSZone *)zone {
    id copy = [[[self class] allocWithZone:zone] init];
    unsigned  int count = 0;
    Ivar *ivars = class_copyIvarList(self.class, &count);
    
    for (int i = 0; i < count; i++) {
        const char *cname = ivar_getName(ivars[i]);
        NSString *name = [NSString stringWithUTF8String:cname];
        NSString *key = [name substringFromIndex:1];
        id value = [self valueForKey:key];
        [copy setValue:value forKey:key];
    }
    return copy;
}


@end

相关文章

网友评论

      本文标题:基于AFNetworking封装的网络层(一站式解析数据)

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