iOS 一个模块化,接口化的网络请求组件JCNetWokingManager

做iOS开发有一段时间,接触了许多的网络请求组件。但是很多网络请求组件对业务的耦合性比较高,很难脱离业务层。对网络请求组件进行了一些优化,实现了接口化及模块化使得该组件更易用,易用扩展,低耦合。

1.模块详解

1.1 结构简图

模块化结构图

1.2 各模块解析

工程结构图

config

  • JCNetWorkingEnvironmentConfigure 域名及环境的全局配置
  • JCNetWorkingProtocolManager 模型转换和缓存功能实例化单例(此类对两层协议进行类绑定)
    采用协议的方式进行实现可将接口统一,之后如果需要修改sdk只需要修改实现类即可,不会让sdk代码入侵业务代码之中

protocol

  • JCNetWorkingBusinessServiceProtocol 请求服务协议
  • JCNetWorkingModelProtocol 模型转换协议(主要实现字典与模型之间的转换)
  • JCNetWorkingCacheProtocol 缓存功能协议(主要实现数据缓存)
  • JCNetWorkingServiceProtocol 网络请求的主要实现协议

custom

  • JCNetWorkingBusinessService 基础服务协议实现类,绑定了功能组件
  • JCNetWorkingModelTool 模型转换实现类
  • JCNetWorkingCacheTool 缓存功能实现类
  • JCNetWorkingServiceTool 网络请求实现类
  • JCNetWorkingClient 此类使用AFNetWorking对网络请求的post get update进行了实现
  • JCNetWorkingRequest 网络请求工具请求对象(封装和定义了请求参数及缓存功能)

model

  • JCNetWorkingParameterModel 基础请求体模型
  • JCNetWorkingResponseModel 基础返回体模型
  • JCNetWorkingErrorResponseModel 错误返回体模型

tool

  • NSString+JCNetWoringUtil 将json字典直接转化为格式好的json字符串
  • NSDictionary+JCNetWoringUtil 字典去空工具

1.3 使用的第三方sdk

  1. AFNetworking (网络请求SDK)
  2. MJExtension (模型转换SDK)
  3. YYCache (数据缓存SDK)

2.架构思想解析

2.1 接口化

组件使用协议统一外部接口,让我们只需要关注内在的功能实现。只要关注协议对象对统一接口的实现即可,而不需要关注该对象在整个组件之间的逻辑,这样在我们需要更换SDK或更改协议对象实现方式的时候就会更加方便和便捷。此处以模型协议JCNetWorkingModelProtocol做为例子进行讲解。
我们定义一个需要统一接口的协议:JCNetWorkingModelProtocol
#import <Foundation/Foundation.h>

@protocol JCNetWorkingModelProtocol <NSObject>

// 模型变成字典
+ (NSDictionary *)configDictWithResponseModel:(id)responseObject;

// 将数据转换成模型
+ (id)configModelWithResponseObject:(id)responseObject class:(Class)cls;

@end
我们定义一个实现该协议的对象:JCNetWorkingModelTool
#import <Foundation/Foundation.h>
#import "JCNetWorkingModelProtocol.h"

@interface JCNetWorkingModelTool : NSObject <JCNetWorkingModelProtocol>

@end
#import "JCNetWorkingModelTool.h"
#import "MJExtension.h"
#import "NSDictionary+JCNetWoringUtil.h"

@implementation JCNetWorkingModelTool

+ (NSDictionary *)configDictWithResponseModel:(id)responseObject {

return [[responseObject mj_keyValues] removeNullValues];
}

+ (id)configModelWithResponseObject:(id)responseObject class:(Class)cls {

if ([responseObject isKindOfClass:[NSArray class]]) {
return [cls mj_objectArrayWithKeyValuesArray:responseObject];
}
id responseModel = [cls mj_objectWithKeyValues:responseObject];
return responseModel;
}

@end
在JCNetWorkingModelTool协议对象中,我们使用了第三方SDK MJExtension进行模型转换的实现,如果我们发现MJExtension出现了严重的bug,不再适合工程使用的时候,只需要替换问题的SDK并实现协议方法即可,耦合性变得很低。protocol文件夹下的其他接口协议同样适用。

2.2 模块化

在测试项目中书写了一个首页网络请求模块。不同的开发人员只要集成JCNetWorkingManager组件,并书写各自的网络服务协议便可按照各自的模块进行开发,使各个模块之间没有任何耦合。
我们定义一个模块的网络层服务协议
#import <Foundation/Foundation.h>
#import "JCNetWorkingParameterModel.h"

@protocol JCHomeSerivceProtocol <NSObject>

/**
*
*  @brief 启动页
*
*/
- (void)requestStartUpWithParameter:(JCNetWorkingParameterModel *)parameterModel Success:(RequestSuccess)success failure:(RequestFailure)failure;

@end
我们定义一个模块的网络层服务协议实现类JCHomeService,并实现协议方法即可。
#import "JCHomeService.h"

