Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A lightweight but powerful network library with simplified and expressive syntax based on AFNetworking.

License

NotificationsYou must be signed in to change notification settings

kangzubin/XMNetworking

Repository files navigation

English Document

XMNetworking 是一个轻量的、简单易用但功能强大的网络库,基于 AFNetworking 3.0+ 封装。

其中,XM 前缀是我们团队Xcode-Men 的缩写。

PlatformLanguageCocoaPodsCarthageLicense

简介

XMNetworking

如上图所示,XMNetworking 采用中心化的设计思想,由XMCenter 统一发起并管理所有的XMRequest 请求,并可通过XMCenter 给所有请求配置回调线程、公共 Server URL、Header、Parameter 等信息,同时也可以 Block 注入的方式给对所有请求做预处理以及实现自定义的请求响应结果处理逻辑,如数据模型转换、业务错误码判断、网络缓存等。另外增加了XMEgine 这一层是为了隔离底层第三方库依赖,便于以后切换其他底层网络库或自己实现底层逻辑。

特性

  • 简单易用,发送请求只需调用一个方法,通过 Block 配置信息,代码紧凑;
  • 功能强大,适用于几乎所有的网络请求使用场景(普通请求、上传、下载);
  • 专为 RESTful Server API 设计,并提供多种不同的请求和响应的序列化类型;
  • 支持批量请求、链式请求等复杂业务逻辑的网络需求;
  • 可随时取消未完成的网络请求,支持自动重试失败的请求;
  • 全局配置所有请求的公共信息,自定义回调线程以及响应处理逻辑;
  • 支持检查网络连接类型,并集成 AFNetworking 强大的安全策略模块。

系统要求

  • iOS 7.0 以上系统
  • Xcode 7.3 或更高版本

安装说明

CocoaPods

在你工程的Podfile 文件中添加如下一行,并执行pod installpod update

pod'XMNetworking','~> 1.1.0'

注意:XMNetworking 会自动依赖AFNetworking 3.0+ ,所以你工程里的Podfile 文件无需再添加pod AFNetworking 去导入AFNetworking

Carthage (只支持 iOS 8+)

与 CocoaPods 不同的是,Carthage 是一个去中心化的第三方依赖库管理工具,它自动帮你编译所依赖的第三方库并以 framework 形式提供给你。

你可以通过Homebrew 执行以下命令来安装 Carthage:

$ brew update$ brew install carthage

成功安装完 Carthage 后,在你工程的Cartfile 文件中添加如下一行:

github "AFNetworking/AFNetworking" ~> 3.0github "kangzubin/XMNetworking" ~> 1.1.0

然后执行carthage update --platform ios 命令生成 framework 包,并把生成的XMNetworking.frameworkAFNetworking.framework 拖拽到你的工程中。

手动安装

下载XMNetworking 子文件夹的内容以及AFNetworking 的代码,并把它们的源文件添加(拖放)到你的工程中。

使用教程

头文件的导入

  • 如果是通过 CocoaPods 或 Carthage 安装,则:
#import<XMNetworking/XMNetworking.h>
  • 如果是手动下载源码安装,则:
#import"XMNetworking.h"

全局网络配置

