视频列表播放+多文件下载
class DownloadingController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.title = "下载列表"
self.navigationController?.navigationBar.titleTextAttributes = [
NSAttributedString.Key.foregroundColor:UIColor.black,
NSAttributedString.Key.font:UIFont.systemFont(ofSize: 20)
]
self.view.addSubview(self.tableView)
// 注册通知监听下载任务
NotificationCenter.default.addObserver(self, selector: #selector(sessionAddVideoUrl), name: NSNotification.Name(rawValue: "addVideoFile"), object: nil)
}
deinit{
NotificationCenter.default.removeObserver(self) // 移除监听
}
// 添加任务
@objc func sessionAddVideoUrl(no:Notification){
let model:VideoModel = no.object as! VideoModel
sessionManager.download(model.videoUrl!, fileName: model.videoName)
}
// 构建列表
lazy var tableView:UITableView = {
let tableView = UITableView(frame: CGRect.zero,style: .plain)
tableView.register(UINib(nibName: "\(DownloadTaskCell.self)", bundle: nil),
forCellReuseIdentifier: DownloadTaskCell.reuseIdentifier)
tableView.delegate = self
tableView.dataSource = self
tableView.estimatedRowHeight = 164
// 禁止自动布局
if #available(iOS 11.0, *){
tableView.contentInsetAdjustmentBehavior = .never
}else{
self.automaticallyAdjustsScrollViewInsets = false
}
return tableView
}()
// 监听view布局更新
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let y = self.navigationController!.navigationBar.frame.maxY;
let h = self.view.frame.maxY;
let bottom:CGFloat = UIApplication.shared.statusBarFrame.height > 20 ? 83 : 49
self.tableView.frame = CGRect(x: 0, y: y, width:self.view.frame.width, height: h-y-bottom)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
}
extension DownloadingController:UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sessionManager.tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: DownloadTaskCell.reuseIdentifier, for: indexPath) as! DownloadTaskCell
return cell
}
// 每个 cell 中的状态更新,应该在 willDisplay 中执行
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let task = sessionManager.tasks.safeObject(at: indexPath.row),
let cell = cell as? DownloadTaskCell
else { return }
cell.task?.progress { _ in }.success { _ in }.failure { _ in }
cell.task = task
cell.titleLabel.text = task.fileName
cell.updateProgress(task)
cell.tapClosure = { [weak self] cell in
guard let task = self?.sessionManager.tasks.safeObject(at: indexPath.row) else { return }
switch task.status {
case .waiting, .running:
self?.sessionManager.suspend(task)
case .suspended, .failed:
self?.sessionManager.start(task)
default:
break
}
}
task.progress { [weak cell] task in
cell?.updateProgress(task)
}
.success { [weak cell] (task) in
cell?.updateProgress(task)
// 下载任务成功了
}
.failure { [weak cell] task in
cell?.updateProgress(task)
if task.status == .suspended {
// 下载任务暂停了
}
if task.status == .failed {
// 下载任务失败了
}
if task.status == .canceled {
// 下载任务取消了
}
if task.status == .removed {
// 下载任务移除了
}
}
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let task = sessionManager.tasks.safeObject(at: indexPath.row) else { return }
sessionManager.remove(task, completely: false) { [weak self] _ in
self?.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
sessionManager.moveTask(at: sourceIndexPath.row, to: destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}