基于AFNetworking封裝的網(wǎng)絡(luò)庫闸氮,主要是為了滿足一些復(fù)雜App的網(wǎng)絡(luò)請求剪况,并在層次劃分上比較清新,所有的網(wǎng)絡(luò)請求是數(shù)據(jù)提供者蒲跨,還歸納了一些常見的功能封裝在里面(緩存,簽名...),設(shè)計文檔
特色功能
- [x] 自定義Key簽名參數(shù)
- [x] 緩存不止支持GET译断,還支持POST,根據(jù)自己的場景,自己選擇策略
- [x] 支持用IP替換域名或悲,達(dá)到提高網(wǎng)絡(luò)性能孙咪,支持HTTP HEAD設(shè)置
- [x] 攔截網(wǎng)絡(luò)請求堪唐,方便攔截任意請求,復(fù)用請求翎蹈,加入Loading
安裝環(huán)境
- iOS 8.0以上
- Xcode 7.3以上
如何安裝
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target 'TargetName' do
pod 'JJNetwork'
end
執(zhí)行命令:
$ pod install
使用Carthage集成
在你的Cartfile
文件里淮菠,加入以下內(nèi)容:
github "jezzmemo/JJNetwork"
將 AFNetworking.framework
,JJNetwork.framework
兩個framework加入到自己的項目
如何使用
JJAPIRequest
每個網(wǎng)絡(luò)請求都是繼承JJAPIRequest
,并按照JJRequestInput
協(xié)議的方法,按照自己的需求荤堪,重寫(overwrite)指定的方法合陵,來滿足自己的需求.
下面我用JJNetwork來向http://api.imemo8.com/diary.php
發(fā)送一個GET請求,參數(shù)是mod=getHotDiary:
#import "JJNetwork.h"
@interface DemoRequest : JJAPIRequest
@end
#import "DemoRequest.h"
@implementation DemoRequest
- (NSString*)requestURL{
return @"http://api.imemo8.com/diary.php";
}
- (HTTPMethod)requestMethod{
return JJRequestGET;
}
@end
requestURL
填寫一個完整的URL澄阳,繼承JJAPIRequest的時候拥知,必須需要實現(xiàn)這個方法,其余方法都是可選的碎赢,requestMethod
返回一個枚舉類型低剔,POST,GET,PUT,DELETE,如果不實現(xiàn),默認(rèn)是GET
如何傳遞參數(shù)和調(diào)用
關(guān)于在哪初始化Request肮塞,這個根據(jù)自己的情況自己選擇户侥,你可以在ViewController里調(diào)用,也可以再自己的中間層調(diào)用峦嗤,這里給的例子是在ViewController里的例子:
#import "PresentViewController.h"
#import "DemoRequest.h"
@interface PresentViewController ()<JJRequestDelegate>
@property(nonatomic,readwrite,strong)DemoRequest* demoRequest;
@end
@implementation PresentViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.demoRequest startRequest];
}
#pragma mark - Get property
- (DemoRequest*)demoRequest{
if (_demoRequest != nil) {
return _demoRequest;
}
_demoRequest = [DemoRequest new];
_demoRequest.delegate = self;
return _demoRequest;
}
#pragma mark - Request parameter
- (NSDictionary*)requestParameters:(JJAPIRequest *)request{
return @{@"mod":@"getHotDiary"};
}
#pragma mark - Network response
- (void)responseSuccess:(JJAPIRequest *)request responseData:(id)data{
NSLog(@"responseSuccess");
}
- (void)responseFail:(JJAPIRequest *)request errorMessage:(NSError *)error{
NSLog(@"responseFail");
}
@end
- 調(diào)用startRequest方法執(zhí)行網(wǎng)絡(luò)請求
- 實現(xiàn)requestParameters來提供請求的參數(shù)蕊唐,網(wǎng)絡(luò)情況的輸入
- responseSuccess和responseFail,網(wǎng)絡(luò)請求的輸出
- 至于為什么選擇Delegate這種交互方式,傳送門
使用自定義Key簽名參數(shù),示例如下:
- (NSString*)signParameterKey{
return @"key";
}
如果使用了signParameterKey
方法烁设,就會產(chǎn)生兩個參數(shù)sign
和timestamp
,并且實現(xiàn)的方式是:md5(parameters + timestamp + key)
GET和POST都支持緩存,示例如下:
- (HTTPCachePolicy)requestCachePolicy{
return ReloadFromCacheTimeLimit;
}
- (NSUInteger)cacheLimitTime{
return 120;
}
如果選擇了ReloadFromCacheTimeLimit緩存策略替梨,就必須實現(xiàn)cacheLimitTime
方法,作用是你的緩存持續(xù)的時間,過期后將從網(wǎng)絡(luò)上重新請求装黑,選擇其他兩種則不需要實現(xiàn)cacheLimitTime
- ReloadFromNetwork: 只從網(wǎng)絡(luò)獲取
- ReloadFromCacheElseLoadNetwork: 有緩存就從緩存獲取副瀑,沒有就從網(wǎng)路獲取
- ReloadFromCacheTimeLimit: 緩存限定的時間范圍內(nèi)
支持用IP替換域名(服務(wù)器要支持IP訪問),達(dá)到提高網(wǎng)絡(luò)性能恋谭,支持HTTP HEAD設(shè)置
JJAPIDominIPModule
@interface DomainModule : NSObject<JJAPIDominIPModule>
@end
@implementation DomainModule
- (NSDictionary*)domainIPData{
return @{@"api.imemo8.com":@"218.244.140.1"};
}
@end
JJAPIHttpHeadModule
@interface HttpHeadModule : NSObject<JJAPIHttpHeadModule>
@end
@implementation HttpHeadModule
- (NSDictionary*)customerHttpHead{
return @{@"user-token":@"xxxxx",@"device-id":@"xxxxx"};
}
@end
并注冊到JJAPIRequest+Extension
[JJAPIRequest registerDomainIP:[[DomainModule alloc] init]];
[JJAPIRequest registerHttpHeadField:[[HttpHeadModule alloc] init]];
這是兩個設(shè)置的接口糠睡,DomainModule是將域名替換成IP,減少了DNS的時間疚颊,從而提高訪問速度.
HttpHeadModule是設(shè)置全局的Head Field,根據(jù)自己的項目需要來決定是否需要設(shè)置.
攔截器的使用
- 從
JJAPIRequest
實例化對象的requestInterseptor的屬性狈孔,并實現(xiàn)JJRequestInterseptor
協(xié)議:
- (DemoRequest*)demoRequest{
if (_demoRequest != nil) {
return _demoRequest;
}
_demoRequest = [DemoRequest new];
_demoRequest.delegate = self;
_demoRequest.requestInterseptor = self;
return _demoRequest;
}
- JJAPIService 的擴(kuò)展實現(xiàn)以下方法,可以監(jiān)聽任意JJAPIService子類:
+ (void)addRequestInterseptor:(id<JJRequestInterseptor>)interseptor forRequestClass:(Class)className;
+ (void)removeRequestInterseptor:(id<JJRequestInterseptor>)interseptor forRequestClass:(Class)className;
使用示例:
[JJAPIService addServiceInterseptor:self forServiceClass:[DemoAPIService class]];
- (void)beforeRequest:(JJAPIRequest*)request{
NSLog(@"網(wǎng)絡(luò)發(fā)送Request執(zhí)行前");
}
- (void)afterRequest:(JJAPIRequest*)request{
NSLog(@"網(wǎng)絡(luò)發(fā)送Request執(zhí)行后");
}
- (void)request:(JJAPIRequest*)request beforeResponse:(id)data{
NSLog(@"返回結(jié)果前");
}
- (void)request:(JJAPIRequest*)request afterResponse:(id)data{
NSLog(@"返回結(jié)果后");
}
主要應(yīng)用的兩個場景就是Loading的顯示和關(guān)閉,還有就是如果我需要用某個網(wǎng)絡(luò)請求的數(shù)據(jù)材义,不需要改動原來的業(yè)務(wù)邏輯均抽,只需要添加一份攔截即可,對已有的代碼不需要任何改動.