DownloadListController

@objcMembers open class DownloadListController: SDETableViewController, AccessoryButtonDelegate, UIPopoverPresentationControllerDelegate

DownloadListController is a UITableViewController subclass and is born to coordinate with SDEDownloadManager to manage download tasks and track download activity.

It has rich custom options:

  • You can display the whole download list, or specified part by displayContent.

  • All elements in the default cell DownloadTrackerCell are customizable.

Of course, they are predefined and limited. If default cell can’t satisfy your needs, you could use your custom UITableViewCell. More details in init method: init(downloadManager:tableViewStyle:registerCellClasses:configureCell:).

  • Adjust max download count by adjustButtonItem.

  • Sort list by sortButtonItem.

  • Custom task management features in cell swipe. All features are disabled by default. Relative properties: allowsStop, allowsDeletion, allowsRedownload, allowsRestoration.

  • Support multiple selection. Task management features in multiple selection mode(also edit mode) could be customed in leftNavigationItemActions. Multiple selection is disabled by default. Two way to activate it:

    1. editButtonItem: enable allowsEditingByEditButtonItem to display editButtonItem at the right of navigationBar, or put editButtonItem on somewhere directly.
    2. long press gesture: enable allowsEditingByLongPress.
  • Offer management features for all tasks on the toolbar. Disabled by default and enable it by allowsManagingAllTasksOnToolBar. These features could be customed in toolBarActions.

  • Predefined UIBarButtonItem has two appearances: title or icon. Relative properties: barButtonAppearanceStyle, buttonIconFilled.

  • Provide custom headerView in headerViewProvider.

  • Custom selection behavior by didSelectCellHandler and didDeselectCellHandler.

  • If init from storyboard/nib file, reassign downloadManager after initialization.

    Declaration

    Swift

    required public init?(coder aDecoder: NSCoder)
  • One of designated init method with optional cell configuration closure. In this initializer, tableView use DownloadTrackerCell, which adds a label to show download speed, a progressView to show download progress and a button to pause/resume download. You can configure cell in parameter configureCell. If you want to use your custom UITableViewCell subclass, you can use the other designated init method: init(downloadManager:tableViewStyle:registerCellClasses:configureCell:).

    Declaration

    Swift

    public init(downloadManager: SDEDownloadManager,
                tableViewStyle style: UITableViewStyle = .plain,
                configureCell cellClosure: ((_ cell: DownloadTrackerCell, _ indexPath: IndexPath, _ URLString: String) -> Void)? = nil)

    Parameters

    downloadManager

    A SDEDownloadManager object.

    style

    UITableView style. The default value is .plain.

    cellClosure

    The closure to configure cell in tableView(_:cellForRowAtIndexPath:). The default is nil.

    cell

    A DownloadTrackerCell.

    indexPath

    Cell location.

    URLString

    The download URL string at this location.

  • One of designated init method with required cell configuration closure. In this initializer, you must specify UITableViewCell class which you want to use in the tableView and configure it. The follow init code is equal to the other initializer: init(downloadManager:tableViewStyle:configureCell:):

    DownloadListController.init(
        downloadManager: downloadManager,
        tableViewStyle: .plain,
        registerCellClasses: [DownloadTrackerCell.self],
        configureCell: { tableView, indexPath, URLString in
            return tableView.dequeueReusableCell(withIdentifier: "DownloadTrackerCell", for: indexPath)
    })
    

    If your custom UITableViewCell subclass implement methods in protocol DownloadActivityTrackable (I make UITableViewCell comform to this protocol in extension already), your custom UITableViewCell is compatible with some existed properties, include:

    1. allowsTrackingDownloadDetail: If your cell implement updateDetailInfo(_ info: String?);
    2. allowsTrackingProgress: If your cell implement updateProgressValue(_ progress: Float);
    3. allowsTrackingSpeed: If your cell implement updateSpeedInfo(_ text: String?);
    4. cellAccessoryButtonStyle: A little long, look detail in cellAccessoryButtonStyle document.

    Declaration

    Swift

    public init(downloadManager: SDEDownloadManager,
                tableViewStyle style: UITableViewStyle = .plain,
                registerCellClasses cellClasses: [UITableViewCell.Type],
                configureCell cellClosure: @escaping ((_ tableView: UITableView, _ indexPath: IndexPath, _ URLString: String) -> UITableViewCell))

    Parameters

    downloadManager

    A SDEDownloadManager object.

    style

    UITableView style. The default is .plain.

    cellClasses

    Custom UITableViewCell subclasses which you want to use in the tableView, for example: [UITableViewCell.self]. The registered identifier of cell is class name.

    cellClosure

    The closure to configure cell in tableView(_:cellForRowAtIndexPath:).

    tableView

    The tableView.

    indexPath

    Cell location.

    URLString

    The download URL string at this location.

  • A Enum value to select content to display, the whole download list or part. The default value is .downloadList.

    Declaration

    Swift

    public var displayContent: ListContent = .downloadList
  • Specify which subsection in download list you want to display. The default value is 0. Works only when displayContent == .subsection.

    Declaration

    Swift

    lazy public var subsectionIndex: Int = 0
  • A Boolean value that determines whether display header title. The default value is true. Note: when tableView.style == .plain, subsections can’t be distinguished if it doesn’t display header title.

    Declaration

    Swift

    public var shouldDisplaySectionTitle: Bool = true
  • A Boolean value decides to display file name or download url in cell’s textLabel. The default value is true.

    Declaration

    Swift

    public var isFileNamePriorThanURL: Bool = true
  • A Enum value to set content to display in UITableViewCell’s imageView. The default value is .thumbnail. This property is valid no matter what UITableViewCell type you use in this class.

    Declaration

    Swift

    public var cellImageViewStyle: CellImageViewStyle = .thumbnail
  • A Enum value to specify thumbnail shape. Works only when cellImageViewStyle == .thumbnail. The default value is .original. If thumbnail is smaller than requested, even this property is .square, thumbnail is still displayed in original scale.

    Declaration

    Swift

    public var fileThumbnailShape: ThumbnailShape = .original
  • A Enum value to specify appearance of accessory button in DownloadTrackerCell: icon, title, or just hidden button. The default value is .icon.

    • .icon: Accessory button shows an icon which bind to task state and is predefined.
    • .title: Accessory button shows a title which bind to task state and is predefined.
    • .none: Hidden accessory button in the cell.

    If above styles can’t satisfy you, you could custom button totally by setting it to .custom:

    • .custom: Accessory button has no title or image to be visible in this style; touching button won’t happen anything. It’s all up to you.

    How to custom DownloadTrackerCell in .custom style?

    1. custom its title or image in init method parameter configureCell;
    2. custom button action in accessoryButtonTouchHandler. There is an example in the document of accessoryButtonTouchHandler.

    If you use custom UITableViewCell, not default DownloadTrackerCell, and want to get the same effect like DownloadTrackerCell, it’s easy:

    To be compatible with .icon style, your custom UITableViewCell should implement updateAccessoryButtonState(_:image:) in protocol DownloadActivityTrackable, this method will be called in nececssary place to update accessory button;

    To be compatible with .title style, your custom UITableViewCell should implement updateAccessoryButtonState(_:title:) in protocol DownloadActivityTrackable, this method will be called in nececssary place to update accessory button;

    For .none and custom style, DownloadListController doesn’t do anything to accessory button of DownloadTrackerCell. Of cource, in .none style, your custom UITableViewCell should hidden button, actually, DownloadTrackerCell only display button in icon and .title style, your custom UITableViewCell could do same thing, or do it in init method parameter configureCell, it’s up to you.

    Declaration

    Swift

    public var cellAccessoryButtonStyle: AccessoryButtonStyle = .icon
  • A closure to custom action method of accessory button in the DownloadTrackerCell. The default value is nil.

    If predefined action can’t satisfy your needs, you colud set cellAccessoryButtonStyle = .custom and configure button action in this closure. And when cellAccessoryButtonStyle == .custom, you must set accessory button’s title or image to make it visible, do it in init method parameter configureCell.

    An example, you want accessory button to show other icon and response as you want, do it like this:

    let listVC = DownloadListController.init(
                    downloadManager: downloadManager,
                    tableViewStyle: .plain,
                    configureCell: {
                        trackerCell, indexPath, URLString in
                        if /....../{
                            trackerCell.accessoryButton?.setImage(icon0, for: .normal)
                        }else{
                            trackerCell.accessoryButton?.setImage(icon1, for: .normal)
                        }
                 })
    listVC.cellAccessoryButtonStyle = .custom
    listVC.accessoryButtonTouchHandler = { tableView, cell, button in
        /* custom button action
    

    Declaration

    Swift

    public var accessoryButtonTouchHandler: ((_ tableView: UITableView, _ cell: UITableViewCell, _ button: UIButton) -> Void)?
  • A Boolean value that determines whether DownloadTrackerCell displays download progress info in detailTextLabel. The default value is true. If you use custom UITableViewCell, implement updateDetailInfo(_ info: String?) in protocol DownloadActivityTrackable to be compatible with this property.

    Declaration

    Swift

    public var allowsTrackingDownloadDetail: Bool = true
  • A Boolean value that determines whether DownloadTrackerCell displays download speed in a label. The default value is true. If you use custom UITableViewCell, implement updateSpeedInfo(_ info: String?) in protocol DownloadActivityTrackable to be compatible with this property.

    Declaration

    Swift

    public var allowsTrackingSpeed: Bool = true
  • A Boolean value that determines whether DownloadTrackerCell displays download progress in a progressView. The default value is true. If you use custom UITableViewCell, implement updateProgressValue(_ progress: Float) in protocol DownloadActivityTrackable to be compatible with this property.

    Declaration

    Swift

    public var allowsTrackingProgress: Bool = true
  • A Boolean value that determines whether user can stop downloading task in cell swipe and multiple selection mode. The default value is false.

    Declaration

    Swift

    lazy public var allowsStop: Bool = false
  • A Boolean value that determines whether user can delete file in cell swipe and multiple selection mode. The default value is false. Use deleteMode to decide how to delete a task.

    Declaration

    Swift

    lazy public var allowsDeletion: Bool = false
  • A Enum value to decide how to delete a task, file or record? The defalut value is .fileAndRecord.

    Declaration

    Swift

    public var deleteMode: DeleteMode = .fileAndRecord
  • A Boolean value that determines whether user can redownload a file in cell swipe. The default value is false. This feature is just available for finished or stoped task.

    Declaration

    Swift

    lazy public var allowsRedownload: Bool = false
  • A Boolean value that determines whether user can restore deleted task in cell swipe and multiple selection mode. The default value is false. Works only when displayContent == .toDeleteList.

    Declaration

    Swift

    lazy public var allowsRestoration: Bool = false
  • A Boolean value that determines whether user can rename file in cell swipe. The default value is false. This feature is just available for finished or stoped task.

    Declaration

    Swift

    lazy public var allowsRenamingFile: Bool = false
  • A Boolean value that determines whether display editButtonItem at the right of navigationBar. The default value is false.

    Declaration

    Swift

    lazy public var allowsEditingByEditButtonItem: Bool = false
  • A Boolean value that determines whether user can enter edit mode(also multiple selection mode) by long press. The default value is false.

    Declaration

    Swift

    lazy public var allowsEditingByLongPress: Bool = false
  • A Boolean value that determines whether exit edit mode(also multiple selection mode) after user confirm operation. The default value is false.

    Declaration

    Swift

    lazy public var shouldExitEditModeAfterConfirmAction: Bool = false
  • Decide what features to display at the left of navigationBar in edit mode(also multiple selection mode). The default value includes all features.

    This property is invisible in Objective-C code, use leftNavigationItemActionRawValues.

    There is a way to filter part features in Objective-C code, e.g., if allowsDeletion == false, .deleteSelected will be filtered. allowsStop and allowsRestoration also works.

    Declaration

    Swift

    lazy public var leftNavigationItemActions: [NavigationBarAction] = [.selectAll, .resumeSelected, .pauseSelected, .stopSelected, .deleteSelected, .restoreSelected]
  • Alternate for leftNavigationItemActions in Objective-C code.

    Declaration

    Swift

    public var leftNavigationItemActionRawValues: [Int]?
  • A Boolean value that determines whether display Toolbar with predefined features. The default value is false. Custom features in toolBarActions. This property is ignored and toolbar won’t be displayed if displayContent == .toDeleteList.

    Declaration

    Swift

    public var allowsManagingAllTasksOnToolBar: Bool = false
  • Predefined features displayed on the Toolbar. The default value include features: ResumeAllTask(), PauseAllTask(), StopAllTasks(). This property is ignored if allowsManagingAllTasksOnToolBar == false.

    This property is invisible in Objective-C code, use toolBarActionRawValues.

    Declaration

    Swift

    lazy public var toolBarActions: [ToolBarAction] = [.resumeAll, .pauseAll, .stopAll]
  • Alternate for toolBarActions in Objective-C code.

    Declaration

    Swift

    public var toolBarActionRawValues: [Int]?
  • A Boolean value that determines whether user can edit title of section when long pressing on header view. The default value is false.

    Precondition

    downloadManager.sortType == .manual.

    Declaration

    Swift

    lazy public var allowsEditingSectionTitle: Bool = false
  • A Boolean value that determines wherther remove section automatically after all tasks in it are gone(moved or deleted). In predefined mode, empty section are removed automatically. The default value is true.

    Precondition

    displayContent == .downloadList && downloadManager.sortType == .manual.

    Declaration

    Swift

    lazy public var shouldRemoveEmptySection: Bool = true
  • A Boolean value that determines wherther provide an control at the left of header view to insert an empty new section after that section when tableView enter edit mode(also multiple selection mode). The default value is false.

    Note: This property is valid only when enter edit mode by editButtonItem, allowsEditingByEditButtonItem or allowsEditingByLongPress.

    Precondition

    displayContent == .downloadList && downloadManager.sortType == .manual.

    Declaration

    Swift

    lazy public var allowsInsertingSection: Bool = false
  • A closure to be executed in UITableView delegate method: tableView(_:didSelectRowAtIndexPath:). String parameter in closure is download URL string at that location. The default value is nil.

    Declaration

    Swift

    public var didSelectCellHandler: ((_ tableView: UITableView, _ indexPath: IndexPath, _ URLString: String) -> Void)?
  • A closure to be executed in UITableView delegate method: tableView(_:didDeselectRowAtIndexPath:). String parameter in closure is download URL string at that location. The default value is nil.

    Declaration

    Swift

    public var didDeselectCellHandler: ((_ tableView: UITableView, _ indexPath: IndexPath, _ URLString: String) -> Void)?
  • A closure to provide header view. The default value is nil. I suggest you use UITableViewHeaderFooterView.

    Declaration

    Swift

    public var headerViewProvider: ((_ tableView: UITableView, _ section: Int) -> UIView?)?
  • This property is used to optimize scroll performance when any file is downloading. Scroll speed is count of scrolled cell in 1 second. When downloading file, download manager track download activity and update cells in DownloadListController. It’s no necessary if scroll speed is high. Of course, download activities in cells are updated in other place even scroll speed is high. I suggest that the value is the half value of cell count which screen could have. The default value is 10.

    Declaration

    Swift

    public var scrollSpeedThresholdForPerformance: Int = 10
  • A UIBarButtonItem to display a view to sort the download list. And use shouldDisplaySortOrderInSortView property to custom sort view.

    You should only use this button item when displayContent == .downloadList, or, displayContent == .subsection but download manager’s sort type is manual.

    Declaration

    Swift

    lazy public var sortButtonItem: UIBarButtonItem =
  • A Boolean value that decides whether to display sort order options(.ascending and .descending) in the sort view. The default value is true.

    Declaration

    Swift

    lazy public var shouldDisplaySortOrderInSortView: Bool = true
  • A Boolean value that decides whether to offer options for download manager to switch to the other sort mode in sort view. The default value is false. It works only when displayContent == .downloadList.

    Declaration

    Swift

    public var allowsSwitchingSortMode: Bool = false
  • A UIBarButtonItem to display a view to adjust max download count.

    Declaration

    Swift

    public lazy var adjustButtonItem: UIBarButtonItem =
  • Return the URL string of download task at the location.

    Declaration

    Swift

    public func downloadURLString(at indexPath: IndexPath) -> String?

    Parameters

    indexPath

    The download task location.

    Return Value

    The download URL string of task.

  • Return location of download task based on its URL string.

    Declaration

    Swift

    public func indexPath(forURLString URLString: String) -> IndexPath?

    Parameters

    URLString

    The download URL string of task.

    Return Value

    Task location in current list.

  • Handle touch event for button in DownloadTrackerCell. If you want DownloadListController to handle touch event for your custom UITableViewCell, implement assignAccessoryButtonDeletegate(_:) in protocol DownloadActivityTrackable and in button’s action method, send this only protocol method to delegate object.

    Declaration

    Swift

    public func tableViewCell(_ cell: UITableViewCell, didTouch button: UIButton, for controlEvents: UIControlEvents)

    Parameters

    cell

    The UITableViewCell.

    button

    The touched button in the cell.

    controlEvents

    The touch event.

  • Replace index sign with an image. And If any another cell’s index sign is replaced already, this method restores its original index sign.

    Precondition

    cellImageViewStyle == .index

    Declaration

    Swift

    public func replaceIndexOfCell(at indexPath: IndexPath, withImage image: UIImage)

    Parameters

    indexPath

    Cell location.

    image

    Image to replace index sign.

  • Restore index sign if it’s replaced by an image.

    Declaration

    Swift

    public func restoreIndexOfCell(at indexPath: IndexPath)

    Parameters

    indexPath

    Cell location.

  • This method is called after the controller has loaded its view hierarchy into memory. But when the controller load its view hierarchy? Before it presents or access any view in the view hierarchy if controller isn’t presented yet. Called only once.

    Declaration

    Swift

    override open func viewDidLoad()
  • Called every time the view controller is about to be presented onscreen.

    Declaration

    Swift

    override open func viewWillAppear(_ animated: Bool)
  • Called every time the view controller is presented onscreen.

    Declaration

    Swift

    override open func viewDidAppear(_ animated: Bool)
  • Called every time the view disappear from screen.

    Declaration

    Swift

    override open func viewDidDisappear(_ animated: Bool)
  • If this method returns 0, other data source methods won’t be called.

    Declaration

    Swift

    override open func numberOfSections(in tableView: UITableView) -> Int
  • Emtpy section is called preferentially.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
  • Create a cell before relative row display.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
  • Called every time cell is moved into the screen.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
  • If it returns empty string or nil, there is not header view.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
  • Provide custom header view. If it returns non-nil, tableView(_:titleForHeaderInSection:) is ignored.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
  • Called every time header view is moved into the screen.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
  • Returns strings displayed at right side of tableView. Use UILocalizedIndexedCollation to provide alphabet.

    Declaration

    Swift

    override open func sectionIndexTitles(for tableView: UITableView) -> [String]?
  • Returns relative section for index title you touch at right side of tableView. If title has no relative section, return NSNotFound.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int
  • Allow to display controls(includes row action) in the cell or not. If return false, no control is displayed.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool
  • Decide control style at the left of cell if tableView is editing and allowsMultipleSelectionDuringEditing == false.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle
  • Filter cells to show reorder control at the right if tableView is editing. Reorder control and other controls at the left could coexist.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
  • Move cell and update data. This method must be implemented to show a reorder control at the right. And cell is moved correctly even this method doesn’t update underlying data, of course, there will be an error in the later.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
  • Provide row actions at the right of cell in left swipe. Cell swipe can’t be used when tableView is editing.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]?
  • If tableView.isEditing == false, this method is called after you select a cell if any of allowsSelection and allowsMultipleSelection is true; If tableView.isEditing == true, this method is called after you select a cell if any of allowsSelectionDuringEditing and allowsMultipleSelectionDuringEditing is true.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
  • If allowsSelection == true && allowsMultipleSelection == false, this method is called after you select another cell; if allowsMultipleSelection == true(allowsSelection is ignored), this method is called after you touch a selected cell(deselect). If tableView.isEditing == true, this method has same behaviors with edit version of these two properties: allowsSelectionDuringEditing and allowsMultipleSelectionDuringEditing.

    Declaration

    Swift

    override open func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
  • Responds to KVO event.

    Declaration

    Swift

    override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
  • Configure popover presentation. Return .none to prevent fullScreen in popover

    Declaration

    Swift

    public func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle
  • Download a group of new files in predefined sort mode(downloadManager.sortType != .manual).

    Precondition

    displayContent == .downloadList && downloadManager.sortType != .manual.

    Declaration

    Swift

    public func downloadFiles(atURLStrings URLStrings: [String])

    Parameters

    URLStrings

    The String array of download URL. Repeated or invalid URL will be filtered. It’s your responsibility to encode URL string if it contains Non-ASCII charater. Use addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) or computed property percentEncodingURLQueryString in the extension to encode string.

  • Download a group of new files in manual mode and insert in the download list at the section which you specify.

    Precondition

    displayContent == .downloadList && downloadManager.sortType == .manual.

    Declaration

    Swift

    public func downloadFiles(atURLStrings URLStrings: [String], inManualModeAtSection section: Int, sectionTitle: String)

    Parameters

    URLStrings

    The String array of download URL. Repeated or invalid URL will be filtered.

    section

    Section location in the download list. If index is beyond bounds, nothing happen.

    sectionTitle

    Title for section header view.

  • Download several groups of new files in manual mode and insert in the download list at the section which you specify.

    Precondition

    displayContent == .downloadList && downloadManager.sortType == .manual.

    Declaration

    Swift

    public func downloadFilesList(_ URLStringsList: [[String]], inManualModeAtSection section: Int, sectionTitles: [String])

    Parameters

    URLStringsList

    A two-dimensional array of download URL string. Repeated or invalid URL will be filtered.

    section

    Section location in the download list. If index is beyond bounds, nothing happen.

    sectionTitles

    Titles for section header view. Its count must be equal to count of parameter URLStringsList, otherwise nothing happen. Tips: There is no header view in UITableView if its section title is empty string.

  • Download a group of new files in manual mode and insert in the download list at the location which you specify.

    Precondition

    displayContent == .downloadList && downloadManager.sortType == .manual.

    Declaration

    Swift

    public func downloadFiles(atURLStrings URLStrings: [String], inManualModeAt indexPath: IndexPath)

    Parameters

    URLStrings

    The String array of download URL. Repeated or invalid URL will be filtered.

    indexPath

    Insert location in the download list. If it’s beyond the bounds, nothing happen.