数据存储之网络访问
- Get和Post请求
- 网络访问的步骤
- iOS网络处理常用类
- 具体处理
- 同步异步请求
一、Get和Post请求
Get
- Get获取制定URL上的资源
- 不安全,数据会被放在URL上
- 传输数量笑,主要因受URL长度限制
Post
- Post往服务器上追加数据
- 数据放在数据体中,按照变量和值相对应的方式,传递到action所指向的URl
- 数据对用户来说不可见
- 可以传输大数据,上传文件只能使用Post
二、网络访问的步骤
- 确定URL地址
- 建立请求
- 开始连接
- 连接成功,处理结果
三、iOS网络处理常用类
- NSURL
- NSURLRequest(Get方式)
- NSMutableURLRequest(Post方式)
- NSURLConnection
四、具体处理
1⃣️Get方式
- 确定地址
- 建立请求
- 建立连接
- 启动连接
- 实现4个代理方法
- (IBAction)getRequest:(id)sender { //1.创建URL NSString *urlString = [NSString stringWithFormat:@"http://169.254.68.33/~apple/itcast/login.php?username=%@&password=%@", _userName.text, _passWord.text]; NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; //2.建立请求 NSURLRequest *getRequest = [NSURLRequest requestWithURL:url]; //3.建立连接 NSURLConnection *getConn = [NSURLConnection connectionWithRequest:getRequest delegate:self]; [getConn start]; }
四个代理方法
#pragma mark - 连接代理方法 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"开始接受服务器的返回请求"); } // 这个方法会被多次调用啊,所以我们需要定义一个成员变量来记录完整的数据! - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // 1. 懒加载 if (_serverData == nil) { _serverData = [NSMutableData data]; } // 2. 追加数据 [_serverData appendData:data]; } //数据传输完成 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // 数据编码成NTF8格式的字符串 NSString *string = [[NSString alloc]initWithData:_serverData encoding:NSUTF8StringEncoding]; NSLog(@"编码后的字符串是:%@", string); // 释放原来接收的数据 _serverData = nil; } // 网络请求失败 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"%@", error.localizedDescription); _serverData = nil; }
2⃣️Post请求
其他一样,建立请求这一步
1.建立请求:
NSMutableURLRequest
2.指定请求超时时间:
[request setTimeoutInterval:5.0]
3.指定请求方法是Post,注意:如果是Post,必须去指定Http方法
[request setHTTPMethod:@“post”];
4.建立请求数据体(因为要讲数据体传输给服务器)
NSString *bodyString = [NSString stringWithFormat:@“username=%@&password=%@“, _userName.text, _passWord.text];
NSData *data = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
5.把数据体设置给请求
[request setHTTPBody:data];
- (IBAction)postLogin:(id)sender { // 整个步骤的顺序和Get方法是一样的,不过需要注意的是请求的处理! // 1. 确定地址URL NSString *urlString = @"http://169.254.68.33/~apple/itcast/login.php/"; NSURL *url = [NSURL URLWithString:urlString]; // 2. 建立请求 // 1)建立请求,是要修改请求,所以要用NSMutableURLRequest NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 2) 建立请求超时时间 [request setTimeoutInterval:5.0]; // 3) 指定请求方法是“POST”,注意,如果是POST,必须去指定HTTP方法。 [request setHTTPMethod:@"post"]; // 4) 建立请求"数据体",因为要把这个数据体传送给服务器。 NSString *bodyString = [NSString stringWithFormat:@"username=%@&password=%@", _userNameText.text, _passwordText.text]; // 将生成的字符串转换成数据 NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; // 5) 把数据体设置给请求 [request setHTTPBody:body]; // 3. 建立连接 NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self]; // 4. 启动连接 [conn start]; }
多的一个代理方法
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { NSLog(@"发送数据 %d %d %d", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); }
五、同步、异步请求
同步:必须要等到确定的结果,才可以继续处理(比如QQ登录)
异步:无需等待结果,同时请求(比如图片展示)
1.苹果提供了两个静态的方法来帮助程序员(同步一个、异步一个)
2.具体方法
1⃣️同步请求的几个参数
- NSURLRequest
- NSURLResponse (将指针地址放到参数里&response)
- NSError(将指针地址放到参数里&error)(写网络访问程序的时候,一定要有出错处理,提醒用户)
同步请求的方法一定会返回NSData,只有返回了结果,才会继续
// 建立Post登录请求 - (NSURLRequest *)postLoginRequest { // 整个步骤的顺序和Get方法是一样的,不过需要注意的是请求的处理! // 1. 确定地址URL NSString *urlString = @"http://169.254.68.11/~apple/itcast/login.php/"; // 这里不需要加百分号!,因为没有中文 NSURL *url = [NSURL URLWithString:urlString]; // 2. 建立请求 // 1)建立请求,是要修改请求,所以要用NSMutableURLRequest NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 2) 建立请求超时时间 [request setTimeoutInterval:5.0]; // 3) 指定请求方法是“POST”,注意,如果是POST,必须去指定HTTP方法。 // post字符串不区分大小写,POST [request setHTTPMethod:@"post"]; // 4) 建立请求"数据体",因为要把这个数据体传送给服务器。 NSString *bodyString = [NSString stringWithFormat:@"username=%@&password=%@", _userNameText.text, _passwordText.text]; NSLog(@"数据体字符串:%@", bodyString); // 将生成的字符串转换成数据 NSData *body = [bodyString dataUsingEncoding:NSUTF8StringEncoding]; NSLog(@"%@", body); // 5) 把数据体设置给请求 [request setHTTPBody:body]; // 返回了一个完整的用户登录请求 return request; } #pragma mark - 同步请求 - (IBAction)syncLogin:(id)sender { // 1. 获得登录请求 NSURLRequest *request = [self postLoginRequest]; // 2. 开始同步连接 // 同步请求需要几个参数 // 1) 请求,已经准备好了 // 2) 响应,所为响应,就是服务器给你的响应 // 3) 错误,因为网络连接有可能出错。 // 在写网络访问程序的时候,一定要有出错处理,提醒用户。 NSURLResponse *response = nil; NSError *error = nil; // 同步请求是一定返回结果才会继续的! NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; // 给一个错误的请求地址,有可能会延时网络访问时间 NSLog(@"访问完成"); // 3. 获取数据 // 可能会返回什么数据? // 1) 返回请求的结果!解码!!!!!解码成我们认识的字符串 // 2) 请求出现错误! // 3) 返回空数据! if (error != nil) { NSLog(@"访问出错:%@", error.localizedDescription); return; } if (data != nil) { NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; // 用户登录成功之后的处理 if (string.integerValue > 0) { NSLog(@"登录成功"); // 这里可以用navigationcontroller push 出去 } else { NSLog(@"请重新输入"); } NSLog(@"返回的内容是:%@", string); } else { NSLog(@"没有接收到数据!"); } } // 异步登录请求 - (IBAction)asyncLogin:(id)sender { // 1. 获得登录请求 NSURLRequest *request = [self postLoginRequest]; // 2. 异步登录请求 // 1) 第一个参数:请求,我们已经有了 // 2) 第二个参数:队列?所谓队列,就是在线程上面需要执行的任务列表 // 3) BLOCK,是一个块代码。【需要我们自己制定参数!】——翻译:完成处理,就是处理请求完成的事情 // 第1个参数:响应 // 第2个参数:数据 // 第3个参数:错误 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // 完成的时候有可能出现的情况有哪些 // 1. 有数据 // 2. 没数据 // 3. 有错误 if (data != nil && error == nil) { // 解码 NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", string); } else if (error == nil) { NSLog(@"接收到空数据"); } else { NSLog(@"网络请求错误%@", error.localizedDescription); } }]; }