Tiercel 2!完美支持原生级别后台下载

项目地址:github.com/Danie1s/Tie…ios

Tiercel是一个简单易用且功能丰富的纯Swift下载框架,支持原生级别后台下载,拥有强大的任务管理功能,知足下载类APP的大部分需求。git

Tiercel 2:

Tiercel 2 是全新的版本,下载实现基于URLSessionDownloadTask,支持原生的后台下载,功能更增强大,使用方式也有了一些改变,不兼容旧版本,请注意新版的使用方法。若是想了解后台下载的细节和注意事项,能够看这篇文章:iOS原生级别后台下载详解github

旧版本下载实现基于URLSessionDataTask,不支持后台下载,已经移至dataTask分支,原则上再也不更新,若是不须要后台下载功能,或者不想迁移到新版,能够直接下载dataTask分支的源码使用,也能够在Podfile里使用如下方式安装:swift

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Tiercel', :git => 'https://github.com/Danie1s/Tiercel.git', :branch => 'dataTask'
end
复制代码

Features:

  • 原生级别的后台下载
  • 支持离线断点续传,不管crash仍是手动Kill App都不会影响
  • 精细的任务管理,每一个下载任务均可以单独管理操做和状态回调
  • 支持多个下载模块,每一个模块拥有一个管理者,每一个模块互不影响
  • 下载模块的管理者拥有总任务的状态回调
  • 内置了下载速度、剩余时间等常见的下载信息
  • 链式语法调用
  • 支持控制下载任务的最大并发数
  • 支持文件校验
  • 线程安全

Requirements

  • iOS 8.0+
  • Xcode 10.0+
  • Swift 4.2+

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:api

$ gem install cocoapods
复制代码

CocoaPods 1.1+ is required to build Tiercel.数组

To integrate Tiercel into your Xcode project using CocoaPods, specify it in your Podfile:xcode

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Tiercel'
end
复制代码

Then, run the following command:缓存

$ pod install
复制代码

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate Tiercel into your project manually.安全

Example

To run the example project, clone the repo, and run Tiercel.xcodeproj .ruby

批量下载

跨控制下载

Usage

配置

Tiercel内置一个全局的TRManager.default单例,由于支持原生后台下载,因此须要在AppDelegate 文件里配置

如下为内置的default单例配置方法,若是须要使用多个下载模块,或者须要自定义TRManager,可参照Demo

// 在AppDelegate文件里

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // 若是有使用内置全局的default单例,必须在此方法内调用一次,不然不会在App启动的时候初始化
    
    // 在这里进行初始化的配置,也能够在任何地方,随时进行配置
    TRManager.default.configuration.allowsCellularAccess = true
    
    return true
}

// 必须实现此方法,而且把identifier对应的completionHandler保存起来
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

    if TRManager.default.identifier == identifier {
        TRManager.default.completionHandler = completionHandler
    }

}
复制代码

基本用法

一行代码开启下载

// 建立下载任务而且开启下载,同时返回可选类型的TRDownloadTask实例,若是URLString无效,则返回nil
let task = TRManager.default.download("http://api.gfs100.cn/upload/20171219/201712191530562229.mp4")

// 批量建立下载任务而且开启下载,返回有效URLString对应的任务数组,URLStrings须要跟fileNames一一对应
let tasks = TRManager.default.multiDownload(URLStrings)
复制代码

若是须要设置回调

// 回调闭包的参数是TRDownloadTask实例,能够获得全部相关的信息
// 回调闭包都是在主线程运行
// progress 闭包:若是任务正在下载,就会触发
// success 闭包:任务已经下载过,或者下载完成,都会出发,这时候task.status == .succeeded
// failure 闭包:只要task.status != .succeeded,就会触发:
// 1. 暂停任务,这时候task.status == .suspended
// 2. 任务下载失败,这时候task.status == .failed
// 3. 取消任务,这时候task.status == .canceled
// 4. 移除任务,这时候task.status == .removed
let task = TRManager.default.download("http://api.gfs100.cn/upload/20171219/201712191530562229.mp4")

task?.progress({ (task) in
    let progress = task.progress.fractionCompleted
    print("下载中, 进度:\(progress)")
}).success({ (task) in
    print("下载完成")
}).failure({ (task) in
    print("下载失败")
})
复制代码

下载任务的管理和操做。在Tiercel中,URLString是下载任务的惟一标识,若是须要对下载任务进行操做,则使用TRManager实例对URLString进行操做。

let URLString = "http://api.gfs100.cn/upload/20171219/201712191530562229.mp4"

// 建立下载任务而且开启下载,同时返回可选类型的TRDownloadTask实例,若是URLString无效,则返回nil
let task = TRManager.default.download(URLString)
// 根据URLString查找下载任务,返回可选类型的TRTask实例,若是不存在,则返回nil
let task = TRManager.default.fetchTask(URLString)

