YTKNetwork網絡封裝

本篇是答應在端午寫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-

 

到如今爲止,四天關於網絡請求的內容四篇博客就大體說完了,歡迎你們指正!!!

相關文章
相關標籤/搜索