iOS的开发中的网络下载方式包括:
- NSData(最原始,实际开发基本不会用)
- NSURLConnection(古老又过气的苹果原生网络框架)
- NSURLSession(现在流行的苹果网络框架)
- AFNetworking,SDWebImage(第三方框架)
- XMNetworking,HYBNetworking(基于AFNetworking的二次封装框架)
本地服务器读取资源的文件夹内容
一.简单的搭建界面用于显示下载的图片或者视频以及下载进程
在Main.storyboard中添加一个Image View,Progress View,Label并关联控件
二.下载图片
1.发起同步的请求,阻塞主线程
//创建路径
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/img/abc.png"];
//创建请求 默认GET
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//接受响应信息的变量
NSHTTPURLResponse *urlResponse = nil;
//发起同步的连接
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:nil];
//NSData->UIImage
UIImage *responseImg = [UIImage imageWithData:responseData];
//显示图片
self.imageView.image = responseImg;
NSData有一个方法dataWithContentsOfURL可以直接获得返回的数据
//创建路径
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/img/abc.png"];
//获得数据
NSData *imgData = [NSData dataWithContentsOfURL:url];
//NSData->UIImage
UIImage *img = [UIImage imageWithData:imgData];
//显示图片
self.imageView.image = img;
2.发起异步的请求,自己设置代码在那个线程执行
//创建路径
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/img/abc.png"];
//创建请求 默认GET
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//发起连接,下载数据
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//数据下载完毕 需要做什么
//NSData->UIImage
UIImage *img = [UIImage imageWithData:data];
//显示图片
self.imageView.image = img;
}];
参数queue的作用:用来设置下载完毕之后的block里面的代码在哪个线程执行
-
1.[NSOperationQueue new] block在新的一个子线程里面执行
-
2.[NSOperationQueue mainQueue] block在主线程里面执行
如果block里面有UI的相关操作,必须放在主线程,子线程只能操作UI以外的事情
如果一个任务需要花费大量时间:上传下载视频 等,为了不阻塞主线程,这些操作放在子线程
//创建路径
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/img/abc.png"];
//创建请求 默认GET
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//打印线程
NSLog(@"%@",[NSThread currentThread]);
//发起连接,下载数据
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue new] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//打印线程
NSLog(@"%@",[NSThread currentThread]);
//数据下载完毕 需要做什么
//NSData->UIImage
UIImage *img = [UIImage imageWithData:data];
//显示图片 将UI操作放在主线程做
dispatch_sync(dispatch_get_main_queue(), ^{
//打印线程
NSLog(@"%@",[NSThread currentThread]);
//显示图片
self.imageView.image = img;
});
}];
线程的打印结果
2019-05-18 iOS-下载图片和视频 <NSThread: 0x6000000668c0>{number = 1, name = main}
2019-05-18 iOS-下载图片和视频 <NSThread: 0x60800006e540>{number = 3, name = (null)}
2019-05-18 iOS-下载图片和视频 <NSThread: 0x6000000668c0>{number = 1, name = main}
3.结果
三.下载视频
可以使用下载图片的两种方式,但是我们想要知道下载情况,所以使用代理方法发送一个异步请求
- NSURLConnectionDelegate 连接的代理 连接状态 授权状态
- NSURLConnectionDownloadDelegate 监听下载的状态 没有实际数据
- NSURLConnectionDataDelegate 监听服务器返回的data
这三个协议中我们最常用NSURLConnectionDataDelegate
1.服从协议以及一些需要的变量
@interface ViewController ()<NSURLConnectionDataDelegate>
//保存下载资源的大小
@property (nonatomic,assign) long long size;
//保存下载资源的二进制数据
@property (nonatomic,strong) NSMutableData *mediaData;
//播放器
@property (nonatomic,strong) AVPlayer *player;
@end
2.创建请求,发送异步连接
//创建路径
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/video/abc.mp4"];
//创建请求 默认GET
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//发起连接
[NSURLConnection connectionWithRequest:request delegate:self];
3.代理方法
//服务器端返回给客户端的响应信息 描述客户端请求的数据的详细信息
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
//如果需要知道这个HTTP的所有信息,就需要获得NSURLResponse的子类
NSHTTPURLResponse *htttpResponse = (NSHTTPURLResponse *)response;
//打印信息
NSLog(@"%@",htttpResponse.allHeaderFields);
//获取文件的大小
self.size = htttpResponse.expectedContentLength;
//创建容器
self.mediaData = [NSMutableData dataWithCapacity:_size];
}
//服务器向客户端发送的一个个数据包
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
//保存数据
[_mediaData appendData:data];
//计算进度 下载比例
CGFloat rate = data.length*1.0/_size;
//显示到progressView
self.progressView.progress += rate;
_progressLabel.text = [NSString stringWithFormat:@"%.1f%%",_progressView.progress*100];
}
//数据下载完毕
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//显示数据
_progressLabel.text = @"100%";
UIImage *img = [UIImage imageWithData:_mediaData];
self.imageView.image = img;
}
打印的信息
{
"Accept-Ranges" = bytes;
Connection = "Keep-Alive";
"Content-Length" = 1018479054;
"Content-Type" = "video/quicktime";
Date = "Sat, 18 May 2019 03:46:38 GMT";
Etag = "\"3cb4c1ce-588a70d715380\"";
"Keep-Alive" = "timeout=5, max=100";
"Last-Modified" = "Sun, 12 May 2019 01:52:30 GMT";
Server = "Apache/2.4.25 (Unix) PHP/5.6.30";
}
运行结果
四.简单的播放视频
导入#import <AVFoundation/AVFoundation.h>
1.简单的播放
-(void)playVideo1{
//获取视频在网络中的url地址
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/video/abc.mov"];
//创建播放器AVPlayer
AVPlayer *player = [AVPlayer playerWithURL:url];
//创建显示的图层AVPlayerLayer用于展示播放的内容
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
//范围
layer.frame = CGRectMake(0, 200, self.view.frame.size.width, 300);
//播放
[player play];
//显示
[self.view.layer addSublayer:layer];
}
2.暂停和播放
-(void)playVideo2{
//获取视频在网络中的url地址
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/upLoad/video/abc.mov"];
//AVPlayItem用于管理视频的具体播放 进度拖动 视频的时间 快进
AVPlayerItem *playItem = [AVPlayerItem playerItemWithURL:url];
//创建播放器AVPlayer
self.player = [AVPlayer playerWithPlayerItem:playItem];
//创建显示的图层AVPlayerLayer用于展示播放的内容
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:_player];
//范围
layer.frame = CGRectMake(0, 200, self.view.frame.size.width, 300);
[_player play];
//显示
[self.view.layer addSublayer:layer];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//暂停和播放
if (_player.rate == 0.0) {
//暂停
[_player play];
}else{
//播放
[_player pause];
}
}
参考文章
https://www.cnblogs.com/wendingding/p/3813572.html
demo链接
https://pan.baidu.com/s/1sRJ-vAHUaEbG9Pa1-CmB0w
密码:dy82
网友评论