聯(lián)系方式:401518215@qq.com
童稚們,我有回來了> <。感覺上次寫的教程反響還是挺好的限番,我動力十足呀扼褪。今天我也來帶給大家在iOS項目開發(fā)里面必須的技能--網絡請求想幻。當然啦,普通的網絡請求寫起來不困難话浇,本來就屬于iOS開發(fā)的必修課程脏毯,不過現(xiàn)在我們需要考慮的是處于項目開發(fā)的環(huán)境下,自然就少不了對網絡服務的封裝幔崖,不然我們在項目的使用過程中就變得異常的混亂和長~~~~食店。
不多說渣淤,我們先要導入一個輪子:AFNetworking。不得不說這個第三方庫的功能實在強大叛买,今天我們使用到的網絡請求功能也不過是這個庫的鳳毛麟角砂代,想要仔細學習的話可以自己去看一下。導入方式不多說:拷貝或者cocoapod率挣。
必須說明的是AFNetworking其實已經把網絡請求給封裝一次了刻伊,那為什么我們還要封裝一次呢?只是為了統(tǒng)一我們的請求接口和使用于我們項目的實質需求椒功。畢竟別人封裝考慮的是全面和實用捶箱,而我們在他們的基礎上再次封裝則是為了我們的項目開發(fā)需求。
說了這么多动漾,終于要上代碼了丁屎。先創(chuàng)建兩個網絡服務類
typedef NS_ENUM(NSUInteger, HttpRequestType) {
//get請求
HttpRequestType_Get = 0,
//post請求
HttpRequestType_Post
};
typedef NS_ENUM(NSInteger, AFNetworkErrorType) {
AFNetworkErrorType_TimeOut = NSURLErrorTimedOut, //連接超時
AFNetworkErrorType_UnURL = NSURLErrorUnsupportedURL, //無URL
AFNetworkErrorType_NoNetwork = NSURLErrorNotConnectedToInternet, //無網絡
AFNetworkErrorType_404Failed = NSURLErrorBadServerResponse, //404
AFNetworkErrorType_3840Failed = 3840 //網絡錯誤
};
@interface CHHttpRequest : NSObject
/**
* 發(fā)送get請求
*
* @param URLString 請求的網址字符串
* @param parameters 請求的參數
* @param success 請求成功的回調
* @param failure 請求失敗的回調
*/
+(void)getWithURLString:(NSString*)URLString
parameters:(id)parameters
success:(void(^)(id responerObject))success
failure:(void(^)(NSError* error))failure;
/**
* 發(fā)送post請求
*
* @param URLString 請求的網址字符串
* @param parameters 請求的參數
* @param success 請求成功的回調
* @param failure 請求失敗的回調
*/
+(void)postWithURLString:(NSString*)URLString
parameters:(id)parameters
success:(void(^)(id responerObject))success
failure:(void(^)(NSError *error))failure;
/**
* 發(fā)送網絡請求
*
* @param URLString 請求的網址字符串
* @param parameters 請求的參數
* @param type 請求的類型
* @param success 請求成功的回調
* @param failure 請求失敗的回調
*/
+(void)requestWithURLString:(NSString*)URLString
parameters:(id)parameters
type:(HttpRequestType)type
success:(void(^)(id responseObject))success
failure:(void(^)(NSError* error))failure;
/**
* 上傳圖片
*
* @param URLString 請求的網址字符串
* @param parameters 請求的參數
* @param uploadParam上傳圖片的信息
* @param success 請求成功的回調
* @param failure 請求失敗的回調
*/
+(void)uploadWithURLString:(NSString *)URLString
parameters:(id)parameters
uploadParam:(CHUploadParam*)uploadParam
success:(void(^)())success
failure:(void(^)(NSError* error))failure;
@end
#import "CHHttpRequest.h"
#import "AFNetworking.h"
#import "CHUploadParam.h"
@implementation CHHttpRequest
#pragma mark -- GET請求
+(void)getWithURLString:(NSString *)URLString parameters:(id)parameters success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
//可以接受的類型
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//請求隊列的最大并發(fā)數
//manager.operationQueue.maxConcurrentOperationCount = 5;
//請求超時的時間
//manager.requestSerializer.timeoutInterval = 5;
[manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask* _Nonnull task,id _Nullable responseObject) {
//請求成功
success(responseObject);
}failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//請求失敗
if (failure) {
failure(error);
//輸出網絡診斷信息
__weak id weakSelf = self;
[weakSelf requestFailure:error];
}
}];
}
#pragma mark -- POST請求
+(void)postWithURLString:(NSString *)URLString parameters:(id)parameters success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//請求隊列的最大并發(fā)數
//manager.operationQueue.maxConcurrentOperationCount = 5;
//請求超時的時間
//manager.requestSerializer.timeoutInterval = 5;
[manager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//請求成功
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//請求失敗
if (failure) {
failure(error);
//輸出網絡診斷信息
__weak id weakSelf = self;
[weakSelf requestFailure:error];
}
}];
}
#pragma mark -- REQUEST請求
+(void)requestWithURLString:(NSString *)URLString parameters:(id)parameters type:(HttpRequestType)type success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPSessionManager* manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//請求隊列的最大并發(fā)數
//manager.operationQueue.maxConcurrentOperationCount = 5;
//請求超時的時間
//manager.requestSerializer.timeoutInterval = 5;
switch (type) {
case HttpRequestType_Get:
{
[manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//請求成功
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//請求失敗
if (failure) {
failure(error);
//輸出網絡診斷信息
__weak id weakSelf = self;
[weakSelf requestFailure:error];
}
}];
}
break;
case HttpRequestType_Post:
{
[manager POST:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//請求成功
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//請求失敗
if (failure) {
failure(error);
//輸出網絡診斷信息
__weak id weakSelf = self;
[weakSelf requestFailure:error];
}
}];
}
break;
}
}
#pragma mark -- 上傳圖片
+(void)uploadWithURLString:(NSString *)URLString parameters:(id)parameters uploadParam:(CHUploadParam *)uploadParam success:(void (^)())success failure:(void (^)(NSError *))failure
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//請求隊列的最大并發(fā)數
//manager.operationQueue.maxConcurrentOperationCount = 5;
//請求超時的時間
//manager.requestSerializer.timeoutInterval = 5;
[manager POST:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileData:uploadParam.data name:uploadParam.name fileName:uploadParam.fileName mimeType:uploadParam.mimeType];
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//請求成功
success(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//請求失敗
if (failure) {
failure(error);
//輸出網絡診斷信息
__weak id weakSelf = self;
[weakSelf requestFailure:error];
}
}];
}
#pragma mark -- requestFailure
-(void)requestFailure:(NSError *)error
{
switch (error.code) {
case AFNetworkErrorType_TimeOut:
NSLog(@"網絡連接超時");
break;
case AFNetworkErrorType_UnURL:
NSLog(@"沒有找到該網絡地址");
break;
case AFNetworkErrorType_NoNetwork:
NSLog(@"沒有網絡服務");
break;
case AFNetworkErrorType_404Failed:
NSLog(@"404網絡原因");
break;
case AFNetworkErrorType_3840Failed:
NSLog(@"服務器出錯");
break;
default:
NSLog(@"不明原因");
break;
}
}
@end
有個CHUploadParam的類是用來處理圖片上傳的,大家也要創(chuàng)建這個類的.h/.m旱眯,代碼如下:
@interface CHUploadParam : NSObject
//圖片二進制數據
@property (nonatomic,strong) NSData * data;
//服務器對應的參數名稱
@property (nonatomic,copy) NSString * name;
//文件的名稱
@property (nonatomic,copy) NSString * fileName;
//文件的MIME類型
@property (nonatomic,copy) NSString * mimeType;
@end
在這里以上的代碼是重要的晨川,基本上對我們要使用的AFNetworking里面的內容的封裝了。大家需要好好理解一下代碼删豺,我也都一一注釋了共虑。
那么這樣的封裝就能滿足我們的實際使用需求嗎?明顯是不行的呀页。雖然我們的使用方便了妈拌,但是在實際使用的時候,比如一個Controller蓬蝶,我們需要請求網絡圖片數據尘分,那么我們就需要在里面寫我們的網絡請求,寫json解析丸氛,寫UI使用培愁。omg,多長多亂呀缓窜。這里的網絡處理根本就不應該出現(xiàn)在Controller里面定续,這樣的設計是累贅的,高內聚的雹洗,不符合我們程序的設計理念。
所以我們來寫寫實際需求的代碼卧波,現(xiàn)在假設我們要從網絡上獲取一個json时肿,里面包含一個數組的字符串。我們如何來實現(xiàn):
首先我們需要用到一個model轉化庫Mantle港粱,同樣的方法導入螃成。然后我們來定義我們接收的model: CHListObject.h/.m
@interface CHListObject : MTLModel <MTLJSONSerializing>
@property (nonatomic, assign) NSInteger ID;
@property (nonatomic, strong) NSString *name;
@end
#import "CHListObject.h"
@implementation CHListObject
+(NSDictionary *)JSONKeyPathsByPropertyKey
{
return @{
@"ID":@"id",
@"name":@"name",
};
}
@end
我們將在我們的實際獲取代碼里面把json數據通過這個第三方庫轉換過來旦签,這是十分方便的。大家同樣需要去學一下Mantle的使用方法寸宏。(ps:是不是覺得要學很多東西宁炫,不要氣餒)
接下來是我們的獲取文件類CHServiceNetRequest.h/.m
#import <Foundation/Foundation.h>
#import "CHListObject.h"
typedef void(^Failure) (NSError* error);
@interface CHServiceNetRequest : NSObject
+(CHServiceNetRequest*)Instance;
/**
* 獲取列表信息
*
* @param token
* @param success
* @param failure
*/
+(void)getListWithToken:(NSString*)token
success:(void(^)(NSArray<CHListObject*> *list))success
failure:(Failure)failure;
@end
#import "CHServiceNetRequest.h"
#import "CHHttpRequest.h"
@implementation CHServiceNetRequest
//單例模式
+(CHServiceNetRequest*)Instance
{
static dispatch_once_t once_token;
static CHServiceNetRequest* service = nil;
if (service == nil) {
dispatch_once(&once_token,^{
service = [[CHServiceNetRequest alloc]init];
});
}
return service;
}
//需求下的網絡請求,返回CHListObject的數組
+(void)getListWithToken:(NSString *)token success:(void (^)(NSArray<CHListObject *> *))success failure:(Failure)failure
{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setObject:token forKey:@"token"];
//==token是什么東西氮凝,大家需要自己去了解一下==
[CHHttpRequest postWithURLString:@"這里寫入一個后臺地址" parameters:dic success:^(id responerObject) {
//請求成功
//如果和后臺溝通正確羔巢,這里的responerObject應該是一個json
//下面開始使用Mantle來處理獲取的json
NSArray* data = (NSArray*)responerObject;
//由于我們假設json里面是一個數組,所以我們用一個listArr來接收我們的網絡數據
NSMutableArray* listArr = [NSMutableArray array];
//取出數據
for (NSDictionary *dic in data) {
CHListObject *obj = [MTLJSONAdapter modelOfClass:[CHListObject class] fromJSONDictionary:dic error:nil];
[listArr addObject:obj];
}
//success輸出
if (success) {
success([listArr copy]);
}
} failure:^(NSError *error) {
//請求失敗
failure(error);
}];
}
@end
先在這里告訴大家罩阵,這樣已經ok了竿秆!實際使用時只需要使用CHServiceNetRequest里面的方法就行,具體在那個Controller里使用稿壁,直接返回我們json解析出來的listArr數據幽钢,Controller里面完全摒棄冗長的代碼量。
相信大家可能會跳著看以上的代碼傅是,可能也是感覺太長了匪燕,難以理解,所以有點放棄了喧笔。這里也不多說帽驯,相信大家還是能找到適合自己學習的方法的。bye溃斋!
聯(lián)系方式:401518215@qq.com