基于Afnetworking 网络层的封装
程序员文章站
2022-04-14 13:12:34
LSAFHTTPClient 对所有请求进行统一管理,添加了两个队列:一个工作队列,一个读写缓存的io队列 LSAFHTTPClient.h 代码如下: LSAFHTTPClient.m 代码如下: LSBaseRequest 实现网络层的统一请求,在子类请求中调用基类的请求方法。 LSBaseRe ......
LSAFHTTPClient 对所有请求进行统一管理,添加了两个队列:一个工作队列,一个读写缓存的io队列
LSAFHTTPClient.h 代码如下:
1 #import "AFNetworking.h" 2 3 @interface LSAFHTTPClient : AFHTTPRequestOperationManager 4 5 @property (nonatomic, strong) dispatch_queue_t workQueue;//Serail Send Request Queue 6 @property (nonatomic, strong) dispatch_queue_t iOSerialQueue; 7 8 +(LSAFHTTPClient*)shareClient; 9 10 typedef void (^LSRequestResultBlock)(id result, NSError *err); 11 12 -(BOOL)isHttpQueueFinished:(NSArray*)httpUrlArray; 13 @end
LSAFHTTPClient.m 代码如下:
1 #import "LSAFHTTPClient.h" 2 #import "LSBaseRequest.h" 3 #import "LSHelper.h" 4 #import "AFHTTPRequestOperation.h" 5 #import "AFURLConnectionOperation.h" 6 #import "LSPathMacro.h" 7 #import <Foundation/Foundation.h> 8 @implementation LSAFHTTPClient 9 10 +(LSAFHTTPClient*)shareClient 11 { 12 static LSAFHTTPClient* _shareClient; 13 static dispatch_once_t onceToken; 14 dispatch_once(&onceToken, ^{ 15 _shareClient = [[LSAFHTTPClient alloc]initWithBaseURL:[NSURL URLWithString:LSURLHeadStatic]]; 16 [_shareClient.requestSerializer setTimeoutInterval:15]; //网络超时时间15S 17 18 //一个工作队列,一个读写缓存的io队列 19 _shareClient.workQueue = dispatch_queue_create("com.shareClient.workQueue", DISPATCH_QUEUE_SERIAL); 20 _shareClient.iOSerialQueue = dispatch_queue_create("com.shareClient.iOSerialQueue", DISPATCH_QUEUE_SERIAL); 21 }); 22 return _shareClient; 23 } 24 25 - (id)initWithBaseURL:(NSURL *)url 26 { 27 self = [super initWithBaseURL:url]; 28 29 if (!self) { 30 return nil; 31 } 32 return self; 33 } 34 - (void)dealloc 35 { 36 37 } 38 -(BOOL)isHttpQueueFinished:(NSArray*)httpUrlArray 39 { 40 NSLog(@"%ld",self.operationQueue.operationCount); 41 if(self.operationQueue.operationCount==0){ 42 return YES; 43 } 44 45 //add filter urlString.length==0 46 NSMutableArray* urlArray = [NSMutableArray array]; 47 for (NSString* currentUrl in httpUrlArray) { 48 if (currentUrl.length != 0) { 49 [urlArray addObject:currentUrl]; 50 } 51 } 52 53 //urlArray is empty 54 if(urlArray.count == 0){ 55 return YES; 56 } 57 58 for (AFHTTPRequestOperation* operation in self.operationQueue.operations) { 59 NSString* url = operation.request.URL.absoluteString; 60 for (NSString* baseUrl in urlArray) { 61 if ([url rangeOfString:baseUrl].location!=NSNotFound) { 62 return NO; 63 } 64 } 65 } 66 return YES; 67 } 68 @end
LSBaseRequest 实现网络层的统一请求,在子类请求中调用基类的请求方法。
LSBaseRequest.h 代码如下:
1 #import <Foundation/Foundation.h> 2 #import "LSAFHTTPClient.h" 3 #import "LSGlobal.h" 4 #import "LSBaseState.h" 5 #import "LSErrorState.h" 6 #import "LSSuccessState.h" 7 #import "AESCrypt.h" 8 9 typedef enum{ 10 LSREQUESTMETHODGET=0, 11 LSREQUESTMETHODPOST=1 12 }LSREQUESTMETHOD; 13 14 @class LSBaseRequest; 15 16 @interface LSBaseRequest : NSObject 17 18 @property(nonatomic) LSREQUESTMETHOD requestMethod; //请求方式 19 @property(nonatomic, strong) NSString *methodName; //方法名 20 @property(nonatomic, strong) NSString *event; //触发事件 21 @property(nonatomic, strong) NSString *cache; //是否缓存 22 @property(nonatomic) BOOL isGzip; //是否压缩 23 @property (strong,nonatomic) id result; 24 @property(nonatomic, assign) long ret; //标识数据否更新 25 @property (strong,nonatomic)NSMutableDictionary* parametersDic; //参数字典 json 26 27 /** 重复次数 */ 28 @property(nonatomic, assign) NSInteger numOfRepeat;//网络请求失败后重复的次数 29 30 /** 31 @brief 网络错误码,通过此错误码可以判断出是否是取消请求造成网络失败,从而不需要显示无数据,7.11加 32 @note kCFURLErrorCancelled为取消请求 33 */ 34 @property (nonatomic, assign) NSInteger network_error_code; 35 36 - (void)setIntegerValue:(NSInteger)value forKey:(NSString *)key; 37 - (void)setDoubleValue:(double)value forKey:(NSString *)key; 38 - (void)setLongLongValue:(long long)value forKey:(NSString *)key; 39 - (void)setBOOLValue:(BOOL)value forKey:(NSString *)key; 40 - (void)setValue:(id)value forKey:(NSString *)key; 41 42 -(void)sendRequestSuccFinishBlock:(void(^)(LSBaseRequest* request))requestFinishBlock requestFailFinishBlock:(void(^)(LSBaseRequest* request))requestFailFinishBlock; 43 -(void)sendUpdateImageRequestSuccFinishBlock:(void(^)(LSBaseRequest* request))requestFinishBlock requestFailFinishBlock:(void(^)(LSBaseRequest* request))requestFailFinishBlock withImageData:(NSData*)imgData; 44 /* 45 * @brief 服务器返回的数据解析成功后会调用 46 * @note 可以访问self.result得到服务器返回的结果,一定是NSDictionary类型。 47 * @note 对网络请求的数据结果进行封装(可选) 子类实现 48 */ 49 -(id)processResultWithDic:(NSMutableDictionary*)resultDic; 50 51 /* 52 *@brief 请使用此方法取消网络请求 53 */ 54 +(void)cancelRequest; 55 56 /** 57 * @note 用户初始化子类request,调用完毕self.methodName=@"xxxx"后,此getUrlName方法有效。 58 * @note 否则返回为空字符串. @"" 59 * @note 不允许子类实现 60 */ 61 +(NSString*)getUrlName; 62 /** 63 * @brief 此方法可以根据传入的urlArray判断是否http已经完成 64 * @note don't OVERRIDE this method 65 */ 66 +(BOOL)isHttpQueueFinished:(NSArray*)httpUrlArray; 67 68 /** 69 * @brief 此方法可以根据传入的class类名判断是否http已经完成 70 * @note don't OVERRIDE this method 71 * @example 72 NSArray* classNameArray = @[@"LSUpdateDataRequest", @"LSSearchGoodsRequest", 73 @"LSGoodsListRequest", @"LSCinemaListRequest"]; 74 BOOL isFinished = [LSBaseRequest isHttpQueueFinishedWithClassNameArray:classNameArray]; 75 */ 76 +(BOOL)isHttpQueueFinishedWithClassNameArray:(NSArray*)requestClassArray; 77 78 @end
LSBaseRequest.m 代码如下:
1 #import <objc/objc.h> 2 #import <objc/runtime.h> 3 #import "LSBaseRequest.h" 4 #import "LSDesUtil.h" 5 #import "AFHTTPRequestOperation.h" 6 #import "LSCacheFile.h" 7 #import "LSServerResult.h" 8 #import "NSString+LSAdditional.h" 9 10 #define LSBASEREQUEST_METHODNAME_KEY @"LSBASEREQUEST_METHODNAME_KEY" 11 //uncomment folling line if you need to test request performance 12 //#define ENABLE_LSBASEREQUEST_LOG 13 14 #ifdef ENABLE_LSBASEREQUEST_LOG 15 #define RequestLog(fmt, ...) NSLog((@"%s [Line %d] %@ " fmt), __PRETTY_FUNCTION__, __LINE__,self, ##__VA_ARGS__) 16 #else 17 #define RequestLog(fmt, ...) 18 #endif 19 20 @interface LSBaseRequest () 21 { 22 void(^_requestSuccFinishBlock)(LSBaseRequest*); 23 void(^_requestFailFinishBlock)(LSBaseRequest*); 24 25 NSMutableDictionary* _httpBodyDic; 26 NSString * _key; 27 NSString * _webtime; 28 29 BOOL _isResetBlock;//是否进行复位block 30 NSInteger _internalRet;//内部使用的ret 31 BOOL _isFailBlockFinish; 32 33 } 34 35 @end 36 37 @implementation LSBaseRequest 38 39 -(id)init 40 { 41 self = [super init]; 42 if (self){ 43 _requestMethod = LSREQUESTMETHODPOST; 44 _parametersDic = [[NSMutableDictionary alloc] init]; 45 _httpBodyDic = [[NSMutableDictionary alloc] init]; 46 self.numOfRepeat = 1; //默认网络请求失败请求3次 47 } 48 return self; 49 } 50 51 -(void)setMethodName:(NSString *)methodName 52 { 53 objc_setAssociatedObject([self class], LSBASEREQUEST_METHODNAME_KEY, methodName, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 54 _methodName = methodName; 55 } 56 - (void)setIntegerValue:(NSInteger)value forKey:(NSString *)key 57 { 58 [self setValue:[NSString stringWithFormat:@"%ld", value] forKey:key]; 59 } 60 - (void)setDoubleValue:(double)value forKey:(NSString *)key 61 { 62 [self setValue:[NSString stringWithFormat:@"%f", value] forKey:key]; 63 } 64 - (void)setLongLongValue:(long long)value forKey:(NSString *)key 65 { 66 [self setValue:[NSString stringWithFormat:@"%lld", value] forKey:key]; 67 } 68 - (void)setBOOLValue:(BOOL)value forKey:(NSString *)key 69 { 70 [self setValue:[NSString stringWithFormat:@"%d", value] forKey:key]; 71 } 72 - (void)setValue:(id)value forKey:(NSString *)key 73 { 74 //value只能是字符串,如果不是字符串类型,[LSHelper getSignParam]会crash,暂时未做处理。 75 if(!value){ 76 value = @""; 77 } 78 [_parametersDic setValue:value forKey:key]; 79 } 80 81 82 -(void)sendRequestSuccFinishBlock:(void(^)(LSBaseRequest* request))requestFinishBlock requestFailFinishBlock:(void(^)(LSBaseRequest* request))requestFailFinishBlock 83 { 84 _requestFailFinishBlock = requestFailFinishBlock; 85 _requestSuccFinishBlock = requestFinishBlock; 86 _isResetBlock = NO; 87 _isFailBlockFinish = NO; 88 self.result = nil; 89 //serail send request 90 // RequestLog(@"in MainThread begin send request"); 91 dispatch_async([LSAFHTTPClient shareClient].workQueue, ^{ 92 // RequestLog(@"serial send request"); 93 if (_requestMethod == LSREQUESTMETHODGET) { 94 [self doGetRequest]; 95 }else if(_requestMethod == LSREQUESTMETHODPOST){ 96 [self doPostRequest]; 97 } 98 }); 99 } 100 101 -(void)sendUpdateImageRequestSuccFinishBlock:(void(^)(LSBaseRequest* request))requestFinishBlock requestFailFinishBlock:(void(^)(LSBaseRequest* request))requestFailFinishBlock withImageData:(NSData*)imgData 102 { 103 _requestFailFinishBlock = requestFailFinishBlock; 104 _requestSuccFinishBlock = requestFinishBlock; 105 _isResetBlock = NO; 106 _isFailBlockFinish = NO; 107 self.result = nil; 108 //serail send request 109 // RequestLog(@"in MainThread begin send request"); 110 dispatch_async([LSAFHTTPClient shareClient].workQueue, ^{ 111 // RequestLog(@"serial send request"); 112 if (_requestMethod == LSREQUESTMETHODGET) { 113 [self doGetRequest]; 114 }else if(_requestMethod == LSREQUESTMETHODPOST){ 115 [self sendUpdateImageRequestWithData:imgData]; 116 } 117 }); 118 } 119 #pragma mark 发起Get或Post请求 120 -(void)doGetRequest 121 { 122 LSAFHTTPClient *httpClient = [LSAFHTTPClient shareClient]; 123 [self setparamesDic]; 124 httpClient.responseSerializer = [AFImageResponseSerializer serializer]; 125 [httpClient GET:_methodName parameters:_httpBodyDic success:^(AFHTTPRequestOperation *operation, id responseObject) { 126 self.result = responseObject; 127 _requestSuccFinishBlock(self); 128 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 129 [self handlerErrorResponse:error]; 130 }]; 131 132 } 133 134 -(void)doPostRequest 135 { 136 [self sendDataNumOfRepeat:self.numOfRepeat]; 137 //equestLog(@"serial postPath End"); 138 } 139 140 -(void)sendDataNumOfRepeat:(NSInteger)numOfRepeat{ 141 142 LSAFHTTPClient *httpClient = [LSAFHTTPClient shareClient]; 143 NSLog(@"%@", [httpClient.baseURL host]); 144 [self setparamesDic]; 145 146 httpClient.responseSerializer = [AFJSONResponseSerializer serializer]; 147 // [httpClient.requestSerializer setTimeoutInterval:15]; 148 [httpClient POST:_methodName parameters:_httpBodyDic success:^(AFHTTPRequestOperation *operation, id responseObject) { 149 //concurrent deal block 150 //RequestLog(@"concurrent deal block Success"); 151 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 152 [self hanleSuccessResponseWithOperation:operation response:responseObject]; 153 }); 154 155 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 156 //RequestLog(@"concurrent deal block Fail"); 157 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 158 if (numOfRepeat <= 1){ 159 [self handlerErrorResponse:error]; 160 }else{ 161 dispatch_async([LSAFHTTPClient shareClient].workQueue, ^{ 162 [self sendDataNumOfRepeat:numOfRepeat -1]; 163 }); 164 } 165 }); 166 167 }]; 168 } 169 170 - (void)sendUpdateImageRequestWithData:(NSData*)imgData 171 { 172 LSAFHTTPClient *httpClient = [LSAFHTTPClient shareClient]; 173 [self setparamesDic]; 174 [httpClient POST:@"member/upimg" parameters:_httpBodyDic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { 175 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 176 // 设置时间格式 177 formatter.dateFormat = @"yyyyMMddHHmmss"; 178 NSString *str = [formatter stringFromDate:[NSDate date]]; 179 NSString *fileName = [NSString stringWithFormat:@"%@.jpg", str]; 180 [formData appendPartWithFileData:imgData name:@"img" fileName:fileName mimeType:@"image/jpeg"]; 181 } success:^(AFHTTPRequestOperation *operation, id responseObject) { 182 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 183 [self hanleSuccessResponseWithOperation:operation response:responseObject]; 184 }); 185 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 186 [self handlerErrorResponse:error]; 187 }]; 188 189 } 190 191 192 - (void)sendImagData:(NSData*)imageData 193 { 194 195 LSAFHTTPClient *httpClient = [LSAFHTTPClient shareClient]; 196 [self setparamesDic]; 197 198 [httpClient POST:@"member/upimg" parameters:_httpBodyDic constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { 199 [formData appendPartWithFileData:imageData name:@"img" fileName:@"ios_header_img.jpg" mimeType:@"image/jpeg"]; 200 } success:^(AFHTTPRequestOperation *operation, id responseObject) { 201 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 202 [self hanleSuccessResponseWithOperation:operation response:responseObject]; 203 }); 204 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 205 [self handlerErrorResponse:error]; 206 }]; 207 208 209 } 210 211 212 -(void)setparamesDic 213 { 214 /* 215 body: params, time, sign, token 216 */ 217 218 NSString *device_name = [LSHelper deviceType]; 219 NSString *system_version = [LSHelper iOSVersion]; 220 NSString *timestamp = [LSHelper getTimeStamp]; 221 NSString *device_id = [LSHelper getCurrentDeviceUDID]; 222 NSString *device_type = @"ios"; 223 NSString *version_no = kSoftwareVersion; 224 NSString *token = [LSGlobal sharedGlobal].token; 225 NSString *channel_id = @"10000"; 226 227 [_httpBodyDic setValue:device_name forKey:@"device_name"]; 228 [_httpBodyDic setValue:system_version forKey:@"system_version"]; 229 [_httpBodyDic setValue:timestamp forKey:@"timestamp"]; 230 [_httpBodyDic setValue:token forKey:@"token"]; 231 [_httpBodyDic setValue:device_id forKey:@"device_id"]; 232 [_httpBodyDic setValue:device_type forKey:@"device_type"]; 233 [_httpBodyDic setValue:version_no forKey:@"version_no"]; 234 [_httpBodyDic setValue:channel_id forKey:@"channel_id"]; 235 [_httpBodyDic addEntriesFromDictionary:_parametersDic]; 236 237 //添加加密字段 238 [_httpBodyDic setValue:[NSString getSignPara:_httpBodyDic andTime:nil] forKey:@"security"]; 239 } 240 #pragma mark 读取写入缓存 241 -(void)readCacheFile 242 { 243 //sync read for webtime and serverKey 244 NSString *md5file_token = [self mdt5FileName:@"token"]; 245 NSDictionary *dic = [LSCacheFile readFileName:md5file_token]; 246 if (dic) { 247 _webtime = [dic objectForKey:@"webtime"]; 248 _key = [dic objectForKey:@"serverkey"]; 249 } 250 251 //async read for local content 252 dispatch_async([LSAFHTTPClient shareClient].iOSerialQueue, ^{ 253 NSString *md5file_local = [self mdt5FileName:@"local"]; 254 NSMutableDictionary* resultDic = [LSCacheFile readFileName:md5file_local]; 255 if(resultDic){ 256 [self handlerSuccFinishResponseWithDic:resultDic isWeb:NO serverResult:nil]; 257 } 258 }); 259 } 260 261 -(void)writeCacheFileWithKey:(NSString *)serverkey webtime:(NSString *)webtime resultDic:(id)resultDic 262 { 263 //async write to local and token file 264 dispatch_async([LSAFHTTPClient shareClient].iOSerialQueue, ^{ 265 if (!serverkey || !webtime) { 266 DLog(@"%@, ERROR:serverkey or webtime is nil, write to cache failed", self); 267 return ; 268 } 269 NSString *md5file_token = [self mdt5FileName:@"token"]; 270 NSDictionary *dic = @{@"webtime":webtime,@"serverkey":serverkey}; 271 [LSCacheFile writeFileName:md5file_token data:dic]; 272 NSString *md5file_local = [self mdt5FileName:@"local"]; 273 [LSCacheFile writeFileName:md5file_local data:resultDic]; 274 }); 275 } 276 #pragma mark 处理返回的结果 277 -(void)hanleSuccessResponseWithOperation:(AFHTTPRequestOperation *)operation response:(id)responseObject 278 { 279 [self handlerResponse:responseObject serverKey:nil des:nil webtime:nil]; 280 } 281 -(void)handlerResponse:(id)responseObject serverKey:(NSString *)serverkey des:(NSString *)des webtime:(NSString *)webtime 282 { 283 LSServerResult *serverResult = [[LSServerResult alloc] init]; 284 serverResult.serverKey = serverkey; 285 serverResult.webTime = webtime; 286 287 NSData* clearData = responseObject; 288 NSError *error = nil; 289 NSMutableDictionary* resultDic = (NSMutableDictionary*)clearData; 290 // if (clearData) { 291 // resultDic = [LSHelper parserJsonData:clearData]; 292 // if(![resultDic isKindOfClass:[NSDictionary class]]) 293 // { 294 // resultDic = nil; 295 // } 296 // } 297 if (clearData && !error) 298 { 299 if ([_cache isEqualToString:@"true"]) { 300 _internalRet = [[resultDic objectForKey:@"ret"] longValue]; 301 if (_internalRet != kNetRetFlag) { 302 serverResult.resultDic = resultDic; 303 [self handlerSuccFinishResponseWithDic:resultDic isWeb:YES serverResult:serverResult]; 304 } 305 else{ 306 //需要处理清空finishblock的情况。同时还注意不要将缓存清掉。 307 [self handlerSuccFinishResponseWithNetFlag]; 308 } 309 }else{ 310 [self handlerSuccFinishResponseWithDic:resultDic isWeb:YES serverResult:serverResult]; 311 } 312 }else{ 313 //数据不是json格式 314 [self handlerErrorResponse:nil]; 315 } 316 } 317 318 /** 如果缓存先返回,而且设置了resetBlock标记,网络返回99999时候进行reset。 */ 319 -(void)handlerSuccFinishResponseWithNetFlag 320 { 321 dispatch_async(dispatch_get_main_queue(), ^{ 322 if(_isResetBlock){ 323 [self resetFinishBlock]; 324 } 325 }); 326 } 327 /** @brief 获取数据完毕后的dic 328 * @param isWebFinish 是否是网络请求获取的字典 329 * @param resultDic 网络请求字典结果 330 */ 331 -(void)handlerSuccFinishResponseWithDic:(NSMutableDictionary*)resultDic isWeb:(BOOL)isWebFinish serverResult:(LSServerResult *)serverResult 332 { 333 RequestLog(@"concurrent deal block Success END. isWebFinish:%d", isWebFinish); 334 [self handleSuccessBlockWithDic:[self processResultWithDic:resultDic] isWeb:isWebFinish serverResult:serverResult]; 335 RequestLog(@"processResult end"); 336 } 337 -(void)handleSuccessBlockWithDic:(id)dic isWeb:(BOOL)isWebFinish serverResult:(LSServerResult *)serverResult 338 { 339 dispatch_async(dispatch_get_main_queue(), ^{ 340 RequestLog(@"in Main Thread begin"); 341 if (_requestSuccFinishBlock) { 342 self.result = dic; 343 344 _requestSuccFinishBlock(self); 345 346 if(isWebFinish){ 347 348 // [self writeCacheFileWithKey:serverResult.serverKey webtime:serverResult.webTime resultDic:serverResult.resultDic]; 349 [self resetFinishBlock]; 350 }else{//缓存返回 351 _isResetBlock = YES;//需要重置block 352 if(_internalRet == kNetRetFlag || _isFailBlockFinish){//网络已经返回且为99999。 ret有可能不等于99999,由handlerSuccFinishResponseWithNetFlag最后保证进行resetBlock 353 [self resetFinishBlock]; 354 } 355 } 356 } 357 RequestLog(@"in Main Thread End"); 358 }); 359 } 360 361 //网络返回错误后的处理 362 -(void)handlerErrorResponse:(NSError*)error 363 { 364 self.network_error_code = error.code; 365 [self handleErroBlock]; 366 } 367 -(void)handleErroBlock 368 { 369 dispatch_async(dispatch_get_main_queue(), ^{ 370 if (_requestFailFinishBlock) { 371 DLog(@"in Main Thread deal fail Block"); 372 _requestFailFinishBlock(self); 373 _isFailBlockFinish = YES; 374 if (self.result) { 375 [self resetFinishBlock]; 376 } 377 } 378 }); 379 } 380 -(void)resetFinishBlock 381 { 382 RequestLog(@""); 383 _requestSuccFinishBlock = nil; 384 _requestFailFinishBlock = nil; 385 } 386 387 /** 获得md5加密文件名*****/ 388 389 -(NSString *)mdt5FileName:(NSString *)ext{ 390 391 NSString *fileName = [LSHelper keyMD5StringWithParamDic:_parametersDic methodName:self.methodName]; 392 return [NSString stringWithFormat:@"%@_%@",fileName,ext]; 393 } 394 395 /* 396 * @brief 服务器返回的数据解析成功后会调用 397 * @note 可以访问self.result得到服务器返回的结果,一定是NSDictionary类型。 398 */ 399 400 -(id)processResultWithDic:(NSMutableDictionary*)resultDic 401 { 402 return resultDic; 403 } 404 +(void)cancelRequest 405 { 406 dispatch_async([LSAFHTTPClient shareClient].workQueue, ^{ 407 NSString* urlString = objc_getAssociatedObject([self class], LSBASEREQUEST_METHODNAME_KEY); 408 if (urlString.length) { 409 DLog(@" cancelRequestUrl == %@", urlString); 410 // [[LSAFHTTPClient shareClient] cancelAllHTTPOperationsWithMethod:nil path:urlString]; 411 [[LSAFHTTPClient shareClient] DELETE:urlString parameters:nil success:nil failure:nil]; 412 objc_setAssociatedObject([self class], LSBASEREQUEST_METHODNAME_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 413 } 414 else{ 415 DLog(@"WARNNING: cancelRequestUrl == nil"); 416 } 417 }); 418 } 419 420 - (NSString *)description 421 { 422 return NSStringFromClass([self class]); 423 } 424 425 -(void)dealloc 426 { 427 // DLog(@"%@", self); 428 } 429 /** 430 * 用户初始化后,此url才有效。 431 */ 432 +(NSString*)getUrlName 433 { 434 NSString* urlString = objc_getAssociatedObject([self class], LSBASEREQUEST_METHODNAME_KEY); 435 436 //为了外面使用isHttpQueueFinished的方便,不返回nil。 437 if(!urlString){ 438 urlString = @""; 439 } 440 return urlString; 441 } 442 443 +(BOOL)isHttpQueueFinished:(NSArray*)httpUrlArray 444 { 445 return [[LSAFHTTPClient shareClient]isHttpQueueFinished:httpUrlArray]; 446 } 447 448 +(BOOL)isHttpQueueFinishedWithClassNameArray:(NSArray*)requestClassArray 449 { 450 NSMutableArray* urlArray = [NSMutableArray array]; 451 452 for (NSString* className in requestClassArray) { 453 if (className.length == 0) { 454 continue; 455 } 456 457 Class currentClass = NSClassFromString(className); 458 if(!currentClass){ 459 continue; 460 } 461 462 if(![currentClass isSubclassOfClass:[LSBaseRequest class]]){ 463 DLog(@"WARNNING: currentClass is not subClassOfClass LSBaseRequest (%@)", currentClass); 464 continue; 465 } 466 467 NSString* urlName = [currentClass getUrlName]; 468 if(urlName.length > 0){ 469 [urlArray addObject:urlName]; 470 } 471 } 472 473 return [self isHttpQueueFinished:urlArray]; 474 } 475 476 @end
测试用例如下:
LsPlayRequest.h 代码如下:
1 #import "LSPlayRequest.h" 2 3 @interface LSPlayRequest : LSBaseRequest 4 5 - (id)initWithPlayRequestWithParamDic:(NSMutableDictionary*)param; 6 7 @end
LsPlayRequest.m 代码如下:
1 #import "LSPlayRequest.h" 2 3 @interface LSPlayRequest () 4 5 @end 6 7 @implementation LSPlayRequest 8 - (id)initWithPayRequestWithParamDic:(NSMutableDictionary*)param 9 { 10 self = [super init]; 11 if (self) { 12 self.methodName = @"play/index"; 13 self.requestMethod = LSREQUESTMETHODPOST; 14 self.parametersDic = param; 15 } 16 return self; 17 18 } 19 20 -(id)processResultWithDic:(NSMutableDictionary *)resultDic 21 { 22 NSError* err = nil; 23 if ([resultDic[@"code"] intValue]==1) { 24 return resultDic[@"data"]; 25 }else{ 26 LSErrorState *errorState = [LSErrorState alloc] initWithDictionary:resultDic error:&err]; 27 return errorState; 28 } 29 } 30 @end
下一篇: 详解C++纯虚函数与抽象类