SCNetworkKit

SCNetworkKit is a simple but powerful iOS network framework based on NSURLSession and NSURLSessionConfiguration, written by Objective-C, Support iOS 7+ ;

Installation with CocoaPods

在你的 Podfile 文件里添加:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'

target 'TargetName' do
pod 'SCNetworkKit', '~> 1.0.3'
end

使用范例

假设服务器返回的数据格式如下:

{ 
  code = 0;
  content =     {
     entrance =         (
         {
	         isFlagship = 0;
	         name = "\U65f6\U5c1a\U6f6e\U65f6\U5c1a";
	         pic = "http://pic12.shangpin.com/e/s/15/03/03/20150303151320537363-10-10.jpg";
	         refContent = "http://m.shangpin.com/meet/185";
	         type = 5;
         },
         {
            //....
         }
       )
     }
 }

下面演示如何通过配置不同的解析器,从而达到着陆 block 回调不同结果的效果:

SCNetworkRequest *req = [[SCNetworkRequest alloc]initWithURLString:@"http://debugly.cn/dist/json/test.json" params:nil httpMethod:@"GET"];
    ///因为默认解析器是SCNJSONResponseParser;会解析成JSON对象;所以这里不指定解析器,让框架返回data!
    req.responseParser = nil;
    [req addCompletionHandler:^(SCNetworkRequest *request, id result, NSError *err) {
        
        if (completion) {
            completion(result);
        }
    }];
[[SCNetworkService sharedService]sendRequest:req];
SCNetworkRequest *req = [[SCNetworkRequest alloc]initWithURLString:@"http://debugly.cn/dist/json/test.json" params:nil httpMethod:@"GET"];
    
SCNJSONResponseParser *responseParser = [SCNJSONResponseParser parser];
///框架会检查接口返回的 code 是不是 0 ,如果不是 0 ,那么返回给你一个err,并且result是 nil;
responseParser.checkKeyPath = @"code";
responseParser.okValue = @"0";
req.responseParser = responseParser;
    
[req addCompletionHandler:^(SCNetworkRequest *request, id result, NSError *err) {
    
    if (completion) {
        completion(result);
    }
}];
[[SCNetworkService sharedService]sendRequest:req];
SCNetworkRequest *req = [[SCNetworkRequest alloc]initWithURLString:@"http://debugly.cn/dist/json/test.json" params:nil httpMethod:@"GET"];
    
SCNModelResponseParser *responseParser = [SCNModelResponseParser parser];
///解析前会检查下JSON是否正确;
responseParser.checkKeyPath = @"code";
responseParser.okValue = @"0";
///根据服务器返回数据的格式和想要解析结构对应的Model配置解析器
responseParser.modelName = @"TestModel";
responseParser.modelKeyPath = @"content/entrance";
req.responseParser = responseParser;
    
[req addCompletionHandler:^(SCNetworkRequest *request, id result, NSError *err) {
    
    if (completion) {
        completion(result);
    }
}];
[[SCNetworkService sharedService]sendRequest:req];

由于上面有 JSON 转 Model 的过程,因此在使用之前需要注册一个对应的解析器,你可以到 demo 里搜下 [SCNModelResponseParser registerModelParser:[SCNModelParser class]]; 具体看下究竟。继续往下看,你会了解为何这么设计!

链式编程

SCNJSONResponseParser *responseParser = [SCNJSONResponseParser parser];
///框架会检查接口返回的 code 是不是 0 ,如果不是 0 ,那么返回给你一个err,并且result是 nil;
responseParser.checkKeyPath = @"code";
responseParser.okValue = @"0";
    
///support chain
    
SCNetworkRequest *req = [[SCNetworkRequest alloc]init];
    
req.c_URL(@"http://debugly.cn/dist/json/test.json")
   .c_Method(@"GET")
   .c_ResponseParser(responseParser);
   .c_CompletionHandler(^(SCNetworkRequest *request, id result, NSError *err) {
        
            if (completion) {
                completion(result);
            }
       });
[[SCNetworkService sharedService]sendRequest:req];

为什么创建这个轮子 ?

因为我在做 SDK,而不是 App;我要确保提供出去的 SDK 不对外产生依赖,以防由于依赖的环境问题影响到了SDK的功能!因此我需要一个稳定的网络请求框架,能够为 SDK 提供可靠的网络服务!

特性

架构设计

设计图:

采用注册的方式解耦和

功能强大的同时要顾及到扩展性,本框架支持很多扩展,以响应解析为例,你可以继续创建你想要的解析器;可以使用你喜欢的 JOSN 转 Model 框架来做解析;可以让网络库解析更多格式的图片;这些都是可以做到的,并且还很简单。

@protocol SCNModelParserProtocol <NSObject>

@required;
+ (id)fetchSubJSON:(id)json keyPath:(NSString *)keypath;
+ (id)JSON2Model:(id)json modelName:(NSString *)mName;

@end

@interface SCNModelResponseParser : SCNJSONResponseParser

@property (nonatomic,copy) NSString *modelName;
@property (nonatomic,copy) NSString *modelKeyPath;

+ (void)registerModelParser:(Class<SCNModelParserProtocol>)parser;

@end

我在 demo 里面使用的是我的另外一个轮子:SCJSONUtil ;具体实现可查看demo。

@protocol SCNImageParserProtocol <NSObject>

@required;
+ (UIImage *)imageWithData:(NSData *)data scale:(CGFloat)scale;

@end

///默认支持png 和 jpg;可通过注册的方式扩展!
@interface SCNImageResponseParser : SCNHTTPResponseParser


/**
 注册新的图片解析器和对应的类型

 @param parser 解析器
 @param mime 支持的类型
 */
+ (void)registerParser:(Class<SCNImageParserProtocol>)parser forMime:(NSString *)mime;

@end

这种注册器的方式优雅地扩充了网络库的功能,就好比插件一样,插上就能用,只需要规格上符合我协议里规定的要求即可!反之,如果你不需要解析 webp, 你不需要 json 转 model 的话,你就没必要去插对应的模块!

如果没有注册器这么一个好的实践的话,要达到同样的扩展效果可能就很难了!如果你有别的点子请联系我。

SCNetworkService

由上图可知,SCNetworkService 主要起到了发起网络请求,处理好 Request,task,delegate 对象的一一对应关系的作用!

SCNetworkRequest

NSURLSession 管理的网络请求结束后,会在 SCNetworkRequest 里处理响应数据,根据配置的 ResponseParser 去异步解析,最终在主线程里安全着陆;


如有问题,或者需要 SCNetworkKit 提供更强大的功能,请提 issue 给我,3q!