[XMCentersetupConfig:^(XMConfig *config) {    config.generalServer =@"general server address";    config.generalHeaders = @{@"general-header":@"general header value"};    config.generalParameters = @{@"general-parameter":@"general parameter value"};    config.generalUserInfo =nil;    config.callbackQueue =dispatch_get_main_queue();    config.engine = [XMEnginesharedEngine];#ifdef DEBUG    config.consoleLog =YES;#endif}];

你可以调用XMCenter+setupConfig: 类方法,通过修改传入的XMConfig 对象来配置全局网络请求的公共信息,包括如下:

  • generalServer: 公共服务端地址,如果一个 XMRequest 请求对象的server 属性为nil,且其useGeneralServerYES(默认),那么该请求的服务端地址server 将会取 XMCenter 中generalServer 的值。
  • generalParameters: 公共请求参数,如果一个 XMRequest 请求对象的useGeneralParameters 属性为YES(默认),并且 XMCenter 的公共参数generalParameters 不为空,那么这些公共参数会自动加到该请求的parameters 中。
  • generalHeaders: 公共请求头,如果一个 XMRequest 请求对象的useGeneralHeaders 属性为YES(默认),并且 XMCenter 的公共请求头generalHeaders 不为空,那么这些公共请求头会自动加到该请求的headers 中。
  • generalUserInfo: 公共用户信息,默认为nil,如果一个 XMRequest 请求对象的userInfo 属性为nil(默认)而该字段不为nil,那么该字段会自动赋值给XMRequest 对象的userInfo。而userInfo 属性可用于区分具有相同上下文信息的不同请求。
  • callbackQueue: 请求的回调 Block 执行的 dispatch 队列(线程),如果为NULL(默认),那么会在一个私有的并发队列(子线程)中执行回调 Block。
  • engine: 底层请求的引擎,默认为[XMEngine sharedEngine] 单例对象,你也可以初始化一个XMEngine 对象给它赋值。
  • consoleLog: 一个BOOL 值,用于表示是否在控制台输出请求和响应的信息,默认为NO

另外,你可以通过调用XMCenter 的以下两个类方法来随时修改全局公共的 header 和 parameter:

+ (void)setGeneralHeaderValue:(nullableNSString *)value forField:(NSString *)field;+ (void)setGeneralParameterValue:(nullableNSString *)value forKey:(NSString *)key;

普通请求

GET

[XMCentersendRequest:^(XMRequest *request) {    request.url =@"http://example.com/v1/foo/bar";    request.httpMethod =kXMHTTPMethodGET;}onSuccess:^(id responseObject) {NSLog(@"onSuccess:%@", responseObject);}onFailure:^(NSError *error) {NSLog(@"onFailure:%@", error);}];

**注意1:**可以通过以下两种方法设置一个请求对象的 URL 地址,但当serverapiurl 三个属性被同时赋值时,url 的优先级比较高,而此时serverapi 的值会被忽略。

request.url =@"http://example.com/v1/foo/bar";
// 如果 request.server 为 `nil`,且 request.useGeneralServer 为 `YES`,那么此时 request.server 会取 XMCenter.generalServer 的值。request.server =@"http://example.com/v1/";request.api =@"foo/bar";

**注意2:**一个请求对象的回调 Block (success/failure/finished/progress) 是非必需的(默认为nil),XMCenter 提供了多个设置不同回调 Block 参数的方法用于发送请求。另外,需要注意的是,success/faillure/finished 等回调 Block 会在 XMCenter 设置的callbackQueue 队列中被执行,但 progress 回调 Block 将在 NSURLSession 自己的队列中执行,而不是callbackQueue

POST

[XMCentersendRequest:^(XMRequest *request) {//request.server = @"http://example.com/v1/"; // 可选,如果为空则读取 XMCenter.generalServer    request.api =@"foo/bar";    request.parameters = @{@"param1":@"value1",@"param2":@"value2"};    request.httpMethod =kXMHTTPMethodPOST;// 可选,默认为 `POST`    request.requestType =kXMRequestNormal;// 可选,默认为 `Normal`}onSuccess:^(id responseObject) {NSLog(@"onSuccess:%@", responseObject);}onFailure:^(NSError *error) {NSLog(@"onFailure:%@", error);}onFinished:^(id responseObject,NSError *error) {NSLog(@"onFinished");}];

其他 HTTP 方法

XMRequest 同样支持其他 HTTP 方法,比如:HEAD,DELETE,PUT,PATCH 等,使用方式与上述类似,不再赘述。

详见XMConstXMRequestXMCenter 等几个文件中的代码和注释。

上传请求

// `NSData` form data.UIImage *image = [UIImageimageNamed:@"testImage"];NSData *fileData1 = UIImageJPEGRepresentation(image,1.0);// `NSURL` form data.NSString *path = [NSHomeDirectory()stringByAppendingString:@"/Documents/testImage.png"];NSURL *fileURL2 = [NSURLfileURLWithPath:pathisDirectory:NO];[XMCentersendRequest:^(XMRequest *request) {    request.server =@"http://example.com/v1/";    request.api =@"foo/bar";    request.requestType =kXMRequestUpload;    [requestaddFormDataWithName:@"image[]"fileName:@"temp.jpg"mimeType:@"image/jpeg"fileData:fileData1];    [requestaddFormDataWithName:@"image[]"fileURL:fileURL2];// see `XMUploadFormData` for more details.}onProgress:^(NSProgress *progress) {// the progress block is running on the session queue.if (progress) {NSLog(@"onProgress:%f", progress.fractionCompleted);    }}onSuccess:^(id responseObject) {NSLog(@"onSuccess:%@", responseObject);}onFailure:^(NSError *error) {NSLog(@"onFailure:%@", error);}onFinished:^(id responseObject,NSError *error) {NSLog(@"onFinished");}];

下载请求

[XMCentersendRequest:^(XMRequest *request) {    request.url =@"http://example.com/v1/testDownFile.zip";    request.downloadSavePath = [NSHomeDirectory()stringByAppendingString:@"/Documents/"];    request.requestType =kXMRequestDownload;}onProgress:^(NSProgress *progress) {// the progress block is running on the session queue.if (progress) {NSLog(@"onProgress:%f", progress.fractionCompleted);    }}onSuccess:^(id responseObject) {NSLog(@"onSuccess:%@", responseObject);}onFailure:^(NSError *error) {NSLog(@"onFailure:%@", error);}];

序列化

XMRequest 中有两个属性requestSerializerTyperesponseSerializerType 分别用于设置请求参数和响应结果的序列化类型。

其中,XMRequestSerializerTypeXMResponseSerializerType 枚举的定义如下:

typedefNS_ENUM(NSInteger, XMRequestSerializerType) {kXMRequestSerializerRAW     =0,// defaultkXMRequestSerializerJSON    =1,kXMRequestSerializerPlist   =2,};
typedefNS_ENUM(NSInteger, XMResponseSerializerType) {kXMResponseSerializerRAW    =0,kXMResponseSerializerJSON   =1,// defaultkXMResponseSerializerPlist  =2,kXMResponseSerializerXML    =3,};

详见AFURLRequestSerialization.hAFURLResponseSerialization.h 获取更多细节。

预处理和后处理插件

请求预处理

你可以通过[XMCenter setRequestProcessBlock:...] 设置 XMCenter 的预处理插件,在这里给所有请求做统一处理,另外需要注意的是,这个requestProcessBlock 只对普通/上传/下载的请求有效,而对于批量请求和链式请求中的XMRequest 对象,则不会走这个逻辑。

[XMCentersetRequestProcessBlock:^(XMRequest *request) {// 自定义请求预处理逻辑    request.httpMethod =kXMHTTPMethodPOST;    request.requestSerializerType =kXMRequestSerializerRAW;    request.responseSerializerType =kXMResponseSerializerRAW;}];

自定义响应结果的处理逻辑

通常地,一个请求成功结束时,会执行 success block,当有错误发生时,执行 failure block。然而,开发中更常见的情况是,即使是一个请求成功结束,我们也需要进一步处理,比如验证响应结果数据、判断与服务端商量好的业务错误码类型等,再决定执行 success block 还是 failure block。

现在,你可以调用[XMCenter setResponseProcessBlock:...] 方法以 Block 注入的方式设置自定义的处理逻辑,当请求成功结束时,这个 Block 会在 success block 被执行前调用,如果传入*error 参数被赋值,则接下来会执行 failure block。此外,你可以通过 Block 返回值修改的responseObject 的值,即如果此 Block 的返回值不会空,则responseObject 会被替换。

在这里你可以对全局请求统一做业务错误码判断、数据模型转换、网络缓存等操作!

[XMCentersetResponseProcessBlock:^id(XMRequest *request,id responseObject,NSError *__autoreleasing *error) {// 自定义响应结果处理逻辑,如果 `*error` 被赋值,则接下来会执行 failure block。returnnil;// or return a new object to reset value for responseObject}];

错误信息统一过滤

你可以在[XMCenter setErrorProcessBlock:...] 方法中对全局网络请求的错误做统一的过滤处理。

[XMCentersetErrorProcessBlock:^(XMRequest *request,NSError *__autoreleasing * error) {// 比如对不同的错误码统一错误提示等}];

批量请求

XMNetworking 支持同时发一组批量请求,这组请求在业务逻辑上相关,但请求本身是互相独立的,success block 会在所有请求都成功结束时才执行,而一旦有一个请求失败,则会执行 failure block。注:回调 Block 中的responseObjectserrors 中元素的顺序与每个 XMRequest 对象在batchRequest.requestArray 中的顺序一致。

[XMCentersendBatchRequest:^(XMBatchRequest *batchRequest) {    XMRequest *request1 = [XMRequestrequest];    request1.url =@"server url 1";// set other properties for request1            XMRequest *request2 = [XMRequestrequest];    request2.url =@"server url 2";// set other properties for request2            [batchRequest.requestArrayaddObject:request1];    [batchRequest.requestArrayaddObject:request2];}onSuccess:^(NSArray *responseObjects) {NSLog(@"onSuccess:%@", responseObjects);}onFailure:^(NSArray *errors) {NSLog(@"onFailure:%@", errors);}onFinished:^(NSArray *responseObjects,NSArray *errors) {NSLog(@"onFinished");}];

[XMCenter sendBatchRequest:...] 方法会返回刚发起的新的XMBatchRequest 对象对应的唯一标识符identifier,你通过identifier 调用 XMCenter 的cancelRequest: 方法取消这组批量请求。

链式请求

XMNetworking 同样支持发一组链式请求,这组请求之间互相依赖,下一请求是否发送以及请求的参数取决于上一个请求的结果,success block 会在所有的链式请求都成功结束时才执行,而中间一旦有一个请求失败,则会执行 failure block。注:回调 Block 中的responseObjectserrors 中元素的顺序与每个链式请求XMRequest 对象的先后顺序一致。

[XMCentersendChainRequest:^(XMChainRequest *chainRequest) {    [[[[chainRequestonFirst:^(XMRequest *request) {        request.url =@"server url 1";// set other properties for request    }]onNext:^(XMRequest *request,id responseObject,BOOL *sendNext) {NSDictionary *params = responseObject;if (params.count >0) {            request.url =@"server url 2";            request.parameters = params;        }else {            *sendNext =NO;        }    }]onNext:^(XMRequest *request,id responseObject,BOOL *sendNext) {        request.url =@"server url 3";        request.parameters = @{@"param1":@"value1",@"param2":@"value2"};    }]onNext: ...];    }onSuccess:^(NSArray *responseObjects) {NSLog(@"onSuccess:%@", responseObjects);}onFailure:^(NSArray *errors) {NSLog(@"onFailure:%@", errors);}onFinished:^(NSArray *responseObjects,NSArray *errors) {NSLog(@"onFinished");}];

[XMCenter sendChainRequest:...] 方法会返回刚发起的新的XMChainRequest 对象对应的唯一标识符identifier,你通过identifier 调用 XMCenter 的cancelRequest: 方法取消这组链式请求。

取消一个网络请求

当调用[XMCenter sendRequest:...] 方法发送一个网络请求时,该方法会返回一个用于唯一标识该请求对象的identifier(如果请求发送失败,该值为nil)。在必要的时候,你可以通过这个identifier 来取消当前网络请求(如果一个请求已经结束,这时再用identifier 来取消该请求时,会直接忽略)。

// send a requestNSString identifier = [XMCentersendRequest:^(XMRequest *request) {    request.url =@"http://example.com/v1/foo/bar";    request.httpMethod =kXMHTTPMethodGET;    request.timeoutInterval =10;    request.retryCount =1;}onFailure:^(NSError *error) {NSLog(@"onFailure:%@", error);}];// your business codesleep(2);// cancel the running request by identifier with cancel block[XMCentercancelRequest:identifieronCancel:^(XMRequest *request) {NSLog(@"onCancel");}];

**注意:**调用XMCenter cancelRequest:onCancel: 方法取消一个网络请求时,被取消的请求对象(如果存在)会以参数的形式传给 cancel block,另外 cancel block 是在当前调用cancelRequest: 方法的线程中执行,并不是 XMCenter 的callbackQueue

网络可连接性检查

我们提供了两种方法用于获取网络的可连接性,分别如下:

  • 该方法会返回一个 Bool 值用于表示当前网络是否可连接。
[[XMCenterdefaultCenter]isNetworkReachable];
  • 该方法会返回一个当前网络的状态值(XMNetworkConnectionType 枚举),-1 表示Unknown,0 表示NotReachable,1 表示WWAN,2 表示WiFi
[[XMCenterdefaultCenter]networkConnectionType];

详见AFNetworkReachabilityManager 获取更多细节.

HTTPS 请求的本地证书校验(SSL Pinning)

在你的应用程序包里添加 (pinned) 相应的 SSL 证书做校验有助于防止中间人攻击和其他安全漏洞。AFNetworking 的AFSecurityPolicy 安全模块可以通过校验本地保存的证书或公钥帮助我们评估服务器是否可信任以及建立安全连接。

在 XMNetworking 中,我们对AFSecurityPolicy 进行了封装以便于使用,你可以通过 XMCenter 的addSSLPinningURL: 方法添加需要做 SSL Pinning 的域名:

[XMCenteraddSSLPinningURL:@"https://example.com/"];

默认你只需要把该域名对应的 .cer 格式的证书拖拽到你的工程中即可(即 .cer 所在的 bundle 需要与 XMNetworking 代码所在的 bundle 一致)。如果你是以embedded framework 的方式(Carthage)集成 XMNetworking,则需要通过以下方式添加证书:

// Add SSL Pinning CertificateNSString *certPath = [[NSBundlebundleForClass:[selfclass]]pathForResource:@"certificate file name"ofType:@"cer"];NSData *certData = [NSDatadataWithContentsOfFile:certPath];[XMCenteraddSSLPinningCert:certData];[XMCenteraddSSLPinningURL:@"https://example.com/"];

详见AFSecurityPolicy 获取更多细节.

文档

详见XMNetworking Documents Link.

单元测试

XMNetworking 包含了一系列单元测试,用于验证网络请求的正确性,详见XMNetworkingDemoTests 文件夹中的测试案例。

结构

XMNetworking 的代码结构非常简洁和紧凑,只包含了 4 个核心文件:XMConst.h 用于定义全局常量枚举和 Block,XMRequestXMCenterXMEngine 则是核心类的声明和实现,具体的代码结构如下图所示:

XMNetworking Structure

待完善

  • 支持断点下载
  • 支持网络层缓存
  • 兼容测试支持 tvOS/watchOS/macOS
  • 更加强大的自定义模型转换
  • 实现一套可扩展的插件机制,便于 XMNetworking 增加新功能

作者

贡献者

许可证

XMNetworking 使用 MIT 许可证,详情见LICENSE 文件。

About

A lightweight but powerful network library with simplified and expressive syntax based on AFNetworking.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp