Get & Post请求
•网络访问的四个步骤
–地址
–请求
–连接
–处理结果
•iOS网络处理常用类
–NSURL(地址)
–NSRequest[GET]& NSMutableURLRequest[POST](请求)
–NSConnection(连接)
•实现NSURLConnectionDataDelegate代理方法可以接收服务器响应数据(处理结果)
关于代理的方法:
•代理方法存在的问题
–代理方法较多,比较分散
–要处理一个请求,需要在很多地方编写代码
–不利于逻辑实现、代码编写、调试、维护以及扩展
–尤其当存在多个请求时会变得非常麻烦!
•已经学习过的代理方法
–UIApplicationDelegate
–UITableViewDelegate、UITableViewDataSource
–UITextFieldDelegate
–通过协议自定义代理方法
–NSURLConnectionDataDelegate
同步和异步请求:
•NSURLConnection提供了两个静态方法可以直接同步或异步调用NSURLRequest,而无需通过NSURLConnectionDataDelegate获取数据
•同步请求:
sendSynchronousRequest:request returningResponse:&response error:&error
•异步请求:
sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
有关主操作队列的内容,在多线程课程讲解
缓存策略:
•NSURLRequest的cachePolicy属性可以设置缓存策略,这是一种内存缓存,非硬盘缓存
•使用缓存的目的是为了使用的应用程序能更快速的响应用户输入,使程序高效的运行。有时候我们需要将远程web服务器获取的数据缓存起来,减少对同一个url多次请求
•cachePolicy支持的缓存策略包括:
–NSURLRequestUseProtocolCachePolicy 默认的缓存策略,要在协议的实现方法中指定缓存逻辑
–NSURLRequestReloadIgnoringCacheData 忽略缓存从原始地址下载
–NSURLRequestReturnCacheDataElseLoad 没有缓存时从原始地址下载
–NSURLRequestReturnCacheDataDontLoad 只使用缓存,如果不存在缓存,请求失败,适用于没有建立网络连接离线模式
–NSURLRequestReloadIgnoringLocalAndRemoteCacheData 忽略本地和远程的缓存数据,直接从原始地址下载,与NSURLRequestReloadIgnoringCacheData类似
–NSURLRequestReloadRevalidatingCacheData 验证本地数据与远程数据是否相同,如果不同则下载远程数据,否则使用本地数据
同步请求数据会造成主线程阻塞,通常在请求大数据或网络不畅时不建议使用。
从上面的代码可以看出,不管同步请求还是异步请求,建立通信的步骤基本是一样的:
1、创建NSURL
2、创建Request对象
3、创建NSURLConnection连接。
NSURLConnection创建成功后,就创建了一个http连接。异步请求和同步请求的区别是:创建了异步请求,用户可以做其他的操作,请求会在另一个线程执行,通信结果及过程会在回调函数中执行。同步请求则不同,需要请求结束用户才能做其他的操作。
(今天学习关于网络的基础,代码有一些重复,缓存策略还没有学习)
下面是get和post方式的代码:
#pragma mark - 测试get方式 -(IBAction)getLogin:(UIButton *)btn { static NSString * loginUrl =@"http://192.168.1.102:8080/IOSApplication/LoginServletController.do"; //初始化数据 _receiveDate = [NSMutableData data]; //定义URL NSString * urlStr = [NSString stringWithFormat:@"%@?username=%@&password=%@",loginUrl,_userName.text,_password.text]; // 注意:网络请求的URL,需要编码才可以使用!!!_ NSURL *url = [NSURL URLWithString:urlStr]; //// 定义请求 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //定义连接 NSURLConnection *cont = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [cont start]; } #pragma mark - 网络连接错误判断 -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"网络连接错误%@",error.localizedDescription); } #pragma mark - 接收响应 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"开始接收的响应"); } #pragma mark - 收到数据 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"收到服务器返回的数据:%@",data); [_receiveDate appendData:data]; } #pragma mark - 连接结束 -(void)connectionDidFinishLoading:(NSURLConnection *)connection { NSString *backString = [[NSString alloc]initWithData:_receiveDate encoding:NSUTF8StringEncoding]; NSLog(@"结束接收的数据 %@",backString); _receiveDate = nil; } #pragma mark - 测试post方式 -(IBAction)postLogin:(UIButton *)btn { static NSString * loginUrl =@"http://192.168.1.102:8080/IOSApplication/LoginServletController.do"; //初始化数据 _receiveDate = [NSMutableData data]; // 定义URL,字母及数字组成的url不需要编码 NSURL * url = [NSURL URLWithString:loginUrl]; //定义请求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //等待服务器响应时间5 [request setTimeoutInterval:5.0]; //设置请求方式 [request setHTTPMethod:@"post"]; NSString *bodyString = [NSString stringWithFormat:@"username=%@&password=%@",_userName.text,_password.text]; //生成请求数据并编码 NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; // 设置HTTP请求数据体,NSMutableURLRequest会自动在请求头中加入Content-Length [request setHTTPBody:body]; //设置连接 NSURLConnection *cont = [[NSURLConnection alloc]initWithRequest:request delegate:self]; //开始连接 [cont start]; } #pragma mark - 发送数据给服务器,POST请求使用此方法 - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { NSLog(@"发送数据给服务器 bytesWritten: %ld, totalBytesWritten %ld totalBytesExpectedToWrite %ld", bytesWritten,totalBytesWritten,totalBytesExpectedToWrite); }
下面是同步和异步(NSURLConnection提供了两个静态方法可以直接同步或异步调用NSURLRequest,而无需通过NSURLConnectionDataDelegate获取数据)
//生成post请求 -(NSMutableURLRequest *)postLoginRequest { static NSString * loginUrl =@"http://192.168.1.102:8080/IOSApplication/LoginServletController.do"; //初始化数据 _receiveDate = [NSMutableData data]; // 定义URL,字母及数字组成的url不需要编码 NSURL * url = [NSURL URLWithString:loginUrl]; //定义请求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //等待服务器响应时间5 [request setTimeoutInterval:5.0]; //设置请求方式 [request setHTTPMethod:@"post"]; NSString *bodyString = [NSString stringWithFormat:@"username=%@&password=%@",_userName.text,_password.text]; //生成请求数据并编码 NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; // 设置HTTP请求数据体,NSMutableURLRequest会自动在请求头中加入Content-Length [request setHTTPBody:body]; return request; } #pragma mark - post 同步方式登录 -(IBAction) synchronizationLogin:(UIButton *)btn { NSMutableURLRequest *request = [self postLoginRequest]; NSError *error; NSURLResponse *response; NSDate * date = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // 注意,只有同步请求结束之后,才会执行后续操作,修改LOGIN_URL可以看到效果 if (!date) { NSLog(@"同步访问错误:%@",error.localizedDescription); } else{ //解码数据 NSString *string = [[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding]; NSLog(@"同步数据 %@",string); } } #pragma mark - post 异步方式登录 -(IBAction)asynchronizationLogin:(UIButton *)btn { NSMutableURLRequest *request = [self postLoginRequest]; // 注意此处使用了块代码!异步请求队列使用的是操作队列的主队列 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { if([data length]>0 && connectionError==nil) { NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"异步成功返回的数据%@",string); } else if ([data length] <=0 && connectionError==nil) { NSLog(@"没有接收到返回数据"); } else { NSLog(@"异步访问错误%@",connectionError.localizedDescription); } }]; }