在网络编程中,有几个必须掌握的基本概念:php
URL的全称是Uniform Resource Locator(统⼀资源定位符)html
经过1个URL,能找到互联网上惟一的1个资源git
URL就是资源的地址、位置,互联网上的每一个资源都有一个惟一的URLgithub
URL的基本格式 = 协议://主机地址/路径http://61.144.56.195/forum/201302/19/144736txfrcuyvmustucmv.jpghttp://www.fzlu.com/uploads/allimg/140107/1-14010G22134235.jpgweb
解释以下: 编程
a.HTTP:超文本传输协议,访问的是远程的网络资源,格式是http:// http协议是在网络开发中最经常使用的协议json
b.file:访问的是本地计算机上的资源,格式是file://(不用加主机地址)api
c.mailto:访问的是电子邮件地址,格式是mailto:浏览器
d.FTP:访问的是共享主机的⽂文件资源,格式是ftp://缓存
网络请求方式有两种:GET 和 POST
两种方式的相同点是:都能给服务器传输数据
两种请求方式的不一样点是:
2.3.1 给服务器传输数据的方式
GCT:经过网址字符串
POST:经过data
2.3.2 传输数据的大小
GET:网址字符串最多255字节
POST:使用NSData,容量超过1G
2.3.3 安全性
GET:全部传输给服务器的数据,显示在网址里,相似于密码的明文输入,直接可见
POST:数据被转成NSData(二进制数据),相似于密码的密文输入,没法直接读取
链接方式
同步链接:程序容易出现卡死现象
(总结:同步链接请求可让你可以从因特网请求数据,一旦发送同步请求后,程序将中止用户交互,直至服务器返回数据完成才可进行下一步操做。)
异步连接:等待数据返回
异步连接有两种实现方式:1.设置代理,接受数据
2.实现block
GET的特色:
1. GET是"获取"指定URL上的资源。
2. 其将数据按照varialbe = value的形式,添加action到所指向的URL后面,而且二者使用"?"链接,各个变量之间用"&"链接。
3. 不安全,由于在传输过程当中,数据被放在请求的URL中。这样很容易被人拿到看见数据信息。
4.传输的数据量比较小
POST的特色:
1. POST语意是指对指定内容添加和追加数据(经过数据体的形式)
2. 将数据放在数据体中,按照变量和值相对应的方式,传递到action所指向的URL
3. 全部的数据对用户不可见,也就是从URL中看不到。
4. 能够传输大量数据,传输文件只能用POST
5. 不过对服务器来讲,接收数据体可能会不安全
HTTP协议,Hyper Text Transfer Protocol (超文本传输协议)是用于从万维网服务器传送超文本到本地浏览器的传输协议,HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。
HTTP协议的做⽤
HTTP的全称是Hypertext Transfer Protocol,超文本传输协议
(1)规定客户端和服务器之间的数据传输格式
(2)让客户端和服务器能有效地进行数据沟通
HTTP的通讯过程
要想使用HTTP协议向服务器索取数据,得先了解HTTP通讯的完整过程 完整的http通讯能够分为2大步骤
(1)请求:客户端向服务器索要数据
(2)响应:服务器返回客户端相应的数据
3.2.1 HTTP请求
HTTP协议规定,1个完整的由客户端发给服务器的HTTP请求中包含如下内容
请求行:包含了请求方法、请求资源路径、HTTP协议版本 GET /MJServer/resources/images/1.jpg HTTP/1.1
请求头:包含了对客户端的环境描述、客户端请求的主机地址等信息
Host: 192.168.1.105:8080 // 客户端想访问的服务器主机地址
3.2.2 HTTP响应
客户端向服务器发送请求,服务器应当作出响应,即返回数据给客户端
HTTP协议规定:1个完整的HTTP响应中包含如下内容:
状态行:包含了HTTP协议版本、状态码、状态英⽂名称HTTP/1.1 200 OK
响应头:包含了对服务器的描述、对返回数据的描述 Server: Apache-Coyote/1.1 // 服务器的类型
Content-Type: image/jpeg // 返回数据的类型
Content-Length: 56811 // 返回数据的长度
Date: Mon, 23 Jun 2014 12:54:52 GMT // 响应的时间 实体内容:服务器返回给客户端的具体数据,⽐好比⽂件数据
发送HTTP请求的⽅法
在HTTP/1.1协议中,定义了8种发送http请求的⽅方法 GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH 根据HTTP协议的设计初衷,不一样的方法对资源有不一样的操做⽅方式
PUT :增
DELETE :删
POST:改
GET:查 提示:最经常使用的是GET和POST(实际上GET和POST都能办到增删改查)
get和post的选择
(1)若是要传递大量数据,⽐如⽂件上传,只能用POST请求
(2)GET的安全性比POST要差些,若是包含机密\敏感信息,建议⽤用POST
(3)若是仅仅是索取数据(数据查询),建议使用GET
(4)若是是增长、修改、删除数据,建议使用POST
• 构造NSURL实例(地址)
• ⽣成NSURLRequest请求(网络请求的信息)
• 经过NSURLConnection发送请求
• 经过返回NSURLRespond实例和NSError实例分析结果
• 处理返回数据
3.3.1 GET请求
GET请求:获取数据,把参数以URL的形式拼接传给服务器,以 ? 分开URL地址和参数,& 拼接多个参数
1.建立一个URL
NSString *urlStr = @"https://route.showapi.com/213-4?showapi_appid=24110&showapi_timestamp=20160905154834&topid=5&showapi_sign=5d1ba1725827501e32238072e5960958"; NSURL *URL = [NSURL URLWithString:urlStr];
2.建立一个NSURLRequest 请求
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
三、建立NSURLSession
NSURLSession *session = [NSURLSession sharedSession];
四、由session建立一个请求数据的任务NSURLSessionDataTask(会以异步的形式发送网络请求,不会阻塞主线程)
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // 执行完后 以block 返回结果,解析数据 id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",jsonData); }];
五、开始执行网络任务
[dataTask resume];
3.3.2 POST请求
POST请求时要指明请求的方式HTTPMethod 为 POST,参数以请求体 HTTPMethod 的形式传入。
一、设置请求方式为 POST
NSURL *url = [NSURL URLWithString:@"https://route.showapi.com/213-4"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST";
二、设置请求体:把参数做为NSData类型传入
NSString *parmStr = [NSString stringWithFormat:@"showapi_appid=%@&showapi_timestamp=%@&topid=%@&showapi_sign=%@",APPID,@"20160905154834",@"5",SIGN]; request.HTTPBody = [parmStr dataUsingEncoding:NSUTF8StringEncoding];
3.建立一个NSURLRequest 请求
NSURLSession *session = [NSURLSession sharedSession];
四、由session建立一个请求数据的任务NSURLSessionDataTask(会以异步的形式发送网络请求,不会阻塞主线程)
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"%@",error); return; } // NSLog(@"%@",response); // 执行完后 以block 返回结果,解析数据 id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSLog(@"%@",jsonData); }]; //开始执行网络请求 [dataTask resume];
NSURLRequest的cachePolicy属性能够设置缓存策略,这是⼀种内存缓存,⾮硬盘缓存。使用缓存的目的是为了使⽤的应用程序能更快速的响应⽤户输入,使程序高效的运行。有时候咱们须要将远程web服务器获取的数据缓存起来,减小对同⼀个url屡次请求。
// 默认,使用缓存,当下一次请求时先判断是否有缓存,有就使用缓存没有才进行网络请求,使用缓存时会先判断缓存是否过时,过时的就从新请求网络。 NSURLRequestUseProtocolCachePolicy = 0, // 忽略缓存,不使用缓存 NSURLRequestReloadIgnoringLocalCacheData = 1, // 无视任何的缓存策略,不管是本地的仍是远程的,老是从原地址从新下载 NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, //首先使用缓存不论是否过时,若是没有本地缓存,才从原地址下载 NSURLRequestReturnCacheDataElseLoad = 2, //使用本地缓存,从不下载,若是本地没有缓存,则请求失败。此策略多用于离线操做 NSURLRequestReturnCacheDataDontLoad = 3, //缓存数据必须得获得服务端确认有效才使用(NSURLRequestUseProtocolCachePolicy中的一种状况) // Unimplemented NSURLRequestReloadRevalidatingCacheData = 5,
timeoutInterval: 设置请求超时的时间秒数
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:10];
NSURLSessionConfiguration:配置网络请求
// 默认的模式,能够缓存数据(默认会话模式) defaultSessionConfiguration, //无痕浏览,不会有任何的缓存(瞬间会话模式) ephemeralSessionConfiguration, //后台会话模式(该模式在后台完成上传和下载,在建立Configuration对象的时候须要提供一个NSString类型的ID用于标识完成工做的后台会话。) backgroundSessionConfigurationWithIdentifier NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
经过 NSURLSessionConfiguration 设置缓存策略
configuration.requestCachePolicy = NSURLRequestUseProtocolCachePolicy; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSURLSession是为了代替NSURLConnection而设计的。Sessions的全部工做都是经过NSURLSessionTask (NSURLsessionTask 是一个抽象类,其中有 3 个实体子类能够直接使用:NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask。这 3 个子类封装了现代程序三个最基本的网络任务:获取数据,好比 JSON 或者 XML,上传文件和下载文件。)实现的。可使用block,delegate,或者二者混合来建立task。(举个例子,你要下载图片,就要建立NSURLSessionDownloadTask。)
建立URL
NSURL *url = [NSURL URLWithString:@"http://dl.stream.qqmusic.qq.com/108051051.mp3?vkey=4A95A0FCDFDC050E9D543841CA4A28AABD19F1973177DAB509EEBED09344D0A91A286D0800E7C58751A670CC429DB1118C98F8908C487284&guid=2718671044"];
建立Session并设置
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
建立一个下载任务
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { return; } // 设置保存文件的本地URL NSURL *docmentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; //拼接一个数据名,response suggestedFilename 自动获取下载数据的名字.格式类型 NSURL *dataURL = [docmentsURL URLByAppendingPathComponent:[response suggestedFilename]]; NSError *moveError = nil; // 将下载的数据从临时URL移动到指定的URL [[NSFileManager defaultManager] moveItemAtURL:location toURL:dataURL error:&moveError]; if (!moveError) { NSLog(@"保存成功"); } NSLog(@"%@",location); }];
启动下载
[downloadTask resume];
代理的方式下载
NSURL *url = [NSURL URLWithString:@"https://github.com/AFNetworking/AFNetworking/archive/master.zip"]; //配置NSURLSession并设置代理,delegateQueue:代理执行的线程 NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDownloadTask *downTask = [session downloadTaskWithURL:url]; // 启动下载 [downTask resume];
下载完成后调用
//下载完成后调用 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSLog(@"下载完成 %@",NSHomeDirectory()); // 设置保存文件的本地URL NSURL *docmentsURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; NSURL *dataURL = [docmentsURL URLByAppendingPathComponent:downloadTask.response.suggestedFilename]; NSError *moveError = nil; //将下载的数据从临时URL移动到指定的URL [[NSFileManager defaultManager] moveItemAtURL:location toURL:dataURL error:&moveError]; if (!moveError) { NSLog(@"保存成功"); } }
监听下载进度
// 监听下载进度 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { // bytesWritten: 时间点下载的数据大小 totalBytesWritten:已经下载的数据大小,totalBytesExpectedToWrite: 下载文件的总大小 self.prograssView.prograss = (CGFloat)totalBytesWritten / (CGFloat)totalBytesExpectedToWrite; NSLog(@"%lld, %lld, %lld ",bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); }
文件上传也有block和代理两种方式
block方式上传
建立URL
NSURL *url = [NSURL URLWithString:@"http://www.imageshack.us/index.php"];
建立请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:20];
设置请求为POST
request.HTTPMethod = @"POST";
设置请求头的上传文件的内容格式(Content-Type) 为图片类型(image/jpeg)
[request setValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
设置请求头的响应(Accept)的文本格式(text/html)
[request setValue:@"text/html" forHTTPHeaderField:@"Accept"]; NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
上传方式一:把要上传的数据保存为NSData
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"image7.jpeg"], 0.5); NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:imageData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"%@",error); } else { NSString *reuslt = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@ \n%@",response, reuslt); } }];
上传方式二:使用文件所在的本地的URL
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"image7" withExtension:@"jpeg"]; // NSURL *fileURL = [NSURL URLWithString:@"http://img.ivsky.com/img/tupian/pre/201507/01/yindian_meinv-001.jpg"]; NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromFile:fileURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { NSLog(@"%@",error); } else { NSString *reuslt = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@ \n%@",response, reuslt); } }]; // 恢复线程,启动任务 [uploadTask resume];
NSURLSession 支持程序的后台下载和上传, 苹果官方将其称之进程以外的上传和下载, 这些任务都交给后台守护线程完成, 而不是应用自己, 即便文件在下载和上传过程当中崩溃了也能够继续运行(若是用户强制关闭程序的话, NSURLSession会断开链接)
签定代理协议
@interface ViewController ()<NSURLSessionDownloadDelegate>
建立URL和请求
NSURL *url = [NSURL URLWithString:@"https://github.com/fuqinglin/MagicalRecord/archive/master.zip"]; NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:20];
设置网络请求为 backgroundSessionConfigurationWithIdentifier 后台模式,后面接标识符
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.tens.background"];
建立NSURLSession
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
启动下载任务
[downloadTask resume];
// 后台下载完调用 - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { NSLog(@"后台下载完成"); AppDelegate *delegate = [UIApplication sharedApplication].delegate; // 回调 AppDelegate 中 application: handleEventsForBackgroundURLSession: completionHandler: 中的block事件,处理下载完后的提示 if (delegate.backgroundCompletionHandler) { void (^completionHandler)() = delegate.backgroundCompletionHandler; completionHandler(); } }
NSURLSessionDownloadTask支持取消下载,能够在下载过程当中随时取消继续下载,同时也能够实现恢复下载。
取消下载 cancelByProducingResumeData
//用当前NSURLSessionDownloadTask对象去调用取消下载 [self.downTask cancelByProducingResumeData: ^(NSData * _Nullable resumeData) { //全局变量 接收当前下载的资源 self.data = resumeData; } //将当前下载任务置为空 self.downTask = nil;
恢复下载 downloadTaskWithResumeData
//恢复下载 其实是创建了一个新的下载任务 去继续以前的下载 self.downTask = [self.downLoadSession downloadTaskWithResumeData:self.data]; //开启任务 [self.downTask resume]; }