背景和目的
目前iOS框架中网络的实现方式大多基于流行的网络框架进行例如ASI、AFNetWork等)或者苹果自带的NSURLSession。ASI是基于CFHTTP的,AFNetworking是基于NSURL的,两者处在不同的层次上,实现原理也不同。
如何在开发自己的项目过程中提供一套最简单的API,只需提供我们用的到的接口,并且将一些重复的处理逻辑封装起来。使得调用者在不需要了解到具体使用何种网络库 CFHTTP、NSURL、ASIHTTPRequest、AFNetworking的情况下,就能把网络请求处理完,让开发着处理网 络请求像调用本地方法一样自然,这就是本次设计的目的。
需要解决的问题
1.调用方式简单明确
减少使用者对具体的网络框架的依赖,按照统一的方式进行调用,便于规范代码书写和后续维护。
2.解决网络数据和业务层的对接问题
返回数据形式是NSDictionary,在model基类中通过runtime方式将其转换为具体的model对象。
3.业务层获得数据的形式
业务层直接对具体的model进行处理和显示。为了减少业务层处理逻辑建议server端返回数据形式尽可能和APP的UI表示逻辑保持一致。
4.封装API应该是集约型还是离散型
所谓集约型,就是只能业务层提供一个方法,所有业务层的网络请求都要通过该方法完成。集约型的好处是对于网络层的编写来说方便快捷,对业务的适用性较强。
离散型就是根据功能模块分为不同的模块,分别提供不同的方法给业务层调用。离散型便于理解,项目结构更清晰同时要求对业务具有较好的抽象能力。
本次设计采用集约型的方式进行主要出于以下几点考虑:
1.server支持的数据结构贴近UI设计,后续需要处理加工较少。
2.APP整体架构设计时已经对Control层进行了扩展,网络访问再使用离散型略显啰嗦和导致代码过于分散。
网络架构需要具备如下功能
1.支持缓存网络请求内容
2.支持统一设置服务器地址
3.支持检查返回Json数据的合法性
4.支持block和delegate两种模式的回调方式
5.支持批量的网络请求,并统一设置它们的回调
6.支持网络请求URL的filter,可以统一为网络请求加上一些参数,或者修改一些路径。
网络架构图
ar.pngUML设计
UML.png最终实现
1.HTRequestConfig:负责配置统一服务器地址和为网络请求加上一些参数(Token,Sig等),可同时为多个Request提供配置
2.HTRequest:基本的请求对象,请求的URL、参数、body数据体和请求的方法(Get、Post)
3.HTReponse:请求的返回数据
4.HTNetWorkError:返回错误信息
5.HTDataCache:数据缓存和读取
类实现
HTRequestConfig
#import <Foundation/Foundation.h> @interface HTRequestConfig : NSObject @property (nonatomic,retain) NSString *baseUrl; @property (nonatomic,retain) NSString *token; @property (nonatomic,retain) NSString *sig; @property (nonatomic,retain) NSString *timestamp; @end
HTRequest
HTRequest通过其类方法进行构造,对外属性均为只读。其中tag用于批量请求时进行区分。
#import "HTRequestConfig.h" typedef NS_ENUM(NSInteger, RequestMethod) { RequestMethod_Get = 0, RequestMethod_Post, RequestMethod_Put, RequestMethod_Delete };
@interface HTRequest : NSObject @property (readonly,nonatomic,copy) NSURL* url; @property (readonly,nonatomic,copy) NSString* fullPath; @property (readonly,nonatomic,copy) NSDictionary* parameters; @property (readonly,nonatomic,copy) NSData* data; @property (readonly,nonatomic)RequestMethod methodType; @property (nonatomic,retain)NSString *tag;
+ (instancetype)sharedRequestWithMethodType:(RequestMethod)methodType withPath:(NSString *)path withParam:(NSDictionary *)paramDic withConfig:(HTRequestConfig *)config;
+ (instancetype)sharedRequestWithData:(NSData *)data withPath:(NSString *)path withParam:(NSDictionary *)paramDic withConfig:(HTRequestConfig *)config; @end
HTNetWorkClient
HTNetWorkClient中集约所有访问方法,包括单个和批量请求、数据上传(图片、音频、视频)支持block和delegate两种模式的回调方式。
1.属性defaultCheckMessage用于检查json的合法性。在和Server端通信设计中规定所有Json的格式按照(MessageCode、Message、data)的形式进行,messageCode非0的场合数据请求失败。
2.属性defaultUseCache用于设置和判断是否有数据缓存,如果要使用缓存数据通过getCacheData进行取得。
@interface HTNetWorkClient : NSObject{ AFHTTPSessionManager *_requestManager; NSInteger _bacthRequestCount; HTResponse *_batchResponse; }
@property (nonatomic,weak) id<HTRequestDelegate> delegate; @property (nonatomic)BOOL defaultCheckMessage; @property (nonatomic)BOOL defaultUseCache;
+ (instancetype)sharedClient;
- (void)startAsynchronous:(HTRequest *)request;
- (void)startAsynchronous:(HTRequest*)request onProgress:(HITResponseProgress)progressBlock onResponse:(HITResponseObject)responseBlock onError:(HITResponseError)errorBlock;
- (void)startAsynchronousWithBatchRequest:(NSArray *)batchRequest;
- (void)startAsynchronousWithBatchRequest:(NSArray *)batchRequest onProgress:(HITResponseProgress)progressBlock onResponse:(HITResponseObject)responseBlock onError:(HITResponseError)errorBlock;
- (void)startUploadData:(HTRequest *)request withDataType:(DataType)dataType;
- (void)startUploadData:(HTRequest *)request withDataType:(DataType)dataType onProgress:(HITResponseProgress)progressBlock onResponse:(HITResponseObject)responseBlock onError:(HITResponseError)errorBlock;
- (void)cancel;
- (id)getCacheData:(HTRequest *)request;
@end
HTNetWorkError
封装错误信息,无论请求是否正常json中messageCode不等于0即为失败。
@interface HTNetWorkError : NSObject
@property (nonatomic,assign) NSInteger errorCode;
@property (nonatomic,copy) NSString *errorDescription;
@end
HTDataCache
按照访问的url为key进行数据缓存。
@interface HTDataCache : NSObject{ NSCache *_cache; }
+ (HTDataCache *)sharedManager;
- (void)cacheDataWithUrl:(NSString *)url withData:(id)jsonData;
- (id)getCacheDataWithUrl:(NSString *)url;
@end
HTResponse
封装了请求的返回数据,有多个请求时以请求的tag作为key。
@interface HTResponse : NSObject{ NSMutableDictionary *_responseObjectDic; }
@property (readonly,nonatomic,strong)id object;
@property (readonly,nonatomic,strong)NSDictionary *objectDic;
+ (HTResponse*)shareResponseWithObject:(id)responseObject;
- (void)setObjectByKey:(NSString *)key withObject:(id)responseObject;
- (id)getObjectByKey:(NSString *)key;
@end
网友评论
https://github.com/horaetech/HTNetWork