美文网首页
NSURLConnection基本使用

NSURLConnection基本使用

作者: 不会打滚儿的狮子 | 来源:发表于2016-07-20 01:28 被阅读43次

    iOS开发网络篇—NSURLConnection基本使用

    一、NSURLConnection的常用类

    (1)NSURL:请求地址

    (2)NSURLRequest:封装一个请求,保存发给服务器的全部数据,包括一个NSURL对象,请求方法、请求头、请求体....

    (3)NSMutableURLRequest:NSURLRequest的子类

    (4)NSURLConnection:负责发送请求,建立客户端和服务器的连接。发送NSURLRequest的数据给服务器,并收集来自服务器的响应数据

    二、NSURLConnection的使用

    1.简单说明

    使用NSURLConnection发送请求的步骤很简单

    (1)创建一个NSURL对象,设置请求路径(设置请求路径)

    (2)传入NSURL创建一个NSURLRequest对象,设置请求头和请求体(创建请求对象)

    (3)使用NSURLConnection发送NSURLRequest(发送请求)

    2.代码示例

    (1)发送请求的三个步骤:

    1.设置请求路径

    2.创建请求对象

    3.发送请求

    3.1发送同步请求(一直在等待服务器返回数据,这行代码会卡住,如果服务器,没有返回数据,那么在主线程UI会卡住不能继续执行操作)有返回值

    3.2发送异步请求:没有返回值

    说明:任何NSURLRequest默认都是get请求。

    (2)发送同步请求代码示例:

    9#import"YYViewController.h"

    10#import"MBProgressHUD+MJ.h"

    11

    12@interfaceYYViewController ()

    13@property (weak, nonatomic) IBOutlet UITextField *username;

    14@property (weak, nonatomic) IBOutlet UITextField *pwd;

    15- (IBAction)login;

    16

    17@end

    18

    19@implementationYYViewController

    20

    21- (IBAction)login {

    22//1.提前的表单验证

    23if(self.username.text.length==0) {

    24[MBProgressHUD showError:@"请输入用户名"];

    25return;

    26}

    27if(self.pwd.text.length==0) {

    28[MBProgressHUD showError:@"请输入密码"];

    29return;

    30}

    31//2.发送请求给服务器(带上账号和密码)

    32//添加一个遮罩,禁止用户操作

    33//[MBProgressHUD showMessage:@"正在努力加载中...."];

    34//GET请求:请求行\请求头\请求体

    35//

    36//1.设置请求路径

    37NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];

    38NSURL *url=[NSURL URLWithString:urlStr];

    39//2.创建请求对象

    40NSURLRequest *request=[NSURLRequest requestWithURL:url];

    41//3.发送请求

    42//发送同步请求,在主线程执行

    43NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    44//(一直在等待服务器返回数据,这行代码会卡住,如果服务器没有返回数据,那么在主线程UI会卡住不能继续执行操作)

    45NSLog(@"--%d--",data.length);

    46}

    47@end

    模拟器情况:

    打印服务器返回的信息:

    补充说明:

    1.提前的表单验证

    2.发送请求给服务器(带上账号和密码)

    GET请求:请求行\请求头\请求体

    注意:GET请求中不存在请求体,因为所有的信息都写在URL里面。在IOS里面,请求行和请求头都不用写。

    (3)发送异步请求

    发送异步请求有两种方式:

    1)使用block回调

    2)代理

    A.使用block回调方法发送异步请求

    使用block回调代码示例:

    7//

    8

    9#import"YYViewController.h"

    10#import"MBProgressHUD+MJ.h"

    11

    12@interfaceYYViewController ()

    13@property (weak, nonatomic) IBOutlet UITextField *username;

    14@property (weak, nonatomic) IBOutlet UITextField *pwd;

    15- (IBAction)login;

    16

    17@end

    18

    19@implementationYYViewController

    20

    21- (IBAction)login {

    22//1.提前的表单验证

    23if(self.username.text.length==0) {

    24[MBProgressHUD showError:@"请输入用户名"];

    25return;

    26}

    27if(self.pwd.text.length==0) {

    28[MBProgressHUD showError:@"请输入密码"];

    29return;

    30}

    31//2.发送请求给服务器(带上账号和密码)

    32//添加一个遮罩,禁止用户操作

    33[MBProgressHUD showMessage:@"正在努力加载中...."];

    34

    35//

    36//1.设置请求路径

    37NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];

    38NSURL *url=[NSURL URLWithString:urlStr];

    39

    40//2.创建请求对象

    41NSURLRequest *request=[NSURLRequest requestWithURL:url];

    42

    43//3.发送请求

    44//3.1发送同步请求,在主线程执行

    45//NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    46//(一直在等待服务器返回数据,这行代码会卡住,如果服务器没有返回数据,那么在主线程UI会卡住不能继续执行操作)

    47

    48//3.1发送异步请求

    49//创建一个队列(默认添加到该队列中的任务异步执行)

    50//NSOperationQueue *queue=[[NSOperationQueue alloc]init];

    51//获取一个主队列

    52NSOperationQueue *queue=[NSOperationQueue mainQueue];

    53[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

    54NSLog(@"--block回调数据--%@---%d", [NSThread currentThread],data.length);

    55//隐藏HUD,刷新UI的操作一定要放在主线程执行

    56[MBProgressHUD hideHUD];

    57

    58//解析data

    59/*

    60{"success":"登录成功"}

    61{"error":"用户名不存在"}

    62{"error":"密码不正确"}

    63*/

    64NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];

    65NSLog(@"%@",dict);

    66

    67//判断后,在界面提示登录信息

    68NSString *error=dict[@"error"];

    69if(error) {

    70[MBProgressHUD showError:error];

    71}else

    72{

    73NSString *success=dict[@"success"];

    74[MBProgressHUD showSuccess:success];

    75}

    76}];

    77NSLog(@"请求发送完毕");

    78}

    79@end

    模拟器情况(注意这里使用了第三方框架):

    打印查看:

    代码说明:

    block代码段:当服务器有返回数据的时候调用会开一条新的线程去发送请求,主线程继续往下走,当拿到服务器的返回数据的数据的时候再回调block,执行block代码段。这种情况不会卡住主线程。

    队列的作用:决定这个block操作放在哪个线程执行?

    刷新UI界面的操作应该放在主线程执行,不能放在子线程,在子线程处理UI相关操作会出现一些莫名的问题。

    提示:

    (1)创建一个操作,放在NSOperation队列中执行,默认是异步执行的。

    (2)mainqueue   返回一个和主线程相关的队列,即主队列。

    新的问题:如果向服务器发送请求,却并没有拿到数据,那么程序会崩溃(data不能为空)

    改进代码:

    1NSOperationQueue *queue=[NSOperationQueue mainQueue];2[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {3//当请求结束的时候调用(有两种结果,一个是成功拿到数据,也可能没有拿到数据,请求失败)4NSLog(@"--block回调数据--%@---%d", [NSThread currentThread],data.length);5//隐藏HUD,刷新UI的操作一定要放在主线程执行6[MBProgressHUD hideHUD];78//解析data9/*10{"success":"登录成功"}11{"error":"用户名不存在"}12{"error":"密码不正确"}13*/14if(data) {//请求成功15NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];16NSLog(@"%@",dict);1718//判断后,在界面提示登录信息19NSString *error=dict[@"error"];20if(error) {21[MBProgressHUD showError:error];22}else23{24NSString *success=dict[@"success"];25[MBProgressHUD showSuccess:success];26}27}else//请求失败28{29[MBProgressHUD showError:@"网络繁忙,请稍后重试!"];30}3132}];

    解析data

    //解析data/*{"success":"登录成功"}

    {"error":"用户名不存在"}

    {"error":"密码不正确"}*/

    说明:使用NSJSONSerialization 返回的对象,取决于最外层是什么,如果是{}那就是字典,[]那就是数组等。

    补充说明:

    首先确定请求路径,然后创建请求对象(默认发送的时get请求),使用异步方法(一调用这个方法,它会自动开启一个子线程去发送请求,当请求成功,数据返回的时候自动调用内部的代码段,这个代码段在那个线程执行取决于队列,如果是主队列,那么在子线程发送请求成功拿到服务器的数据后,回到主线程中解析数据,刷新UI界面)。

    B.使用代理方法发送异步请求

    要监听服务器返回的data,所以使用协议

    常见大代理方法如下:

    1#pragmamark- NSURLConnectionDataDelegate代理方法23//当接收到服务器的响应(连通了服务器)时会调用45-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response67//当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)89-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1011//当服务器的数据加载完毕时就会调用1213-(void)connectionDidFinishLoading:(NSURLConnection *)connection1415//请求错误(失败)的时候调用(请求超时\断网\没有网\,一般指客户端错误)1617-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

    使用异步方法发送get请求的代码示例:

    9#import"YYViewController.h"

    10#import"MBProgressHUD+MJ.h"

    11

    12@interfaceYYViewController ()

    13@property (weak, nonatomic) IBOutlet UITextField *username;

    14@property (weak, nonatomic) IBOutlet UITextField *pwd;

    15@property(nonatomic,strong)NSMutableData *responseData;

    16- (IBAction)login;

    17

    18@end

    19

    20@implementationYYViewController

    21

    22- (IBAction)login {

    23//1.提前的表单验证

    24if(self.username.text.length==0) {

    25[MBProgressHUD showError:@"请输入用户名"];

    26return;

    27}

    28if(self.pwd.text.length==0) {

    29[MBProgressHUD showError:@"请输入密码"];

    30return;

    31}

    32//2.发送请求给服务器(带上账号和密码)

    33//添加一个遮罩,禁止用户操作

    34[MBProgressHUD showMessage:@"正在努力加载中...."];

    35

    36//

    37//2.1设置请求路径

    38NSString *urlStr=[NSString stringWithFormat:@"http://192.168.1.53:8080/MJServer/login?username=%@&pwd=%@",self.username.text,self.pwd.text];

    39NSURL *url=[NSURL URLWithString:urlStr];

    40

    41//2.2创建请求对象

    42//NSURLRequest *request=[NSURLRequest requestWithURL:url];//默认就是GET请求

    43//设置请求超时

    44NSMutableURLRequest *request=[NSMutableURLRequest  requestWithURL:url];

    45request.timeoutInterval=5.0;

    46

    47//2.3.发送请求

    48//使用代理发送异步请求(通常应用于文件下载)

    49NSURLConnection *conn=[NSURLConnection connectionWithRequest:requestdelegate:self];

    50[conn start];

    51NSLog(@"已经发出请求---");

    52}

    53

    54#pragmamark- NSURLConnectionDataDelegate代理方法

    55/*

    56*当接收到服务器的响应(连通了服务器)时会调用

    57*/

    58-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

    59{

    60NSLog(@"接收到服务器的响应");

    61//初始化数据

    62self.responseData=[NSMutableData data];

    63}

    64

    65/*

    66*当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)

    67*/

    68-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    69{

    70NSLog(@"接收到服务器的数据");

    71//拼接数据

    72[self.responseData appendData:data];

    73NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);

    74}

    75

    76/*

    77*当服务器的数据加载完毕时就会调用

    78*/

    79-(void)connectionDidFinishLoading:(NSURLConnection *)connection

    80{

    81NSLog(@"服务器的数据加载完毕");

    82//隐藏HUD

    83[MBProgressHUD hideHUD];

    84

    85//处理服务器返回的所有数据

    86NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:nil];

    87

    88//判断后,在界面提示登录信息

    89NSString *error=dict[@"error"];

    90if(error) {

    91[MBProgressHUD showError:error];

    92}else

    93{

    94NSString *success=dict[@"success"];

    95[MBProgressHUD showSuccess:success];

    96}

    97NSLog(@"%d---%@--",self.responseData.length,[NSThread currentThread]);

    98}

    99/*

    100*请求错误(失败)的时候调用(请求超时\断网\没有网\,一般指客户端错误)

    101*/

    102-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

    103{

    104//NSLog(@"请求错误");

    105//隐藏HUD

    106[MBProgressHUD hideHUD];

    107[MBProgressHUD showError:@"网络繁忙,请稍后重试!"];

    108}

    109@end

    打印查看:

    补充:

    (1)数据的处理

    在didReceiveData:方法中,拼接接收到的所有数据,等所有数据都拿到后,在connectionDidFinishLoading:方法中进行处理

    (2)网络延迟

    在做网络开发的时候,一定要考虑到网络延迟情况的处理,可以在服务器的代码设置一个断点模拟。

    在服务器代码的登录方法中设置断点

    设置请求的最大延迟

    模拟器情况:

    打印查看:

    三、NSMutableURLRequest

    NSMutableURLRequest是NSURLRequest的子类,常用方法有

    设置请求超时等待时间(超过这个时间就算超时,请求失败)- (void)setTimeoutInterval:(NSTimeInterval)seconds;

    设置请求方法(比如GET和POST)- (void)setHTTPMethod:(NSString *)method;

    设置请求体- (void)setHTTPBody:(NSData *)data;

    设置请求头- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;

    相关文章

      网友评论

          本文标题:NSURLConnection基本使用

          本文链接:https://www.haomeiwen.com/subject/yktrjttx.html