// 开始下载
// 若是调用suspend暂停了下载,能够调用这个方法继续下载
TRManager.default.start(URLString)

// 暂停下载
TRManager.default.suspend(URLString)

// 取消下载,没有下载完成的任务会被移除,不保留缓存,已经下载完成的不受影响
TRManager.default.cancel(URLString)

// 移除下载,任何状态的任务都会被移除,没有下载完成的缓存文件会被删除,能够选择是否保留已经下载完成的文件
TRManager.default.remove(URLString, completely: false)

// 除了能够对单个任务进行操做,TRManager也提供了对全部任务同时操做的API
TRManager.default.totalStart()
TRManager.default.totalSuspend()
TRManager.default.totalCancel()
TRManager.default.totalRemove(completely: false)
复制代码

后台下载

Tiercel 2 的下载实现基于URLSessionDownloadTask,支持原生的后台下载,按照苹果官方文档的要求,TRManager实例必须在App启动的时候建立,而且在AppDelegate 文件里实现如下方法

// 必须实现此方法,而且把identifier对应的completionHandler保存起来
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {

    if TRManager.default.identifier == identifier {
        TRManager.default.completionHandler = completionHandler
    }
}
复制代码

只要使用Tiercel 开启了下载任务:

  • 手动Kill App,任务会暂时,重启App后能够恢复进度,继续下载
  • 只要不是手动Kill App,任务会一直在下载
    • 把App退回后台,任务会一直在下载
    • 不管在前台仍是后台,若是App崩溃或者被系统关闭,任务仍是会一直在下载
    • 重启手机,任务会一直在下载

若是想了解后台下载的细节和注意事项,能够看这篇文章:iOS原生级别后台下载详解

文件校验

Tiercel提供了文件校验功能,能够根据须要添加,校验结果在回调的task.validation

// 回调闭包在主线程运行
let task = TRManager.default.download("http://dldir1.qq.com/qqfile/QQforMac/QQ_V4.2.4.dmg")

task?.validateFile(verificationCode: "9e2a3650530b563da297c9246acaad5c",
                   verificationType: .md5,
                   validateHandler: { (task) in
                    if task.validation == .correct {
                        // 文件正确
                    } else {
                        // 文件错误
                    }
})
复制代码

TRChecksumHelper是文件校验的工具类,能够直接使用它对已经存在的文件进行校验

/// 对文件进行校验,是在子线程进行的
///
/// - Parameters:
/// - filePath: 文件路径
/// - verificationCode: 文件的Hash值
/// - verificationType: Hash类型
/// - completion: 完成回调
public class func validateFile(_ filePath: String, verificationCode: String, verificationType: TRVerificationType, completion: @escaping (Bool) -> ()) {
    
}
复制代码

TRManager

TRManager是下载任务的管理者,管理当前模块全部下载任务,内置一个全局的default单例,若是须要多个下载模块,或者须要自定义TRManager,能够手动建立TRManager实例。

⚠️⚠️⚠️ 按照苹果官方文档的要求,TRManager实例必须在App启动的时候建立,即TRManager的生命周期跟App几乎一致,为方便使用,最好是做为AppDelegate的属性,或者是全局变量,具体请参照Demo

/// 初始化方法
///
/// - Parameters:
/// - identifier: 设置TRManager实例的标识,区分不一样的下载模块,同时为urlSession的标识,原生级别的后台下载必需要有惟一标识
public init(_ identifier: String) {
    // 实现的代码... 
}
复制代码

TRManager做为全部下载任务的管理者,也能够设置回调

// 回调闭包的参数是TRManager实例,能够获得全部相关的信息
// 回调闭包都是在主线程运行
// progress 闭包:只要有一个任务正在下载,就会触发
// success 闭包:只有一种状况会触发:
// 全部任务都下载成功(取消和移除的任务会被移除而后销毁,再也不被manager管理) ,这时候manager.status == .succeeded
// failure 闭包:只要manager.status != .succeeded,就会触发:
// 1. 调用所有暂停的方法,或者没有等待运行的任务,也没有正在运行的任务,这时候manager.status == .suspended
// 2. 全部任务都结束,但有一个或者多个是失败的,这时候manager.status == .failed
// 3. 调用所有取消的方法,或者剩下一个任务的时候把这个任务取消,这时候manager.status == .canceled
// 4. 调用所有移除的方法,或者剩下一个任务的时候把这个任务移除,这时候manager.status == .removed
TRManager.default.progress { (manager) in
    let progress = manager.progress.fractionCompleted
    print("downloadManager运行中, 总进度:\(progress)")
    }.success { (manager) in
         print("全部下载任务都成功了")
    }.failure { (manager) in
         if manager.status == .suspended {
            print("全部下载任务都暂停了")
        } else if manager.status == .failed {
            print("存在下载失败的任务")
        } else if manager.status == .canceled {
            print("全部下载任务都取消了")
        } else if manager.status == .removed {
            print("全部下载任务都移除了")
        }
}
复制代码

