现在的移动开发必然涉及到服务器,那就不能不说网络。在网络编程中,有几个基本的概念:
图解:
客户端是如何找到服务器呢,主要是通过URL找到想要连接的服务器,而什么是URL?
协议: 不同的协议,代表着不同的资源查找方式,资源传输方式
主机地址: 存放资源的主机(服务器)的IP地址(域名)
路径: 资源在主机(服务器)中的具体位置
HTTP协议的特点:
因为http协议简单,所以Http服务器的程序规模小,因而通信速度很快
Http允许各种各样的数据
Http协议规定: 一个完整的由客户端和服务器端的Http请求包括以下内容:
iOS中发送Http的请求方案:
2. NSURLConnection的使用步骤
3. 发送同步请求: 主要使用+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error;方法
/*
GET:http://120.25.226.186:32812/login?username=123&pwd=456&type=JSON
协议+主机地址+接口名称+?+参数1&参数2&参数3
post:http://120.25.226.186:32812/login
协议+主机地址+接口名称
*/
//GET,没有请求体
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.创建请求对象
//请求头不需要设置(默认的请求头)
//请求方法--->默认为GET
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
//3.发送请求
//真实类型:NSHTTPURLResponse
NSHTTPURLResponse *response = nil;
/*
第一个参数:请求对象
第二个参数:响应头信息
第三个参数:错误信息
返回值:响应体
*/
//该方法是阻塞的,即如果该方法没有执行完则后面的代码将得不到执行
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//4.解析 data--->字符串
//NSUTF8StringEncoding
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"%zd",response.statusCode);
4. 发送异步请求: 主要使用两类方法
+ (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler;
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.创建请求对象
//请求头不需要设置(默认的请求头)
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
//3.发送异步请求
/*
第一个参数:请求对象
第二个参数:队列 决定代码块completionHandler的调用线程
第三个参数:completionHandler 当请求完成(成功|失败)的时候回调
response:响应头
data:响应体
connectionError:错误信息
*/
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.解析数据
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
NSLog(@"%zd",res.statusCode);
NSLog(@"%@",[NSThread currentThread]);
}];
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately;
在startImmediately = NO的情况下,需要调用start方法开始发送请
- (void)start;
成为NSURLConnection的代理,最好遵守NSURLConnectionDataDelegate协议
5. NSURLConnectionDataDelegate协议中的代理方法
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
-(void)delegate
{
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=123&pwd=123&type=JSON"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.设置代理,发送请求
//3.1
//[NSURLConnection connectionWithRequest:request delegate:self];
//3.2
//[[NSURLConnection alloc]initWithRequest:request delegate:self];
//3.3 设置代理,时候发送请求需要检查startImmediately的值
//(startImmediately == YES 会发送 | startImmediately == NO 则需要调用start方法)
NSURLConnection * connect = [[NSURLConnection alloc]initWithRequest:request delegate:self startImmediately:NO];
//调用开始方法
[connect start];
// [connect cancel];//取消
}
#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
//1.当接收到服务器响应的时候调用
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"%s",__func__);
}
//2.接收到服务器返回数据的时候调用,调用多次
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(@"%s",__func__);
//拼接数据
[self.resultData appendData:data];
}
//3.当请求失败的时候调用
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%s",__func__);
}
//4.请求结束的时候调用
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"%s",__func__);
NSLog(@"%@",[[NSString alloc]initWithData:self.resultData encoding:NSUTF8StringEncoding]);
}
1. 常用类与GET类似
2. 比较特殊的处理方法
NSMutableURLRequest是NSURLRequest的子类,常用方法有
- (void)setTimeoutInterval:(NSTimeInterval)seconds;
- (void)setHTTPMethod:(NSString *)method;
- (void)setHTTPBody:(NSData *)data;
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
-(void)post
{
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
//2.创建可变请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3.修改请求方法,POST必须大写
request.HTTPMethod = @"POST";
//设置属性,请求超时(超过这个时间算请求失败)
request.timeoutInterval = 10;
//设置请求头User-Agent
//注意:key一定要一致(用于传递数据给后台)
[request setValue:@"ios 10.1" forHTTPHeaderField:@"User-Agent"];
//4.设置请求体信息,字符串--->NSData
request.HTTPBody = [@"username=520it&pwd=123&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
//5.发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//6.解析数据,NSData --->NSString
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
}
代理方法与上面block类似,除了添加request.HTTPMethod和request.HTTPBody等其余与GET的代理一样。
#import "ViewController.h"
@interface ViewController ()
/** 注释 */
@property (nonatomic, strong) NSMutableData *fileData;
@property (nonatomic, assign) NSInteger totalSize;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
-(NSMutableData *)fileData
{
if (_fileData == nil) {
_fileData = [NSMutableData data];
}
return _fileData;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self download3];
}
//耗时操作[NSData dataWithContentsOfURL:url]
-(void)download1
{
//1.url
NSURL *url = [NSURL URLWithString:@"http://img5.imgtn.bdimg.com/it/u=1915764121,2488815998&fm=21&gp=0.jpg"];
//2.下载二进制数据
NSData *data = [NSData dataWithContentsOfURL:url];
//3.转换
UIImage *image = [UIImage imageWithData:data];
}
//1.无法监听进度
//2.内存飙升
-(void)download2
{
//1.url
// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//4.转换
// UIImage *image = [UIImage imageWithData:data];
//
// self.imageView.image = image;
//NSLog(@"%@",connectionError);
//4.写数据到沙盒中
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];
[data writeToFile:fullPath atomically:YES];
}];
}
//内存飙升
-(void)download3
{
//1.url
// NSURL *url = [NSURL URLWithString:@"http://imgsrc.baidu.com/forum/w%3D580/sign=54a8cc6f728b4710ce2ffdc4f3cec3b2/d143ad4bd11373f06c0b5bd1a40f4bfbfbed0443.jpg"];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];
//2.创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.发送请求
[[NSURLConnection alloc]initWithRequest:request delegate:self];
}
#pragma mark ----------------------
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"didReceiveResponse");
//得到文件的总大小(本次请求的文件数据的总大小)
self.totalSize = response.expectedContentLength;
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// NSLog(@"%zd",data.length);
[self.fileData appendData:data];
//进度=已经下载/文件的总大小
NSLog(@"%f",1.0 * self.fileData.length /self.totalSize);
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"connectionDidFinishLoading");
//4.写数据到沙盒中
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]stringByAppendingPathComponent:@"123.mp4"];
[self.fileData writeToFile:fullPath atomically:YES];
NSLog(@"%@",fullPath);
}
@end