AFNetworking3.0的封装

 AFNetworking在iOS网络请求第三方库中占据着半壁江山,前段时间将AFNetworking进行了3.0版本的迁移,运用面向对象的设计将代码进行封装整合,这篇文章主要为还在寻找AFNetworking集成代码或者准备3.0迁移的各位童鞋们提供思路,同时自定义了字典模型转换方法,需要的朋友也可以作为参考,还望各位老司机批评指正!先上代码框架图:

1、DB数据访问层,在AFNetworkingManager中我将AFNetworking的GET/POST/DELETE/PUT方法封装,提供了以下接口:
  AFNetworking封装

针对AFNetworking底层封装AFNetworkingManager后,是不是就可以直接在Service调用GET/POST/DELETE/PUT接口访问数据了呢?理论上是完全可以的,但是我们在实际开发中往往还需要自定义或者个性化一些效果如菊花等待框、阴影效果,提示文案等,所以本人建议在AFNetworkingManager基础上再包装一层专门用于Service对接,这样的好处是Service层完全不必关心AFNetworking的封装实现和序列化、授权等等问题,这样也便于后续的维护与版本的升级,好了我们再看看对接Service的ZTHttpManager:

  ZTHttpManager封装

好了,在这里完成了DB层的代码,访问API就毫无压力了!

2、模型基类JsonCommonResultBase/SerializationBaseModel

在这里我要说明一点,这里的模型基类是按照我们公司后台返回的API格式自定义,不一定适合每个人,但是可以作为各位的参考,具体的API返回数据结构为:

  API返回200数据格式

针对上述的数据格式,自定义的模型基类如下(BTW这里多层级的数据转化也是毫无压力的,完全OK):

  序列化model基类 需要继承NSCopying
  返回数据基类与具体实现子类
 
那么重点来了,我们知道AFNetworking调用API后返回的数据格式流为:NSData -> NSDictionary ,我们需要先将responseObject数据从NSData转化为NSDictionary,这点在AFNetworkingManager中的已经写明:
NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];

使用JSONObjectWithData后我们得到了NSDictionary格式的数据,但是我们需要的上面自定义对象模型数据啊!所以,你还需要一个序列化的工具在字典和模型间自如的转化,它就是SerializationTools!

  序列化工具类

值得注意的是这段代码,利用runtime获取模型的字段属性(代码段落,全部代码请移步SerializationTools实现类.m)

复制代码
// 获取类成员变量和属性列表,ivarsCnt为类成员数量
    unsigned int ivarsCnt = 0;
    
    Ivar *ivars = class_copyIvarList(cls, &ivarsCnt);
    
    // 只获取类属性列表
    //  unsigned int outCount = 0;
    //  objc_property_t *properties =class_copyPropertyList(cls, &outCount);
    
    // 遍历成员变量列表,其中每个变量都是Ivar类型的结构体
    for (const Ivar *p = ivars; p < ivars + ivarsCnt; ++p) {
        
        Ivar const ivar = *p;
        
        // 获取变量名
        NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
        // 若此变量未在类结构体中声明而只声明为Property,则变量名加前缀 '_'下划线
        // 比如 @property(retain) NSString *abc;则 key == _abc;
        id value = [obj valueForKey:key];
        
        if([key characterAtIndex:0]=='_'){
            key=[key substringFromIndex:1];
        }
        if (value) {
            [dictionaryFormat setObject:[value class] forKey:key];
        } else {
            // 获取类名
            NSString *className = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
            
            [dictionaryFormat setObject:[self GetClassByName:className] forKey:key];
        }
    }
复制代码

通过序列化工具我们就可以很轻松的将字典转化为自定义模型了!

id resultJson = [[SerializationTools sharedInstance] ToObjectOfDictionary:self.resultDic class:class];
3、Service逻辑计算与服务提供

service层主要是根据实际业务需求来定义的接口,实现逻辑计算与业务组装,在这里我举一个例子如:

复制代码
// 返回成功的结果、返回失败的信息、请求超时的错误都能通过block实现反向传值

.h文件

