iOS学习笔记(二十六)————网络通信

/ 0评 / 0

现在已经是移动互联网的时代了,所以我们的app也离不开互联网,那怎样与网络建立连接呢?这就涉及到了网络请求,之前我们已经介绍了一些基本的网络知识,下面我们就看一下iOS中是怎么实现网络请求的。
其实呢,app中的请求跟你在浏览器中的请求是一样的,都是基于HTTP协议的,只是某些参数不一样,最终的展示不一样而已,我们先来写一个php服务端脚本来处理请求。

if (isset($_GET['username'])  &&  $_GET['username'] != '') {
	if ($_GET['username'] == 'admin' && $_GET['password'] == '123456') {
		echo $_GET['username'] . '登陆成功';
	}else {
		echo '登录失败';
	}
}else if (isset($_POST['username'])  &&  $_POST['username'] != '') {
	if ($_POST['username'] == 'admin' && $_POST['password'] == '123456') {
		echo $_POST['username'] . '登陆成功';
	}else {
		echo '登录失败';
	}
}else{
	echo "非法请求\n";
}

在创建项目的时候要注意,Xcode 7之后默认支持的请求就是 https 了,所以我们要先将请求改为 http

internet visit 001

下面来看iOS中的 NSUrlConnection 这个请求库是怎么使用的

@interface ConnectionViewController (){
    NSMutableData *_buffer;//创建一个缓冲区
}

@end

@implementation ConnectionViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    self.edgesForExtendedLayout = UIRectEdgeNone;
    
    
    [self createUI];
}

- (void)createUI{
    UIButton *button1 = [[UIButton alloc] initWithFrame:CGRectMake(20, 40, 280, 50)];
    button1.backgroundColor = [UIColor purpleColor];
    [button1 setTitle:@"发送GET请求" forState:UIControlStateNormal];
    [button1 addTarget:self action:@selector(buttonClick1) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button1];
    
    UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(20, 100, 280, 50)];
    button2.backgroundColor = [UIColor purpleColor];
    [button2 setTitle:@"发送POST请求" forState:UIControlStateNormal];
    [button2 addTarget:self action:@selector(buttonClick2) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button2];
}

- (void)buttonClick1{
    //发送一个get请求(访问了一个接口)
    //接口文档
    NSString *username = @"admin";
    NSString *password = @"123456";
    
    NSString *string = [NSString stringWithFormat:@"http://localhost:80/webtest/index.php?username=%@&password=%@",username,password];
    
    /*
     
     http://localhost:80/webtest?username=%@&password=%@
     http:// 表示我们使用的是http协议
     127.0.0.1  本机的ip地址 (localhost)
     ip地址可以用来确定互联网中某一台电脑主机
     :80 服务器的端口号
     端口号可以帮我们确定到电脑上的某一个软件
     W  上下文路径(整个服务器项目的别名)
     ?  用来分割地址和参数的(表示后面要传参数了)
     username=admin  参数名=要传的参数的值
     &  用来拼接参数的(表示后面有下一个参数)
     
     */
    
    // 根据请求的地址创建一个URL对象
    NSURL *url = [NSURL URLWithString:string];
    
    // 创建一个请求对象
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    
    // 用请求对象去连接服务器
    [NSURLConnection connectionWithRequest:request delegate:self];
}


- (void)buttonClick2{
    // post请求参数不在地址后拼接
    NSString *string = @"http://127.0.0.1/webtest/index.php";
    
    NSURL *url = [NSURL URLWithString:string];
    
    // 因为要往请求数据区添加参数 所以需要创建可变的请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    // 拼接请求参数的
    // 字符串转化为data
    NSData *data = [@"username=admin&password=123456" dataUsingEncoding:NSUTF8StringEncoding];
    
    [request setValue:[NSString stringWithFormat:@"%ld",data.length] forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    
    // 设置请求数据(请求包体)
    [request setHTTPBody:data];

    // 设置请求方法
    [request setHTTPMethod:@"POST"];
    
    
    
    NSLog(@"====%@",request);
    
    
    [NSURLConnection connectionWithRequest:request delegate:self];
}

// 一次请求的过程中 不管数据量再大 收到响应的方法只会调用一次
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"收到响应了");
    
    _buffer = [[NSMutableData alloc] init];
}

// 如果数据量很大的情况下  收到数据这个方法 会调用很多次


//1234567890
//   12   34   56  78  90
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    NSLog(@"收到数据了");
    
    // 往缓冲区中追加数据
    [_buffer appendData:data];
    
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"数据接收完了");
    
    // 把data转化为字符串
    NSString *str = [[NSString alloc] initWithData:_buffer encoding:NSUTF8StringEncoding];
    
    NSLog(@"%@",[str stringByRemovingPercentEncoding]);
    
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"请求失败了");
}

然而很不幸的是苹果马上就抛弃 NSUrlConnection 了,将只采用从 2013年开始使用的库 NSUrlSession 库

- (void)buttonClick1{
    // 1.实例化网络会话.
    NSURLSession *session = [NSURLSession sharedSession];
    
    // 2.根据网络会话,实例化网络任务.
    // 网络任务: 三种: 普通/上传/下载
    
    // NSURLSessionDataTask :普通网络任务.
    // 如果是GET 请求,可以直接根据 url 实例化网络任务.
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/webtest/index.php?username=admin&password=123456"];
    /*
     第一个参数:请求路径:内部会自动将路径包装成请求对象
     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
     data:响应体信息(期望的数据)
     response:响应头信息,主要是对服务器端的描述
     error:错误信息,如果请求失败,则error有值
     */
    NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        // 默认是子线程.
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        
    }];
    
    // 3.开启网络任务.
    [task resume];
    
}

- (void)buttonClick2{
    // 1.实例化网络会话.
    NSURLSession *session = [NSURLSession sharedSession];
    
    // 2.根据网络会话,实例化网络任务.
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/webtest/index.php"];
    
    //3.创建可变请求对象
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    //4.设置请求体
    request.HTTPBody = [@"username=admin&password=123456" dataUsingEncoding:NSUTF8StringEncoding];
    
    //5..设置请求方法:
    request.HTTPMethod = @"POST";
    
    /*
     第一个参数:请求对象
     第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
     data:响应体信息(期望的数据)
     response:响应头信息,主要是对服务器端的描述
     error:错误信息,如果请求失败,则error有值
     */
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        // 默认是子线程.
        NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        
    }];
    
    // 3.开启网络任务.
    [task resume];
}

internet visit 002

代码请查看 http://git.oschina.net/zcb1603999/LearningiOS

评论已关闭。