Reed is a downloader framework for Swift. It is many fetures, stability,fast, ow coupling, easily extended. It use ActiveSQLite to persist datas。
- Multi download tasks
- Resume at break-point
- Max concurrent count
- Validate md5 file
- Check full space
- Thread safe
- Multi scope
- Log with CocoaLumberjack
- Background download
- OperationQueue
Core Downloader only exist memory, it not use database. Can use it download without Reed layer.
It save download model in database, deal with download status changes, handle errors, post notifications.
This is a simple version of model:
class ReedInfo {
var key:String = "" //Identifier
var url:String = ""
var md5:String?
var totalBytes:NSNumber = 0
var writedBytes:NSNumber = 0
var destFilePath = ""
var cacheFilePath = ""
var context = ""
var downloadListKey = ""
var downloadStatus:ReedDownloadStatus = .waiting
var downloadFailReason:ReedDownloadFailReason?
}
public enum ReedDownloadStatus: String {
case waiting
case downloading
case pause
case completed
case faild
}
public enum ReedDownloadFailReason:String{
case unknown
case timeout
case noNetwork
case fullSpace
case md5Verification
}
/// key: Identifier
/// url:
/// destinationFilePath:eg:”Documents/xxxx/filename.pdf“
/// downloadListKey : Default value is nil. can exist many than one downloadlist
/// md5: Value of md5. Default value is nil.
/// isReplace: Replace the old download destination file and cache file. Default value is false
Reed.shared.start(key:"key", url:"url", destinationFilePath:"Documents/filename.pdf",downloadListKey:"PDF_DOWNLOAD_LIST",md5:nil,isReplace:false)
Reed.shared.addToStartList(key:"key", url:"url", destinationFilePath:"Documents/filename.xxx")
Reed.shared.start(key: "key")
Reed.shared.addToStartList(key:"key", url:"url", destinationFilePath:"Documents/filename.xxx")
Reed.shared.checkToStart()
checkToStart(downloadListKey:String? == nil)
check free space on device;
check max concurrent download count in the downloadlist;
start download task whoes is waiting status, and order by added date and ;
1,Network become available. opposite shutdown.
2.User login. opposite shutdown.
3.App launch if need.
4.Reed call by its self when a download task change its status (complete,pause,failed,delete). The downloading count sub 1, may start other waiting task.
First | Second | Third |
context1 | DownloadListKey1 | key1 |
key2 | ||
key3 | ||
DownloadListKey2 | key4 | |
key5 | ||
key6 | ||
key7 |
context is first level scope
The value of ReedInfo.context come from the value of Reed.shared.context. they are the same.
eg: App launch -> set Reed.shared.context -> start download.
eg: shutDown() -> set Reed.shared.context -> start download.
context usually used to separate different users.
eg: logout() -> shutDown() -> login() -> set Reed.shared.context.
downloadListKey is a porperty of ReedInfo.
A pair of context and downloadListKey define a downloadListKey, it has itself‘s max concurrent download count.
downloadlistkey usually used for different business eg:named PDF_LIST, MP3_LIST.
key is a porperty of ReedInfo, you must set every task different identifier key.
Noti_ReedDownload_Add_To_Downlaod_List
Noti_ReedDownload_Start
Reed.downloadProgressNotification
Reed.downloadCompleteNotification
Reed.downloadFailsNotification
Noti_ReedDownload_Waiting
Reed.downloadPauseNotification
Reed.downloadDeleteNotification
Reed.downloadFullSpaceNotification
Every notification contains a object, its type is ReedInfo.
If full space, Reed will post one or more notifications whose object is ReedInfo, and post 1 notification that object = nil.
///Add a task to downloadlist
public func addToStartList(key:String, url:String, destinationFilePath:String,downloadListKey:String? = nil,md5:String? = nil,isReplace:Bool = false)
/// start download when added a task to downloadlist
public func start(_ key:String, isReplace:Bool = false)
/// Direct download. not recommend. Recommend use addToStartList and checkToStart.
public func start(key:String, url:String, destinationFilePath:String, downloadListKey:String? = nil,md5:String? = nil,isReplace:Bool = false)
/// batch start download
public func startBatch(keys:[String])
/// check to start. Go to "Introduce checkToStart()" on this ReadMe.
public func checkToStart()
/// check to start on this downloadList.
public func checkToStart(downloadListKey:String)
///isTryStart meens:If call checkToStart() after the action. usually use default value.
public func pause(_ key:String, isTryStart:Bool? = true)
public func pauseBatch(keys:[String],isTryStart:Bool? = true)
public func deleteBatch(keys:[String],isTryStart:Bool? = true)
public func delete(_ key:String,isTryStart:Bool? = true)
//Shutdown all tasks. But all status of tasks are not changed.
//Execute this when:logout;no network;go to background.
public func shutDown()
/// is downloading progress
/// (Downloading, waiting, pause, failed)
public func isDownloadingProgress(_ key:String) -> Bool
/// is undownload (un add to download list, un start, no record on database)
public func isUnDownload(_ key:String) -> Bool
public func isComplete(_ key:String) -> Bool
public func isDownloading(_ key:String) -> Bool
public func isPause(_ key:String) -> Bool
public func isWaiting(_ key:String) -> Bool
public func isFailed(_ key:String) -> Bool
/// get download model with key
public func getDownloadInfo(key:String) -> ReedInfo?
/// get all models on this downloadListKey
public func getDownloadInfos(downloadListKey:String? = nil) -> [ReedInfo]
/// get all models on download progress(Downloading,Waiting,Pause,Failed)
public func getDownloadProgressInfos(downloadListKey:String? = nil) -> [ReedInfo]
/// get all complete models
public func getCompleteInfos(downloadListKey:String? = nil) -> [ReedInfo]
@objc public func getDownloadProgressCount(downloadListKey:String? = nil) -> Int
@objc public func getDownloadingCount(downloadListKey:String? = nil) -> Int
@objc public func getWaitingCount(downloadListKey:String? = nil) -> Int
@objc public func getPauseCount(downloadListKey:String? = nil) -> Int
/// Concurrent max download count on one downloadlist,default value is 3
Reed.shared.maxCount
/// Retry count when md5 invalidate,default value is 3
Reed.shared.maxRetryCount
/// Set it before start download, default value is ""
public var context
/// min interval between two download progress notifications been post, default value is 0.3 seconds
Reed.shared.progressPostTimeInterval:TimeInterval
/// If you use CocoaLumberjack,Reed would use your CocoaLumberjack configration.
/// If you not use CocoaLumberjack, Reed would not print whenever what value of showLogger.
Reed.shared.showLogger:Bool = true
/// If you not use CocoaLumberjack,Call this method to config CocoaLumberjack
/// timeFormatter:Date message of every log,default value is "yyyy-MM-dd'T'HH:mm:ss.SSSZ" of Date()
public func configLogger(level:DDLogLevel? = .info, timeFormatter:(()->String)? = nil)
- iOS 8.0+
- Xcode 10.2
- Swift 5
Aadd the following line to your Podfile:
pod "Reed"
Kevin Zhou
- Email: wumingapie@gmail.com
- Facebook: wumingapie
- 微信&QQ: 458545592
Reed is available under the MIT license. See the LICENSE file for more info.