// GET
- (void)getStudentRecords:(NSInteger)offset
                   length:(NSInteger)length
               parentView:(UIView *)parentView
                 blockRtn:(void (^)(ZTTestModelResult *))blockRtn
               blockError:(void (^)(JsonCommonResultBase*))blockError
             blockTimeOut:(TimeOutCompletion)blockTimeOut;

-------------------------------分割线-------------------------------------

.m文件

- (void)getStudentRecords:(NSInteger)offset
                   length:(NSInteger)length
               parentView:(UIView *)parentView
                 blockRtn:(void (^)(ZTTestModelResult *))blockRtn
               blockError:(void (^)(JsonCommonResultBase*))blockError
             blockTimeOut:(TimeOutCompletion)blockTimeOut
{
    NSString *strUrl = @"对接的api url";
    
    [[ZTHttpManager sharedInstance]
     getDataToUrl:strUrl
     headers:nil
     params:nil
     parentView:parentView
     showShadow:YES
     class:[ZTTestModelResult class]
     blockRtn:blockRtn
     blockError:blockError
     blockTimeOut:blockTimeOut];
}
复制代码
4、Controller层业务诉求
复制代码
// Get
    [service getStudentRecords:0 length:10 parentView:self.view blockRtn:^(ZTTestModelResult *arryRtn) {
        
        // 回调成功,处理后续逻辑
        
    } blockError:^(JsonCommonResultBase *error) {
        
        // show message about error
        
    } blockTimeOut:^{
        
        // show message about timeout
    }];
    
    // Post
    [service postTest:@"param1" param2:@"param2" param3:@"param3" parentView:self.view blockRtn:^(JsonCommonResultBase *result) {
        
        // 回调成功,处理后续逻辑
        
    } blockError:^(JsonCommonResultBase *error) {
        
        // show message about error
        
    } blockTimeOut:^{
        
         // show message about timeout
    }];
    
    
    // upload
    [service uploadFileExpImage:[UIImage new] parentView:self.view blockProgress:^(NSString *progress) {
        
        // 上传进度回调成功,处理显示逻辑,注意刷新UI的操作一定要在主线程
        dispatch_async(dispatch_get_main_queue(), ^{
           
            //
        });
        
    } blockRtn:^(JsonCommonResultBase *rtn) {
        
        // 回调成功,处理后续逻辑
        
    } blockError:^(JsonCommonResultBase *error) {
        
        // show message about error
        
    } blockTimeOut:^{
        
        // show message about timeout
        
    }];
复制代码

综上所述,一个基本的基于MVC的网络数据访问框架就完成了!

转载于:https://www.cnblogs.com/lys-iOS-study/p/7063555.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我无法提供具体的原理图,因为这需要访问特定的硬件设计文档和资。然而,我可以向您解释一下USB 3.0封装原理。 USB 3.0(也称为SuperSpeed USB)是一种高速数据传输标准,提供了比USB 2.0更快的传输速度和更大的带宽。USB 3.0封装原理图通常包括以下主要组件: 1. 主控制器:USB 3.0主控制器负责管理数据传输和协议处理。它是连接计算机主机和外部设备之间的桥梁。主控制器通常包括处理器、内存和其他必要的电路。 2. PHY芯片:PHY(Physical Layer)芯片是USB 3.0接口中的物理层处理器。它负责处理电信号转换、时钟管理、电源管理和信号完整性等方面的功能。PHY芯片还负责将数据流转换为可在USB总线上传输的电信号。 3. USB插座:USB 3.0封装原理图中的USB插座是与外部设备连接的接口。它通常包括一组针脚,用于传输数据、提供电源和接地等功能。 4. 过滤器和保护电路:USB 3.0封装原理图中可能包括一些过滤器和保护电路,用于过滤干扰、保护芯片免受电压峰值和静电放电等不良影响。 5. 时钟生成电路:USB 3.0接口需要精确的时钟信号来同步数据传输。因此,时钟生成电路通常包括在封装原理图中,以确保数据传输的准确性和可靠性。 这些是USB 3.0封装原理图中常见的组件,但具体的设计细节和配置可能会因厂商和产品而有所不同。如果您需要详细了解USB 3.0封装原理图,请参考相关的硬件设计文档或咨询相关专业人士。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值