預期效果:方便、簡單調用,能夠定位具體的請求并cancel;
思路:類A做具體的請求事件,類B調用類A處理一些業務邏輯:網絡或者數據的加工等。
定義類A:QYNetwork 處理具體的請求
- 單列模式,方便調用
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static QYNetwork *sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[QYNetwork alloc] init];
});
return sharedInstance;
}
- 發起請求
- (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掉;在請求回調里面進行數據的解析和錯誤的預處理;
///對API返回的數據進行初始判斷
- (void)processingResponseObject:(id)responseObject
success:(CallBackBlock)success
fail:(CallBackBlock)fail {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
//TODO:解析code,返回具體數據,具體業務具體處理
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){
//網絡
!fail ?: fail(error.code,@"無網絡");
}
//...
}
- 請求cancel,根據tast的taskIdentifier取消task
- (void)cancelRequestWithRequestID:(NSNumber *)requestID {
NSURLSessionDataTask *requestOperation = self.dispatchTable[requestID];
[requestOperation cancel];
[self.dispatchTable removeObjectForKey:requestID];
}
定義類QYNetManager 讓上層調用
- 單列模式,方便調用
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static QYNetManager *sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[QYNetManager alloc] init];
});
return sharedInstance;
}
- 定義請求的類型:get、post...
- 網絡的監聽,AFNetWorking自帶,這里用RealReachability
- 上層的調用,返回task的taskIdentifier,業務層可以自處理
- (NSInteger)loadDataWithParameters:(NSDictionary *)parameters
path:(NSString *)path
methodType:(QYRequestType)methodType
success:(successBlock)success
failure:(failureBlock)failure {
NSInteger requestId = 0;
if ([self isReachability]) {//網絡狀態
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)]; \
}