异步发送比同步发送请求有不阻塞主线程和支持多线程发送请求的好处。
异步发送请求可以抽象为标准的代理对象,具有使用方便,可扩充性强,只要你足够牛可以写出比第三方控件更牛的发送模块,由于是你自己写的,可以根据自己的意愿对请求的各种细节进行处理。这个异步发送请求处理模块也是对苹果代理具体实现的经典案例。
chttpsendAsynchronousRequest.h
#import <Foundation/Foundation.h> @protocol chttpsendAsynchronousDelegate <NSObject> @required - (void)requestDidFinish:(NSString *)responseData responseType:(NSInteger)type; @end @interface chttpsendAsynchronousRequest : NSObject @property (strong, nonatomic) id <chttpsendAsynchronousDelegate> pSelfView; - (void)sendHttpRequest:(NSString*)sendString; - (void)sendImageDataToServer:(UIImage *)image; @end
chttpsendAsynchronousRequest.m
#import "chttpsendAsynchronousRequest.h" #import "config.h" @implementation chttpsendAsynchronousRequest @synthesize pSelfView; - (void)sendHttpRequest:(NSString*)sendString { //这个是服务器的地址,暂时随便写地址,不然就把用户的服务器信息泄密了 NSURL *serverNUSUrl = [NSURL URLWithString:@"http://120.139.148.144:8090/test/main.do"]; NSLog(@"sendString %@",sendString); NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:serverNUSUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60]; [request setHTTPMethod:@"POST"]; [request setValue:@"text.html" forHTTPHeaderField:@"Content-Type"]; NSString * sendData = sendString; NSData *postData = [sendData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody:postData]; [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if ([data length] >0 && error == nil && [httpResponse statusCode] == 200) { NSString * recvStrData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if(nil != recvStrData) { NSLog(@"recvStrData[%@]",recvStrData); } if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]) { [pSelfView requestDidFinish:recvStrData responseType:0]; } } else if ([data length] == 0 && error == nil && [httpResponse statusCode] == 200) { if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]){ [pSelfView requestDidFinish:nil responseType:1]; } } else { if (pSelfView && [pSelfView respondsToSelector:@selector(requestDidFinish:responseType:)]){ [pSelfView requestDidFinish:nil responseType:-1]; } } }]; return; } - (void)sendImageDataToServer:(UIImage *)image { //分界线的标识符 NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x"; NSString *urlString = @"http://192.168.2.77:8080/GUT/IOSServer"; NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10]; NSData *image2 = UIImagePNGRepresentation(image); NSMutableData *myRequestData=[NSMutableData data]; [myRequestData appendData:image2]; NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY]; [request setValue:content forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody:myRequestData]; [request setHTTPMethod:@"POST"]; //建立连接,设置代理 NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if(conn){ NSLog(@"连接成功"); } NSHTTPURLResponse *urlResponese = nil; NSError *error = [[NSError alloc]init]; NSData* resultData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponese error:&error]; NSString* result= [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; if([urlResponese statusCode] >=200&&[urlResponese statusCode]<300){ NSLog(@"返回结果=====%@",result); } //提示用户上传成功 需要判断返回的json NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"通知" message:@"图片上传成功" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil]; [alert show]; NSLog(@"%@",returnString); } @end
具体的应用。
发送请求部分:
- (void) searchNotificationMethodRequest { @try { HUD = [[MBProgressHUD alloc] initWithView:self.view]; [self.view addSubview:HUD]; //如果设置此属性则当前的view置于后台 HUD.dimBackground = NO; //设置对话框文字 HUD.labelText = @"请稍等..."; //显示对话框 [HUD showAnimated:YES whileExecutingBlock:^{ //对话框显示时需要执行的操作 [self myProgressTask]; //sleep(1); } completionBlock:^{ //操作执行完后取消对话框 [HUD removeFromSuperview]; HUD = nil; }]; chttpsendAsynchronousRequest *phttpsendAsynchronousRequest = [[chttpsendAsynchronousRequest alloc] init ]; NSString *messageString = nil; NSString *sendString = nil; //3. 构造数据 CHeadEncode *pHeadEncode = [[CHeadEncode alloc] init ]; messageString = [pHeadEncode headEncode : strToken : @"0x000C" : @"" : @"" : nil]; if((nil == messageString) || (nil == strVId)) { taskFlag = YES; dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... [self hudWasHidden:HUD]; }); return; } sendString = [NSString stringWithFormat:@"%@,\"body\":{\"v_id\":\"%@\"}}", messageString, strVId]; LogInfo(@"sendString = %@", sendString); //4. 发送数据 phttpsendAsynchronousRequest.pSelfView = self; [phttpsendAsynchronousRequest sendHttpRequest:sendString]; sendString = nil; } @catch (NSException *exception) { LogError(@"NSException : %@", exception); } @finally { } }
请求响应代理函数实现:
- (void)requestDidFinish:(NSString *)responseData responseType:(NSInteger)type { if(nil == responseData) { LogInfo(@"responseData = nil; Type:%d", type); } else { LogInfo(@"responseData: %@ Type:%d",responseData,type); } if (type == 0) { if(!_setState) { [self analyzeMessage:responseData]; } else { [self analyzeSettingMessage:responseData]; } } else { [self failHandle:type]; } } - (void)failHandle:(NSInteger) resultCode { taskFlag = YES; dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... [self hudWasHidden:HUD]; }); if(1 == resultCode) { dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"服务器异常!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil]; [alert show]; [theLock unlock]; //[self hudWasHidden:HUD]; //[self switchTaskWayBillSearchViewController]; //return; }); } else { dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"网络异常!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil]; [alert show]; [theLock unlock]; //[self hudWasHidden:HUD]; //[self switchTaskWayBillSearchViewController]; //return; }); } }
具体的对响应页面的处理部分:
- (void)analyzeMessage:(NSString *)recvData { LogInfo(@"recvData[%@]",recvData); dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 taskFlag = YES; [self hudWasHidden:HUD]; }); NSMutableDictionary *rootDic = [recvData JSONValue]; NSDictionary *headDic = [rootDic objectForKey:@"head"]; if(![self DecodeHeader:headDic]) { [theLock unlock]; return; } NSDictionary *bodDictionary = [rootDic objectForKey:@"body"]; self.next_page = [bodDictionary objectForKey:@"next_page"]; LogInfo(@"next_page : %@",self.next_page); NSMutableArray *bodyArr = [bodDictionary objectForKey:@"data_list"]; NSDictionary *bodyDic = nil; NSUInteger i = 0; for (i = 0; i < bodyArr.count; i++) { bodyDic = [bodyArr objectAtIndex:i]; CWaringInfo *waringinfo = [[CWaringInfo alloc] init]; NSString *feildStr = [bodyDic objectForKey:@"alarm_id"]; if(nil == feildStr) { [theLock unlock]; return; } else { [waringinfo setAlarm_id:feildStr]; } LogInfo(@"waringinfo = [%@]", feildStr); feildStr = [bodyDic objectForKey:@"alarm_name"]; if(nil == feildStr) { [theLock unlock]; return; } else { [waringinfo setAlarm_name:feildStr]; } LogInfo(@"waringinfo = [%@]", feildStr); feildStr = [bodyDic objectForKey:@"alarm_date"]; if(nil == feildStr) { [theLock unlock]; return; } else { [waringinfo setAlarm_date:feildStr]; } LogInfo(@"waringinfo = [%@]", feildStr); feildStr = [bodyDic objectForKey:@"alarm_desc"]; if(nil == feildStr) { [theLock unlock]; return; } else { [waringinfo setAlarm_desc:feildStr]; } LogInfo(@"waringinfo = [%@]", feildStr); [self.computers addObject:waringinfo]; } LogInfo(@"OldTaskArray = [%@]", self.computers); dispatch_async(dispatch_get_main_queue(), ^{ //更新UI操作 //..... [self.tableView reloadData]; [theLock unlock]; }); }