[iOS 多线程 & 网络 - 3.0] - 在线动画Demo
A.需求
- 所有数据都从服务器下载
- 动画列表包含:图片、动画名标题、时长副标题
- 点击打开动画观看
code source: https://github.com/hellovoidworld/VideoOnlineDemo
server source: https://github.com/hellovoidworld/MyOnlineVideoDemoServer
B.实现
1.显示图片和基本信息
服务器端的json信息:
{ "videos": [
{
"name":"驯龙高手1",
"length":"16秒",
"image":"images/[20150124-180852-0].PNG",
"video":"videos/1.MP4"
},
{
"name":"驯龙高手2",
"length":"21秒",
"image":"images/[20150124-180905-1].PNG",
"video":"videos/2.MP4"
},
{
"name":"驯龙高手3",
"length":"14秒",
"image":"images/[20150124-180908-2].PNG",
"video":"videos/3.MP4"
},
...
]
}
(1)使用tableView来布置界面
(2)创建一个模型,用来装载录像信息
1 // 2 // HVWVideo.h 3 // VideoOnlineDemo 4 // 5 // Created by hellovoidworld on 15/1/24. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 @interface HVWVideo : NSObject 12 13 @property(nonatomic, strong) NSString *name; 14 @property(nonatomic, strong) NSString *length; 15 @property(nonatomic, strong) NSString *image; 16 @property(nonatomic, strong) NSString *video; 17 18 + (instancetype) videoWithDict:(NSDictionary *) dict; 19 20 @end
(3)发送请求 & 接收服务器信息
- 使用代理方法发送请求,接收json数据
- 解析json数据,封装到模型中
- 使用SDWebImage框架加载服务器图片
1 // 2 // HVWVideoViewController.m 3 // VideoOnlineDemo 4 // 5 // Created by hellovoidworld on 15/1/25. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWVideoViewController.h" 10 #import "HVWVideo.h" 11 #import "UIImageView+WebCache.h" 12 13 #define ServerIP @"http://192.168.0.21:8080/MyTestServer" 14 15 @interface HVWVideoViewController () <UITableViewDataSource, UITableViewDelegate, NSURLConnectionDataDelegate> 16 17 /** 接收到的二进制数据 */ 18 @property(nonatomic, strong) NSMutableData *data; 19 20 /** 所有的录像模型数据 */ 21 @property(nonatomic, strong) NSArray *videos; 22 23 @end 24 25 @implementation HVWVideoViewController 26 27 - (void)viewDidLoad { 28 [super viewDidLoad]; 29 30 self.tableView.dataSource = self; 31 self.tableView.delegate = self; 32 33 // 读取服务器数据 34 [self acceptDataFromServer]; 35 } 36 37 - (void)didReceiveMemoryWarning { 38 [super didReceiveMemoryWarning]; 39 // Dispose of any resources that can be recreated. 40 } 41 42 /** 读取服务器数据 */ 43 - (void) acceptDataFromServer { 44 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/video", ServerIP]]; 45 NSURLRequest *request = [NSURLRequest requestWithURL:url]; 46 NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; 47 [connection start]; 48 } 49 50 #pragma mark - UITableViewDataSource 51 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 52 return 1; 53 } 54 55 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 56 return self.videos.count; 57 } 58 59 - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 60 static NSString *ID = @"VideoCell"; 61 62 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 63 if (nil == cell) { 64 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID]; 65 } 66 67 HVWVideo *video = self.videos[indexPath.row]; 68 // 设置标题 & 副标题 69 cell.textLabel.text = video.name; 70 cell.detailTextLabel.text = video.length; 71 72 // 下载图片 73 NSString *imageUrlStr = [NSString stringWithFormat:@"%@/%@", ServerIP, video.image]; 74 NSURL *imageUrl = [NSURL URLWithString:imageUrlStr]; 75 [cell.imageView setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"placeholder"]]; 76 77 78 // 下载录像 79 80 81 return cell; 82 } 83 84 #pragma mark - UITableViewDelegate 85 86 87 88 #pragma mark - NSURLConnectionDataDelegate 代理方法 89 - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 90 NSLog(@"开始接收数据"); 91 self.data = [NSMutableData data]; 92 } 93 94 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 95 NSLog(@"接收数据中..."); 96 [self.data appendData:data]; 97 } 98 99 - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 100 NSLog(@"接收数据完毕"); 101 102 if (self.data) { 103 // 加载录像资料 104 NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableLeaves error:nil]; 105 106 // NSLog(@"%@", jsonDict); 107 NSArray *jsonArray = jsonDict[@"videos"]; 108 // NSLog(@"%@", jsonArray); 109 110 NSMutableArray *videoArray = [NSMutableArray array]; 111 for (NSDictionary *dict in jsonArray) { 112 NSLog(@"%@", dict); 113 HVWVideo *video = [HVWVideo videoWithDict:dict]; 114 [videoArray addObject:video]; 115 } 116 self.videos = videoArray; 117 118 [self.tableView reloadData]; 119 } 120 121 } 122 123 @end
(4)调整cell高度,创建自定义cell类,调整尺寸、分割线
1 // 2 // HVWVideoCell.m 3 // VideoOnlineDemo 4 // 5 // Created by hellovoidworld on 15/1/25. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWVideoCell.h" 10 #import "UIImageView+WebCache.h" 11 12 #define ServerIP @"http://192.168.0.21:8080/MyTestServer" 13 14 @interface HVWVideoCell() 15 16 /** 分割线 */ 17 @property(nonatomic, strong) UIView *separatorLine; 18 19 @end 20 21 @implementation HVWVideoCell 22 23 + (instancetype) cellWithTableView:(UITableView *) tableView { 24 static NSString *ID = @"VideoCell"; 25 26 HVWVideoCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 27 if (nil == cell) { 28 cell = [[HVWVideoCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; 29 } 30 31 return cell; 32 } 33 34 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 35 if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { 36 // 重写样式 37 // 自定义分割写 38 UIView *separatorLine = [[UIView alloc] init]; 39 separatorLine.backgroundColor = [UIColor lightGrayColor]; 40 separatorLine.alpha = 0.3; 41 [self.contentView addSubview:separatorLine]; 42 43 self.separatorLine = separatorLine; 44 } 45 46 return self; 47 } 48 49 /** 重写内部子控件的位置尺寸 */ 50 - (void)layoutSubviews { 51 [super layoutSubviews]; 52 53 // 设置图片 54 CGFloat imageWidth = 100; 55 CGFloat imageHeight = 56; 56 CGFloat imageX = 10; 57 CGFloat imageY = (self.frame.size.height - imageHeight) / 2; 58 CGRect imageFrame = CGRectMake(imageX, imageY, imageWidth, imageHeight); 59 self.imageView.frame = imageFrame; 60 61 // 设置标题 62 CGRect textFrame = self.textLabel.frame; 63 textFrame.origin.x = imageX + imageWidth + 10; 64 self.textLabel.frame = textFrame; 65 66 // 设置副标题 67 CGRect detailFrame = self.detailTextLabel.frame; 68 detailFrame.origin.x = self.textLabel.frame.origin.x; 69 self.detailTextLabel.frame = detailFrame; 70 71 // 设置分割线 72 CGFloat separatorLineY = self.frame.size.height - 1; 73 self.separatorLine.frame = CGRectMake(0, separatorLineY, self.frame.size.width, 1); 74 } 75 76 /** 设置数据 */ 77 - (void)setVideo:(HVWVideo *)video { 78 _video = video; 79 80 // 设置标题 & 副标题 81 self.textLabel.text = video.name; 82 self.detailTextLabel.text = video.length; 83 84 // 下载图片 85 NSString *imageUrlStr = [NSString stringWithFormat:@"%@/%@", ServerIP, video.image]; 86 NSURL *imageUrl = [NSURL URLWithString:imageUrlStr]; 87 [self.imageView setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"placeholder"]]; 88 } 89 90 @end
2.播放视频
(1)引入MediaPlayer类
1 #import <MediaPlayer/MediaPlayer.h>
(2)使用MPMoviePlayerViewController 播放视频
1 - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 2 // 加载视频 3 HVWVideo *video = self.videos[indexPath.row]; 4 NSString *videoUrlStr = [NSString stringWithFormat:@"%@/%@", ServerIP, video.video]; 5 NSURL *videoUrl = [NSURL URLWithString:videoUrlStr]; 6 7 NSLog(@"%@", videoUrlStr); 8 9 // 使用MediaPlayer框架播放视频 10 MPMoviePlayerViewController *mvController = [[MPMoviePlayerViewController alloc] initWithContentURL:videoUrl]; 11 [self presentMoviePlayerViewControllerAnimated:mvController]; 12 }
(3)阻止app进入后台之后退出视频
a.默认app进入后台之后,会自动把视频播放的view缩回去
b.自定义一个集成MPMoviePlayerViewController的类,通过取消接收“进入后台”消息来阻止此操作
1 // 2 // HVWMoviePlayerViewController.m 3 // VideoOnlineDemo 4 // 5 // Created by hellovoidworld on 15/1/25. 6 // Copyright (c) 2015年 hellovoidworld. All rights reserved. 7 // 8 9 #import "HVWMoviePlayerViewController.h" 10 11 @interface HVWMoviePlayerViewController () 12 13 @end 14 15 @implementation HVWMoviePlayerViewController 16 17 - (void)viewDidLoad { 18 [super viewDidLoad]; 19 // Do any additional setup after loading the view. 20 21 // 取消接收程序进入后台的通知 22 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil]; 23 } 24 25 /** 重写屏幕方向方法 */ 26 - (NSUInteger)supportedInterfaceOrientations { 27 // 横屏,向左/右 28 return UIInterfaceOrientationMaskLandscape; 29 } 30 31 @end
(4)强制使用横屏播放
(默认是3个方向都可以播放)
1 /** 重写屏幕方向方法 */ 2 - (NSUInteger)supportedInterfaceOrientations { 3 // 横屏,向左/右 4 return UIInterfaceOrientationMaskLandscape; 5 }