本篇是答應在端午寫iOS網絡-四篇源碼解析以及封裝的最後一篇,是針對上一篇YTKNetwork源碼解析後的一次封裝,也是本身實際項目中所使用過的。在對YTKNetwork封裝的時候,仍是須要對YTKNetwork源碼進行了解,方便對此封裝的理解,請讀一下:http://www.javashuo.com/article/p-spkgoewu-bv.htmljavascript
本篇是實際工做過項目網絡架構抽出來的,讀完大約15-25分鐘左右,Demo也會上傳到github。(暫沒有批量請求需求)html
1、代碼結構以下java
1.針對YTKNetwork網絡封裝目錄ios
2.項目代碼結構與使用:舉例購物車列表git
2、準備github
1.新建項目,導入AFNetworking,YTKNetwork(暫用cocoapods)。json
1)經過命令行cd 新建項目地址(整個直接拖拽到終端),vim
2)進入項目輸入vim Podfile安全
3)輸入i,進入編輯模式服務器
platform :ios, '8.0' target 'TestYTK' do pod 'AFNetworking' pod 'YTKNetwork' pod 'YYModel' pod 'Toast' end
4)而後按Esc鍵,而且輸入「 :」號進入vim命令模式,在冒號後邊輸入wq
5)pod install
從新編譯一下。 (最好創建一個pch文件,便於管理)
2.將代碼直接拖入項目中
將標紅的代碼拖入項目中,編譯一下!
3、代碼分析
1 . IOANotificationManager(通知)
主要做用:主要是監聽網絡的變化。
#import <Foundation/Foundation.h> extern const NSString *kNotNetworkNotificationKey; @interface IOANotificationManager : NSObject // 無網絡 + (void)postNoNetworkNotification:(NSDictionary *)userInfo; // 無網絡 + (void)addNoNetworkBoserver:(id)target selector:(SEL)selector; + (void)removeObservers:(id)target; @end
.m實現以下:
#import "IOANotificationManager.h" const NSString *kNotNetworkNotificationKey = @"com.ioa.NoNetwork"; @implementation IOANotificationManager + (void)postNoNetworkNotification:(NSDictionary *)userInfo { [[NSNotificationCenter defaultCenter] postNotificationName:(NSString *)kNotNetworkNotificationKey object:nil userInfo:userInfo]; } // 無網絡 + (void)addNoNetworkBoserver:(id)target selector:(SEL)selector { if (target) { [[NSNotificationCenter defaultCenter] addObserver:target selector:selector name:(NSString *)kNotNetworkNotificationKey object:nil]; } } + (void)removeObservers:(id)target { [[NSNotificationCenter defaultCenter] removeObserver:target]; } @end
>>>拓展
其實在這裏面也能夠作用戶登錄,退出登錄等監聽操做。
2. IOARequest
主要做用:定義一些請求狀態碼、響應碼,發起請求等
IOARequest.h
#import <YTKNetwork.h> #import "IOAApiManager.h" //管理用戶信息 //#import "IOADataManager.h" #import "IOANotificationManager.h" #import "IOAResponse.h" @interface IOARequest : YTKRequest //返回接口狀態碼,其中:200 成功, // 600 未登陸 // 500 服務器錯誤 // 501 已經存在 // 502 數據接口爲空 // 400 請求參數有錯, // 401 非法請求, // 1 沒有網絡 // 0 服務後臺問題,可以使用response的statuscode查詢具體問題 @property (nonatomic, readonly, assign) NSInteger serverResponseStatusCode; //返回請求狀態碼,其中:1正常,0不正常 @property (nonatomic, readonly, assign) NSInteger serverRequestStatusCode; // 返回的提示信息 @property (nonatomic, readonly, copy) NSString *serverResponseMessage; // 若是沒有網絡 failure同步方式返回 - (void)startWithCompletionBlockWithSuccess:(YTKRequestCompletionBlock)success failure:(YTKRequestCompletionBlock)failure;
經過上面發現IOARequest是繼承YTKRequest,之後咱們在每個模塊請求數據的時候,就繼承咱們本身的IOARequest。
返回接口狀態碼以及請求碼是根據咱們後臺本身定義的,你們能夠根據本身的實際狀況進行更改。
2. IOARequest.m
部分代碼:
- (NSTimeInterval)requestTimeoutInterval { //請求限時 return 30.0; } - (YTKRequestMethod)requestMethod { //測試環境,使用YTKRequestMethodGET,便於與後臺和測試調試問題 #ifdef DEBUG return YTKRequestMethodGET; #else return YTKRequestMethodPOST; #endif } - (void)startWithCompletionBlockWithSuccess:(YTKRequestCompletionBlock)success failure:(YTKRequestCompletionBlock)failure { if (![IOAApiManager isNetworkReachable]) { self.serverResponseStatusCode = 1; // 沒網絡 [IOANotificationManager postNoNetworkNotification:nil]; if (failure) { failure(self); } return; } // WS(weakSelf); [self setCompletionBlockWithSuccess:success failure:^(__kindof YTKBaseRequest * _Nonnull request) { if (failure) { failure(request); // return; } }]; //發起請求 [self start]; } - (BOOL)statusCodeValidator { //判斷響應狀態碼 BOOL isOk = [super statusCodeValidator]; if (!isOk) { #if DEBUG [self testAlertInfo:@"網絡請求錯誤"]; #endif return isOk; } if (!self.responseObject) { self.serverResponseStatusCode = 0; return NO; } self.serverResponseStatusCode = [self.responseObject[@"ret"] integerValue]; self.serverRequestStatusCode = [self.responseObject[@"code"] integerValue]; self.serverResponseMessage = self.responseObject[@"msg"]; if (self.serverResponseStatusCode == 200) { return YES; } else if (self.serverResponseStatusCode > 400 && self.serverResponseStatusCode < 500) { [IOAApiManager saveToken:nil]; //移除用戶我的信息 // [IOADataManager removeUserInfo]; return NO; } return NO; }
3.IOAUploadRequest
主要負責:圖片的上傳和下載(咱們項目上傳圖片,後臺返回是一個對象,對象包括以下)。
#import "IOARequest.h" // 上傳圖片返回的模型 @interface IOAUploadResponseModel : NSObject @property (nonatomic, copy) NSString *url; @property (nonatomic, copy) NSString *file; @property (nonatomic, copy) NSString *file_name; @end //能夠直接IOARequest,不須要繼承YTKRequest @interface IOAUploadRequest : IOARequest @property (nonatomic, strong) UIImage *image; //獲取上傳進度 @property(nonatomic, copy) void(^uploadProgressBlock)(IOAUploadRequest *currentApi, NSProgress * progress); @end
在.m裏面以文件上傳方式上傳
#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self @implementation IOAUploadResponseModel @end @implementation IOAUploadRequest - (YTKRequestMethod)requestMethod { return YTKRequestMethodPOST; } //設置上傳圖片 所須要的 HTTP HEADER - (AFConstructingBlock)constructingBodyBlock { UIImage *image = self.image; return ^(id<AFMultipartFormData> formData) { NSData *data = UIImagePNGRepresentation(image); NSString *name = @"file"; NSString *fileName = @"upload"; NSString *type = @"image/png"; [formData appendPartWithFileData:data name:name fileName:fileName mimeType:type]; }; } #pragma mark 上傳進度 - (AFURLSessionTaskProgressBlock) resumableUploadProgressBlock { WS(weakSelf); AFURLSessionTaskProgressBlock block = ^void(NSProgress * progress){ if (_uploadProgressBlock) { _uploadProgressBlock(weakSelf, progress); } }; return block; } @end
4.IOANetworkManager
主要負責網絡狀態的管理,監聽。
5.IOAResponse
主要負責後臺返回狀態碼管理,包括:是否有網絡,token是否失效,服務器錯誤以及參數錯誤等。
IOAResponse.h
typedef NS_ENUM(NSInteger, ResponseStatusType) { kResponseStatusTypeRequestError = 0, // 服務後臺問題 kResponseStatusTypeNoNetwork = 1, // 沒有網絡 kResponseStatusTypeSuccess = 200, kResponseStatusTypeExpiryToken = 401, kResponseStatusTypeServerServiceError = 500, // kResponseStatustypeServiceExist = 501, kResponseStatusTypeDataNull = 502, kResponseStatusTypeNotLogin = 600, };
@property (nonatomic, assign) BOOL success; //返回接口狀態碼,其中:200 成功, // 600 未登陸 // 500 服務器錯誤 // 501 已經存在 // 502 數據接口爲空 // 400 請求參數有錯, // 401 非法請求, // 1 沒有網絡 // 0 服務後臺問題,可以使用response的statuscode查詢具體問題 @property (nonatomic, assign) ResponseStatusType responseStatusType; @property (nonatomic, assign) NSInteger serverResponseStatusCode; // 服務端返回的status code @property (nonatomic, assign) NSInteger requestResponseStatusCode; // 請求返回的status code @property (nonatomic, strong) id responseObject; @property (nonatomic, copy) NSString *responseMessage; + (IOAResponse *)responseWithRequest:(IOARequest *)request; - (void)updateStatusCodesWithRequest:(IOARequest *)request; // 是否須要提示 - (BOOL)alertOrNot; // 是否沒有有網絡 - (BOOL)isNoNetwork; // 是否token失效 - (BOOL)isExpiryToken; // 服務器錯誤 - (BOOL)isRequestServerError; // 後臺服務錯誤 - (BOOL)isServerServiceError;
IOAResponse.m是其賦值,查看demo便可。
6.IOAApiManager
主要任務:負責是管理Api,開發環境,證書,接口參數,token等。
IOAApiManager.h
+ (void)configNetwork; //+ (NSString *)getService; //+ (NSString *)getToken; + (NSMutableDictionary *)getCommomParametersWith:(NSString *)service token:(NSString *)token; + (NSMutableDictionary *)getParametersWithService:(NSString *)service; + (void)startNetworkMonitoring; + (void)stopNetworkMonitoring; + (BOOL)isNetworkReachable; + (AFNetworkReachabilityStatus)getNetworkStatus; + (void)saveToken:(NSString *)token; + (NSString *)getToken;
在IOAApiManager.m
typedef NS_ENUM(NSUInteger, ServerType) { kSeverTypeDev, // 開發服務器地址 kSeverTypeTest, //測試服務器地址 kSeverTypeRelease //發佈版服務器地址 }; @implementation IOAApiManager + (void)configNetwork { YTKNetworkAgent *agent = [YTKNetworkAgent sharedAgent]; [agent setValue:[NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain",@"application/x-www-form-urlencodem", nil] forKeyPath:@"_manager.responseSerializer.acceptableContentTypes"]; static ServerType serverType = kSeverTypeRelease; #if DEBUG serverType = kSeverTypeDev; #else serverType = kSeverTypeRelease; #endif YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig]; switch (serverType) { case kSeverTypeDev: // 開發服務器地址 //改爲本身的 config.baseUrl = @"http://www.baidu.com"; break; case kSeverTypeTest: // 測試服務器地址 config.baseUrl = @"https://www.baidu.com"; break; case kSeverTypeRelease: // 發佈版服務器地址 config.baseUrl = @"https://www.baidu.com"; break; default: break; } [self configHttps]; } + (void)configHttps { // 獲取證書 NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ssl_content" ofType:@"pem"];//證書的路徑 NSData *certData = [NSData dataWithContentsOfFile:cerPath]; // 配置安全模式 YTKNetworkConfig *config = [YTKNetworkConfig sharedConfig]; // config.cdnUrl = @""; // 驗證公鑰和證書的其餘信息 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; // 容許自建證書 securityPolicy.allowInvalidCertificates = YES; // 校驗域名信息 securityPolicy.validatesDomainName = YES; // 添加服務器證書,單向驗證; 可採用雙證書 雙向驗證; securityPolicy.pinnedCertificates = [NSSet setWithObject:certData]; [config setSecurityPolicy:securityPolicy]; }
上面的域名要改爲本身的域名,上面是以baidu爲準啦!!!
4、實際使用
1. 這個項目是以MVVM模式進行搭建。
在Api文件夾寫接口參數
在viewModel裏面寫接口的請求以及解析
在Datas裏面放的是plist文件等。
這樣便於根據不一樣功能進行管理
2.Api文件夾
Api.h
Api.m,利用YYModel進行將聲明的model轉爲字典,做爲參數
3.ViewModel
ViewModel.h聲明方法,請求方法
在ViewModel.m實現其方法
4.最後在控制器裏面調用請求方法
4.一、導入ViewModel所在的類名
4.二、聲明屬性並懶加載
4.三、控制器調用請求方法
上面就是YTKNetwork的封裝使用了,demo裏面只有封裝的代碼,使用必需要真實的接口,(假數據沒有必要)。若是有須要對YTKNetwork進行二次封裝,能夠下載github,而後按照這個使用方法就能夠進行網絡請求和封裝啦。
demo地址:https://github.com/zxy1829760/YTKNetwork-
到如今爲止,四天關於網絡請求的內容四篇博客就大體說完了,歡迎你們指正!!!