控制器部分.h
#import <UIKit/UIKit.h>@import AVFoundation;
@interface MYYViewController : UIViewController<UITableViewDelegate,UITableViewDataSource]] >
@property(nonatomic,strong)IBOutlet UITableView *tableView;
@end
实现部分.m
#import "MYYViewController.h"
#import "MYYDownLoadOperation.h"
#import "MYYTableViewCell.h"
@interface MYYViewController ()
//创建可变数组对象,存储歌曲信息
@property(nonatomic,strong)NSMutableArray *songList;
//创建操作管理对象
@property(nonatomic,strong)NSOperationQueue *downloaQueue;
//播放音乐对象
@property(nonatomic,strong)AVPlayer *player;
@end
@implementation MYYViewController
-(void)awakeFromNib{
[super awakeFromNib];
self.songList = [[NSMutableArray alloc]init];
//创建对象
self.downloaQueue = [[NSOperationQueue alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
#define KURLFormat @"http://115.28.227.1/student/beijing/class_beijing_28/media/%@.mp3"
//循环添加60个音乐的地址
for (NSInteger i = 1; i<=60; i++) {
MYYMusicInfo *item = [[MYYMusicInfo alloc]init];
NSString *url = [[NSString alloc] initWithFormat:KURLFormat,@(i).description];
item.url = url;
item.musicName = @(i).description;
item.progress = 0.0f;
[self.songList addObject:item];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark-table
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.songList.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MYYTableViewCell *cell = nil;
cell = (MYYTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"song" forIndexPath:indexPath];
MYYMusicInfo *item = self.songList[indexPath.row];
item.delegate = cell;
//单元格刷新
cell.item = item;
return cell;
}
//单元格消失时,设定音乐对象的代理对象为空
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
MYYMusicInfo *item = self.songList[indexPath.row];
item.delegate = nil;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//点击要先置空 (进行下一个的时候)
/*
[self.player pause];
self.player = nil;
NSURL *songURL = [NSURL URLWithString:self.songList[indexPath.row]];
self.player =[[AVPlayer alloc]initWithURL:songURL];
[self.player play];
*/
MYYMusicInfo *item = self.songList[indexPath.row];
//假设当前音乐处于下载状态时,就不在进行下载了
if (item.isDownloading) {
return;
}
//假设当前的音乐处于下载状态时,就不用再下载了
if (!item.isDownloading && item.isFinished) {
//下载完成后,因为已经修改url为本地的地址了
self.player = [[AVPlayer alloc]initWithURL:[NSURL fileURLWithPath:item.url]];
//播放音乐
[self.player play];
return;
}
MYYDownLoadOperation *downLoadOp = [[MYYDownLoadOperation alloc]initWithInfo:item ];
[self.downloaQueue addOperation:downLoadOp];
}
//
// UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
//
// [tableView registerNib:[UINib nibWithNibName:@"MYYTableViewCell" bundle:nil] forCellReuseIdentifier:@"song"];
//
// [tableView registerClass:NSClassFromString(@"MYYTableViewCell") forCellReuseIdentifier:@"song"];
//
// tableView.delegate = self;
// tableView.dataSource = self;
//
// [self.view addSubview:tableView];
//}
@end
#import "MYYDownLoadOperation.h"
#import "MYYTableViewCell.h"
@interface MYYViewController ()
//创建可变数组对象,存储歌曲信息
@property(nonatomic,strong)NSMutableArray *songList;
//创建操作管理对象
@property(nonatomic,strong)NSOperationQueue *downloaQueue;
//播放音乐对象
@property(nonatomic,strong)AVPlayer *player;
@end
@implementation MYYViewController
-(void)awakeFromNib{
[super awakeFromNib];
self.songList = [[NSMutableArray alloc]init];
//创建对象
self.downloaQueue = [[NSOperationQueue alloc] init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
#define KURLFormat @"http://115.28.227.1/student/beijing/class_beijing_28/media/%@.mp3"
//循环添加60个音乐的地址
for (NSInteger i = 1; i<=60; i++) {
MYYMusicInfo *item = [[MYYMusicInfo alloc]init];
NSString *url = [[NSString alloc] initWithFormat:KURLFormat,@(i).description];
item.url = url;
item.musicName = @(i).description;
item.progress = 0.0f;
[self.songList addObject:item];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark-table
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.songList.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MYYTableViewCell *cell = nil;
cell = (MYYTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"song" forIndexPath:indexPath];
MYYMusicInfo *item = self.songList[indexPath.row];
item.delegate = cell;
//单元格刷新
cell.item = item;
return cell;
}
//单元格消失时,设定音乐对象的代理对象为空
-(void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
MYYMusicInfo *item = self.songList[indexPath.row];
item.delegate = nil;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
//点击要先置空 (进行下一个的时候)
/*
[self.player pause];
self.player = nil;
NSURL *songURL = [NSURL URLWithString:self.songList[indexPath.row]];
self.player =[[AVPlayer alloc]initWithURL:songURL];
[self.player play];
*/
MYYMusicInfo *item = self.songList[indexPath.row];
//假设当前音乐处于下载状态时,就不在进行下载了
if (item.isDownloading) {
return;
}
//假设当前的音乐处于下载状态时,就不用再下载了
if (!item.isDownloading && item.isFinished) {
//下载完成后,因为已经修改url为本地的地址了
self.player = [[AVPlayer alloc]initWithURL:[NSURL fileURLWithPath:item.url]];
//播放音乐
[self.player play];
return;
}
MYYDownLoadOperation *downLoadOp = [[MYYDownLoadOperation alloc]initWithInfo:item ];
[self.downloaQueue addOperation:downLoadOp];
}
//
// UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
//
// [tableView registerNib:[UINib nibWithNibName:@"MYYTableViewCell" bundle:nil] forCellReuseIdentifier:@"song"];
//
// [tableView registerClass:NSClassFromString(@"MYYTableViewCell") forCellReuseIdentifier:@"song"];
//
// tableView.delegate = self;
// tableView.dataSource = self;
//
// [self.view addSubview:tableView];
//}
@end
音乐对象.h
#import <Foundation/Foundation.h>
@class MYYMusicInfo;
@protocol MYYMusicProtocol<NSObject >
-(void)musicDownLoadRefresh:(MYYMusicInfo *)music;
@end
@interface MYYMusicInfo : NSObject
@property(nonatomic,strong)NSString *url;
@property(nonatomic,assign)CGFloat progress;
//歌曲名称
@property(nonatomic,strong)NSString *musicName;
@property(nonatomic,weak)id<MYYMusicProtocol>delegate;
@property(nonatomic,assign)BOOL isDownloading;
@property(nonatomic,assign)BOOL isFinished;
@end
音乐类的实现
#import "MYYMusicInfo.h"
@implementation MYYMusicInfo
- (instancetype)init
{
self = [super init];
if (self) {
self.isDownloading = NO;
self.isFinished = NO;
}
return self;
}
-(void)setProgress:(CGFloat)progress{
_progress = progress;
//通知代理对象
[self.delegate musicDownLoadRefresh:self];
}
@end
@implementation MYYMusicInfo
- (instancetype)init
{
self = [super init];
if (self) {
self.isDownloading = NO;
self.isFinished = NO;
}
return self;
}
-(void)setProgress:(CGFloat)progress{
_progress = progress;
//通知代理对象
[self.delegate musicDownLoadRefresh:self];
}
@end
自定义单元格
#import <UIKit/UIKit.h>
#import "MYYMusicInfo.h"
@interface MYYTableViewCell : UITableViewCell<MYYMusicProtocol >
@property (nonatomic ,strong) IBOutlet UIView *progressView;
@property (nonatomic ,strong) IBOutlet UILabel *nameLabel;
@property (nonatomic ,strong) IBOutlet UILabel *progressLabel;
@property(nonatomic,strong)MYYMusicInfo *item;
@end
#import "MYYMusicInfo.h"
@interface MYYTableViewCell : UITableViewCell<MYYMusicProtocol >
@property (nonatomic ,strong) IBOutlet UIView *progressView;
@property (nonatomic ,strong) IBOutlet UILabel *nameLabel;
@property (nonatomic ,strong) IBOutlet UILabel *progressLabel;
@property(nonatomic,strong)MYYMusicInfo *item;
@end
.m
#import "MYYTableViewCell.h"
@implementation MYYTableViewCell
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
;
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)musicDownLoadRefresh:(MYYMusicInfo *)music{
//修改进度视图的宽度
CGRect rect = self.progressView.frame;
rect.size.width = music.progress *320;
self.progressView.frame = rect;
NSLog(@"%@",NSStringFromCGRect(rect));
self.nameLabel.text = music.musicName;
//修改进度标签的文字
self.progressLabel.text = [NSString stringWithFormat:@"%.2f",music.progress *100];
NSLog(@"%.2f",music.progress *100);
}
-(void)setItem:(MYYMusicInfo *)item{
if (_item == item) {
return;
}
_item = item;
//刷新
[self musicDownLoadRefresh:_item];
}
@end
下载音乐
#import <Foundation/Foundation.h>
#import "MYYMusicInfo.h"
//下载的功能
@interface MYYDownLoadOperation : NSOperation<NSURLConnectionDataDelegate]] >
//添加一个存储的属性
@property(nonatomic,strong)MYYMusicInfo *musicInfo;
-(instancetype)initWithInfo:(MYYMusicInfo *)musicInfo;
@end
#import "MYYMusicInfo.h"
//下载的功能
@interface MYYDownLoadOperation : NSOperation<NSURLConnectionDataDelegate]] >
//添加一个存储的属性
@property(nonatomic,strong)MYYMusicInfo *musicInfo;
-(instancetype)initWithInfo:(MYYMusicInfo *)musicInfo;
@end
。m
#import "MYYDownLoadOperation.h"
@implementation MYYDownLoadOperation
{//用来拼接下载到的每个片段的数据
NSMutableData *mutableData;
//声明bool值 用来判断当前是否在下载,如果下载runloop一直存在,结束后,runloop消失
BOOL isDownLoading;
//用来存储整个文件的大小
NSInteger maxLength;
}
-(instancetype)initWithInfo:(MYYMusicInfo *)musicInfo
{
self = [super init];
if (self) {
self.musicInfo = musicInfo;
}
return self;
}
-(void)main{
//只有一进来就认为开始下载
self.musicInfo.isDownloading = YES;
//将字符串转换成路径对象
NSURL *url = [NSURL URLWithString:self.musicInfo.url];
//响应
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
//只要再下载中 ,runloop就一直存在
while (self.musicInfo.isDownloading)
{
[[NSRunLoop currentRunLoop]runUntilDate:[NSDate distantFuture]];
}
}
//客户端的接收到服务器的响应
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
mutableData = [[NSMutableData alloc]init];
//能够直接强行转的原因,就是我们在发送请求的时候接收了http协议
NSHTTPURLResponse *httpRespone = (NSHTTPURLResponse *)response;
//响应中存储的信息
NSDictionary *dictionary = [httpRespone allHeaderFields];
//http协议中规定了很多的关键字,其中content-length 就是代表文件的大小
maxLength = [dictionary[@"Content-Length"]integerValue];
}
//客户端每次接收到的数据片段数据之后都会执行的方法
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[mutableData appendData:data];
CGFloat progess = (CGFloat)mutableData.length / maxLength;
//修改下载的音乐对象的进度....
self.musicInfo.progress = progess;
}
//下载完成的状态
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//下载完成,修改下载状态 = NO
self.musicInfo.isDownloading = NO;
self.musicInfo.isFinished = YES;
//写入文件。。。。
NSArray *document = NSSearchPathForDirectoriesInDomains(9, 1, 1);
NSString *documentPath = document[0];
NSString *filePath = [documentPath stringByAppendingFormat:@"/%@.mp3",self.musicInfo.musicName];
//下载完成后替换成本地链接.....
self.musicInfo.url = filePath;
//正确的写入方法
[mutableData writeToFile:filePath atomically:YES];
}
//下载失败的回调函数
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
self.musicInfo.isDownloading = NO;
}
@end
@implementation MYYDownLoadOperation
{//用来拼接下载到的每个片段的数据
NSMutableData *mutableData;
//声明bool值 用来判断当前是否在下载,如果下载runloop一直存在,结束后,runloop消失
BOOL isDownLoading;
//用来存储整个文件的大小
NSInteger maxLength;
}
-(instancetype)initWithInfo:(MYYMusicInfo *)musicInfo
{
self = [super init];
if (self) {
self.musicInfo = musicInfo;
}
return self;
}
-(void)main{
//只有一进来就认为开始下载
self.musicInfo.isDownloading = YES;
//将字符串转换成路径对象
NSURL *url = [NSURL URLWithString:self.musicInfo.url];
//响应
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
//只要再下载中 ,runloop就一直存在
while (self.musicInfo.isDownloading)
{
[[NSRunLoop currentRunLoop]runUntilDate:[NSDate distantFuture]];
}
}
//客户端的接收到服务器的响应
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
mutableData = [[NSMutableData alloc]init];
//能够直接强行转的原因,就是我们在发送请求的时候接收了http协议
NSHTTPURLResponse *httpRespone = (NSHTTPURLResponse *)response;
//响应中存储的信息
NSDictionary *dictionary = [httpRespone allHeaderFields];
//http协议中规定了很多的关键字,其中content-length 就是代表文件的大小
maxLength = [dictionary[@"Content-Length"]integerValue];
}
//客户端每次接收到的数据片段数据之后都会执行的方法
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[mutableData appendData:data];
CGFloat progess = (CGFloat)mutableData.length / maxLength;
//修改下载的音乐对象的进度....
self.musicInfo.progress = progess;
}
//下载完成的状态
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
//下载完成,修改下载状态 = NO
self.musicInfo.isDownloading = NO;
self.musicInfo.isFinished = YES;
//写入文件。。。。
NSArray *document = NSSearchPathForDirectoriesInDomains(9, 1, 1);
NSString *documentPath = document[0];
NSString *filePath = [documentPath stringByAppendingFormat:@"/%@.mp3",self.musicInfo.musicName];
//下载完成后替换成本地链接.....
self.musicInfo.url = filePath;
//正确的写入方法
[mutableData writeToFile:filePath atomically:YES];
}
//下载失败的回调函数
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
self.musicInfo.isDownloading = NO;
}
@end