static NSString *const kStartPic = @"/zbs/index/startpic";       //启动图片

@implementation JCHomeService

- (void)requestStartUpWithParameter:(JCNetWorkingParameterModel *)parameterModel Success:(RequestSuccess)success failure:(RequestFailure)failure {

JCNetWorkingRequest *request = [JCNetWorkingRequest requestWithDomainType:JCDomainTypeHome path:kStartPic parameterModel:parameterModel responseClass:[JCHomeStarPageResponseModel class]];
request.netWorkingModelProtocolClass = self.netWorkingModelProtocolClass;
request.netWorkingCacheTool = self.netWorkingCacheTool;
[self sendRequest:request success:success failure:failure];
}

@end

3.使用详解

3.1 工程环境及域名配置

在正式使用项目的时候我们需要配置功能环境,以达到自动切换请求环境的目的。
工程环境配置
在Appdelegate书写转换代码,这样只要我们切换了编译环境。我们网络请求模块的域名就会自动修改为对应的环境域名。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

#ifdef TEST_ENV
[[JCNetWorkingEnvironmentConfigure showJCEnvironmentConfigure] setEnvironmentType:JCNetWorkingEnvironmentTypeTest];
#else
[[JCNetWorkingEnvironmentConfigure showJCEnvironmentConfigure] setEnvironmentType:JCNetWorkingEnvironmentTypeOnline];
#endif

return YES;
}
在JCNetWorkingEnvironmentConfigure中对网络组件的总体域名进行定义并分类。在.h文件中定义了两个分类枚举分别为环境枚举,域名枚举。
typedef NS_ENUM(NSUInteger, JCNetWorkingEnvironmentType) {
JCNetWorkingEnvironmentTypeTest,
JCNetWorkingEnvironmentTypeOnline
};

typedef NS_ENUM(NSInteger , JCDomainType) {
JCDomainTypeDefault,
JCDomainTypeHome
};
在JCNetWorkingEnvironmentConfigure.m中主要是定义具体域名。
- (void)setEnvironmentType:(JCNetWorkingEnvironmentType)environmentType {

_environmentType = environmentType;
switch (environmentType) {
case JCNetWorkingEnvironmentTypeTest:
{
_HTTPHost = @"http://www.baidu.com";
_HomeHost = @"http://www.google.com";
}
break;
case JCNetWorkingEnvironmentTypeOnline:
{
_HTTPHost = @"http://www.baidu.com";
_HomeHost = @"http://www.google.com";
}
break;
default:
break;
}
}

- (NSString *)configPathWithDomainTypeDefault:(JCDomainType)domainTypeDefault path:(NSString *)path {

switch (domainTypeDefault) {
case JCDomainTypeDefault:
{
return [[JCNetWorkingEnvironmentConfigure showJCEnvironmentConfigure].HTTPHost stringByAppendingString:path];
}
break;
case JCDomainTypeHome:
{
return [[JCNetWorkingEnvironmentConfigure showJCEnvironmentConfigure].HomeHost stringByAppendingString:path];
}
break;
}
}

3.2 网络请求模块书写

该模块的教程书写同2.2 模块化中的具体实现即可。

3.3 具体使用

在具体的控制器中定义协议服务对象,并发起请求即可。
- (void)requestStarPage {

[self.homeService requestStartUpWithParameter:[JCHomeStarPageParameterModel new] Success:^(JCHomeStarPageResponseModel * responseModel, BOOL isCache) {
     NSLog(@"%@", responseModel);
} failure:^(JCNetWorkingErrorResponseModel *responseModel) {
     NSLog(@"%@", responseModel);
}];
}

- (JCHomeService *)homeService {

   if (!_homeService){
      _homeService = [JCHomeService new];
   }
   return _homeService;
}

4.结语

在组件架构的设计过程中只有不断的完善代码,并将组件之间,模块与组件的耦合降低,才能设计出更加高效和易于扩展的组件。欢迎给我留言并提出您宝贵的意见,如果喜欢记得给一颗星哦。
传送门: git地址
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • (403) 我也很享受晚上坐在书桌前看书写东西的感觉,这是一天最能投入的时间。 阿姨想着我让我劳逸结合,心里暖暖的...
    韩尚小阅读 163评论 2 1
  • 上文http://www.jianshu.com/p/e7989b6359d7)说的是对因果报应的逻辑理顺,下面我...
    聆心2016阅读 268评论 11 9
  • 单元十六(搜集研究资料的基本方法) 1 潜在特质 潜在特质是项目反应理论的一个重要概念,它是指被试某种相对稳定的、...
    星星与七便士阅读 1,051评论 0 1
  • 第一章 没累着你蔫什么 吱悠悠,咯吱吱;吱悠悠,嘎吱吱…… 饱受主人虐待的床板如同上了岁数的老人,浑身经不起敲打,...
    丰口阅读 539评论 1 1