預(yù)期效果:方便玉组、簡單調(diào)用谎柄,能夠定位具體的請求并cancel;
思路:類A做具體的請求事件惯雳,類B調(diào)用類A處理一些業(yè)務(wù)邏輯:網(wǎng)絡(luò)或者數(shù)據(jù)的加工等朝巫。
定義類A:QYNetwork 處理具體的請求
- 單列模式,方便調(diào)用
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static QYNetwork *sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[QYNetwork alloc] init];
});
return sharedInstance;
}
- 發(fā)起請求
- (NSInteger)callGETWithParams:(NSDictionary *)params
methodName:(NSString *)methodName
success:(CallBackBlock)success
fail:(CallBackBlock)fail {
__block NSURLSessionDataTask *dataTask = nil;
kWeakSelf(self);
dataTask = [self.sessionManager GET:methodName parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
kStrongSelf(self);
///請求完成---移除
[self.dispatchTable removeObjectForKey:@([dataTask taskIdentifier])];
[self processingResponseObject:responseObject success:success fail:fail];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
kStrongSelf(self);
[self.dispatchTable removeObjectForKey:@([dataTask taskIdentifier])];
[self processingError:error fail:fail];
}];
self.dispatchTable[@([dataTask taskIdentifier])] = dataTask;
return dataTask.taskIdentifier;
}
以task的taskIdentifier作為鍵保存task石景,方便針對單個的請求進行cancel劈猿,請求完成后remove掉;在請求回調(diào)里面進行數(shù)據(jù)的解析和錯誤的預(yù)處理潮孽;
///對API返回的數(shù)據(jù)進行初始判斷
- (void)processingResponseObject:(id)responseObject
success:(CallBackBlock)success
fail:(CallBackBlock)fail {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
//TODO:解析code揪荣,返回具體數(shù)據(jù),具體業(yè)務(wù)具體處理
NSInteger code = [json[@"code"] integerValue];
if (code == 200) {
!success ?: success(code, json);
}else {
!fail ?: fail(code,json[@"message"]);
}
}
///處理錯誤事件
- (void)processingError:(NSError *)error
fail:(CallBackBlock)fail {
//TODO:提示
if (error.code == NSURLErrorTimedOut) {
//超時
!fail ?: fail(error.code,@"超時");
}else if (error.code == NSURLErrorCancelled){
//取消
}else if (error.code == NSURLErrorNetworkConnectionLost){
//網(wǎng)絡(luò)
!fail ?: fail(error.code,@"無網(wǎng)絡(luò)");
}
//...
}
- 請求cancel,根據(jù)tast的taskIdentifier取消task
- (void)cancelRequestWithRequestID:(NSNumber *)requestID {
NSURLSessionDataTask *requestOperation = self.dispatchTable[requestID];
[requestOperation cancel];
[self.dispatchTable removeObjectForKey:requestID];
}
定義類QYNetManager 讓上層調(diào)用
- 單列模式往史,方便調(diào)用
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static QYNetManager *sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[QYNetManager alloc] init];
});
return sharedInstance;
}
- 定義請求的類型:get仗颈、post...
- 網(wǎng)絡(luò)的監(jiān)聽,AFNetWorking自帶椎例,這里用RealReachability
- 上層的調(diào)用,返回task的taskIdentifier挨决,業(yè)務(wù)層可以自處理
- (NSInteger)loadDataWithParameters:(NSDictionary *)parameters
path:(NSString *)path
methodType:(QYRequestType)methodType
success:(successBlock)success
failure:(failureBlock)failure {
NSInteger requestId = 0;
if ([self isReachability]) {//網(wǎng)絡(luò)狀態(tài)
switch (methodType) {
case QYRequestType_GET:
QYCallAPI(GET,requestId);
break;
case QYRequestType_POST:
QYCallAPI(POST,requestId);
break;
default:
break;
}
}
return requestId;
}
定義的宏:
#define QYCallAPI(REQUEST_METHOD, REQUEST_ID) \
{ \
REQUEST_ID = [[QYNetwork sharedInstance] call##REQUEST_METHOD##WithParams:parameters methodName:path success:^(NSInteger code,id responseObject) { \
success(responseObject);\
} fail:^(NSInteger code,id responseObject) { \
failure(responseObject);\
}]; \
[self.requestIdList addObject:@(REQUEST_ID)]; \
}