Reed 1.0.0

Reed 1.0.0

Maintained by Refael Zhou.



 
Depends on:
CocoaLumberjack/Swift>= 0
ActiveSQLite= 0.5.1
ZKCommonCrypto>= 0
 

Reed 1.0.0

  • By
  • taozui

Reed

Version

License Platform

Reed is a downloader framework for Swift. It is many fetures, stability,fast, ow coupling, easily extended. It use ActiveSQLite to persist datas。

中文版

Features

  • 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

Demo

Design

- Core Downloader -> Pure Downloader

Core Downloader only exist memory, it not use database. Can use it download without Reed layer.

- Reed Download Manager -> Download Manager

It save download model in database, deal with download status changes, handle errors, post notifications.

Major Words

1 Model of download info

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? 
    
}

2 Status of download

public enum ReedDownloadStatus: String {
    case waiting
    case downloading
    case pause
    case completed
    case faild
}

3 Reason of download failed

public enum ReedDownloadFailReason:String{
    case unknown
    case timeout
    case noNetwork
    case fullSpace
    case md5Verification
}

Usage

Start download

1 Direct download

/// 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)

2 Add task to download list at first, and then start it.

Reed.shared.addToStartList(key:"key", url:"url", destinationFilePath:"Documents/filename.xxx")


Reed.shared.start(key: "key")

3 Add task to download list at first, and then check to start(Recommend)

Reed.shared.addToStartList(key:"key", url:"url", destinationFilePath:"Documents/filename.xxx")

Reed.shared.checkToStart()

Introduce checkToStart()

Define:

checkToStart(downloadListKey:String? == nil)

Description:

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 ;

Use Case:

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.

Scope

First Second Third
context1
DownloadListKey1 key1
key2
key3
DownloadListKey2 key4
key5
key6
key7

1 context

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.

2 downloadlistkey

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.

3 key

key is a porperty of ReedInfo, you must set every task different identifier key.

Notifications

Noti_ReedDownload_Add_To_Downlaod_List

Noti_ReedDownload_Start

Noti_ReedDownload_Progress

Noti_ReedDownload_Complete

Noti_ReedDownload_Fails

Noti_ReedDownload_Waiting

Noti_ReedDownload_Pause

Noti_ReedDownload_Delete

Noti_ReedDownload_FullSpace

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.

Most commonly used API

APIs relate control

	///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()
    

APIs relate status

    /// 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
    

Config

 	 /// 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)

Requirements

  • iOS 8.0+
  • Xcode 10.2
  • Swift 5

Installatio

Cocoapods

Aadd the following line to your Podfile:

pod "Reed"

Author

Kevin Zhou

License

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