TRManager的主要属性

// 内置的全局单例
public static let `default` = TRManager("default")
// 设置内置日志打印等级,若是为none则不打印
public static var logLevel: TRLogLevel = .detailed
// 是否须要对networkActivityIndicator进行管理
public static var isControlNetworkActivityIndicator = true
// TRManager的状态
public var status: TRStatus = .waiting
// TRManager的缓存管理实例
public var cache: TRCache
// TRManager的标识,区分不一样的下载模块
public let identifier: String
// TRManager的进度
public var progress: Progress
// TRManager的配置,能够设置请求超时时间,最大并发数,是否容许蜂窝网络下载
public var configuration = TRConfiguration()
// 全部下载中的任务加起来的总速度
public private(set) var speed: Int64 = 0
// 全部下载中的任务须要的剩余时间
public private(set) var timeRemaining: Int64 = 0
// manager管理的下载任务,取消和移除的任务会被销毁,但操做是异步的,在回调闭包里面获取才能保证正确
public var tasks: [TRTask] = []
复制代码

TRConfiguration

TRConfiguration是Tiercel中配置TRManager的结构体,可配置属性以下:

// 请求超时时间
public var timeoutIntervalForRequest = 30.0

// 最大并发数
public var maxConcurrentTasksLimit = Int.max

// 是否容许蜂窝网络下载
public var allowsCellularAccess = false
复制代码

更改TRManager的配置

// 不管是否有下载任务正在运行,均可以在任何地方,随时配置
// 若是只是更改某一项,能够直接对TRManager属性设置
TRManager.default.configuration.allowsCellularAccess = true

// 若是是须要更改多项,最好是从新建立TRConfiguration
let configuration = TRConfiguration()
configuration.allowsCellularAccess = true
configuration.maxConcurrentTasksLimit = 2
configuration.timeoutIntervalForRequest = 60

TRManager.default.configuration = configuration
复制代码

TRDownloadTask

TRDownloadTask是Tiercel中的下载任务类,继承自TRTask。**在Tiercel中,URLString是下载任务的惟一标识,URLString表明着任务,若是须要对下载任务进行操做,则使用TRManager实例对URLString进行操做。**因此TRDownloadTask实例都是由TRManager实例建立,单首创建没有意义。

主要属性

// 保存到沙盒的下载文件的文件名,若是在下载的时候没有设置,则默认为url的md5加上文件扩展名
public internal(set) var fileName: String
// 下载任务对应的URLString
public let URLString: String
// 下载任务的状态
public var status: TRStatus
// 下载文件的校验状态
public var validation: TRValidation
// 下载任务的进度
public var progress: Progress = Progress()
// 下载任务的开始日期
public var startDate: TimeInterval = 0
// 下载任务的结束日期
public var endDate: TimeInterval = Date().timeIntervalSince1970
// 下载任务的速度
public var speed: Int64 = 0
// 下载任务的剩余时间
public var timeRemaining: Int64 = 0
// 下载文件路径
public var filePath: String
// 下载文件的扩展名
public var pathExtension: String?
复制代码

对下载任务操做,必须经过TRManager实例进行,不能用TRDownloadTask实例直接操做

  • 开启
  • 暂停
  • 取消,没有完成的任务从TRManager实例中的tasks中移除,不保留缓存,已经下载完成的任务不受影响
  • 移除,已经完成的任务也会被移除,没有下载完成的缓存文件会被删除,已经下载完成的文件能够选择是否保留

注意:对下载中的任务进行暂停、取消和移除操做,结果是异步回调的,在回调闭包里面获取状态才能保证正确

TRCache

TRCache是Tiercel中负责管理缓存下载任务信息和下载文件的类。TRCache实例通常做为TRManager实例的属性来使用,一样地,Tiercel内置一个全局的TRCache.default单例,对应TRManager.default

/// 初始化方法
///
/// - Parameters:
/// - name: 不一样的name,表明不一样的下载模块,对应的文件放在不一样的地方,对应TRManager建立时传入的identifier
public init(_ name: String) {
    // 实现的代码...
}
复制代码

主要属性

// 下载模块的目录路径
public let downloadPath: String

// 没有完成的下载文件缓存的目录路径
public let downloadTmpPath: String

// 下载完成的文件的目录路径
public let downloadFilePath: String
复制代码

主要API分红几大类:

  • 检查沙盒是否存在文件
  • 移除跟下载任务相关的文件
  • 保存跟下载任务相关的文件
  • 读取下载任务相关的文件,得到下载任务相关的信息

License

Tiercel is available under the MIT license. See the LICENSE file for more info.

相关文章
相关标签/搜索