Обновить индикатор загрузки в ячейках таблицы - PullRequest
0 голосов
/ 16 апреля 2020

У меня FirstTableViewContoller с несколькими ячейками. Если я нажму на ячейку, я go до SecondTableViewContoller с индикатором загрузки внутри ячеек. Когда я нажимаю на ячейку в SecondTableViewContoller, мой индикатор запускается.

Также у меня есть класс DownloadManager, который я могу начать загружать в firstTable в SecondTableViewContoller go до FirstTableViewContoller, нажмите на вторую ячейку и от go до SecondTableViewContoller с secondTable. Тем самым я скачиваю файлы в два tableViews.

Мой DownloadManager класс работает нормально. И скачивание файлов. Но мои показатели прогресса иногда работают некорректно. Например, я начинаю скачивать файлы и go в другое приложение (Instagram, Facebook и др. c). После этого я возвращаюсь в своем приложении. Но мой прогресс ViewView не отображается (кроме загрузки файлов в это время). Когда я прячу и снова открываю свое приложение несколько раз, мои индикаторы отображаются и работают нормально. Пожалуйста, помогите мне исправить мои показатели. Я не понимаю, почему это происходит ...

SecondTableViewContoller

enum DownloadStatus {
    case none
    case inProgress
    case completed
    case failed
}

struct item {
    var title : String!
    let link = ""
    var downloadStatus : DownloadStatus = .none

    init(title: String) {
        self.title = title
    }
}

var downloadQ = [Int: [Int]]()

class SecondTableViewContoller: UITableViewController {

typealias ProgressHandler = (Int, Float) -> ()
    var objects = [Any]()
    var items = [item]()
    var tableId = 0
    var onProgress : ProgressHandler?

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: String(format: "cell", indexPath.row), for: indexPath) as! SecondViewCell

        let cellFilePath = "\(indexPath.row).mp3"
        let indexOfTask = allDownloadTasks.index { (task:URLSessionDownloadTask) -> Bool in
            return task.currentRequest?.url?.lastPathComponent == cellFilePath
        }

        if indexOfTask == nil {
            (cell.accessoryView as! FFCircularProgressView?)?.stopSpinProgressBackgroundLayer()
            (cell.accessoryView as! FFCircularProgressView?)?.circularState = .completed
        }

        let item = items[indexPath.row]
        cell.firstTextLabel.text = array[indexPath.row]
        cell.secondTextLabel.text = item.title

        let progressRing = FFCircularProgressView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(24), height: CGFloat(24)))

        if item.downloadStatus == .completed {
            cell.tag = indexPath.row
            cell.accessoryView = progressRing
            progressRing.stopSpinProgressBackgroundLayer()

            if let idx = downloadQ[self.buttonIndex]?.index(of: cell.tag) {
                downloadQ[self.buttonIndex]?.remove(at: idx)
            }
        } else {
            cell.accessoryView = nil
        }

        if let downloadQ = downloadQ[self.buttonIndex], downloadQ.contains(indexPath.row) {
            cell.accessoryView = progressRing
            progressRing.startSpinProgressBackgroundLayer()
         }

        return cell
    }

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    var item = self.items[indexPath.row]
    downloadQ[self.buttonIndex]?.append(indexPath.row)

    var theArray = downloadQ[self.buttonIndex] ?? [Int]()
    theArray.append(indexPath.row)
    downloadQ[self.buttonIndex] = theArray

    if downloadQ.isEmpty {
        print("The downloadQ dictionary is empty.")
    } else {
        print("The downloadQ dictionary is not empty.")
    }

    let url = URL(string: "link.mp3")!
    let downloadManager = DownloadManager()
    downloadManager.identifier = indexPath.row
    downloadManager.tableId = self.buttonIndex
    downloadManager.folderPath = "\(self.id)"
    let downloadTaskLocal =  downloadManager.activate().downloadTask(with: url)
    downloadTaskLocal.resume()

    let circularProgressViewForCell = FFCircularProgressView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(24), height: CGFloat(24)))
    let cell = tableView.cellForRow(at: indexPath)
    cell?.accessoryView = circularProgressViewForCell
    circularProgressViewForCell.startSpinProgressBackgroundLayer()

    downloadManager.onProgress = { (row, tableId, progress) in

        DispatchQueue.main.async {
            let appDelegate = UIApplication.shared.delegate as! AppDelegate

            if appDelegate.masterVC == nil {
                print("master vc is nil")
                return
            }

            if appDelegate.masterVC.tableId != tableId {
                print("different table is nil")
                return
            }

            let indexpath = IndexPath.init(row: row, section: 0)
            let cell = appDelegate.masterVC.tableView.cellForRow(at: indexpath)

            if progress <= 1.0 {

            let progressRing = FFCircularProgressView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(24), height: CGFloat(24)))
            cell?.accessoryView = progressRing
            progressRing.progress = CGFloat(progress)

            if progress == 1.0 {
                item.downloadStatus = .completed
                progressRing.circularState = .completed
            } else {
                item.downloadStatus = .inProgress

            }
         }
      }
   }
}

DownloadManager

extension URLSession {
    func getSessionDescription () -> Int {
        // row id
        return Int(self.sessionDescription!)!
    }

    func getDebugDescription () -> Int {
        // table id
        return Int(self.debugDescription)!
    }
}

class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate {



    static var shared = DownloadManager()
    var identifier : Int = -1
    var tableId : Int = -1
    var folderPath : String = ""
    typealias ProgressHandler = (Int, Int, Float) -> ()


    var onProgress : ProgressHandler? {
        didSet {
            if onProgress != nil {
                let _ = activate()
            }
        }
    }

    override init() {
        super.init()
    }

    func activate() -> URLSession {
        let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background.\(NSUUID.init())")

        let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
        urlSession.sessionDescription = String(identifier)
        urlSession.accessibilityHint = String(tableId)

        return urlSession
    }

    private func calculateProgress(session : URLSession, completionHandler : @escaping (Int, Int, Float) -> ()) {
        session.getTasksWithCompletionHandler { (tasks, uploads, downloads) in
            let progress = downloads.map({ (task) -> Float in
                if task.countOfBytesExpectedToReceive > 0 {
                    return Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive)
                } else {
                    return 0.0
                }
            })

            let stringNumb = (session.accessibilityHint ?? "hit")
            let someNumb = Int(stringNumb as String)

            let string1 = (session.sessionDescription ?? "hit")
            let some1 = Int(string1 as String)

            if let idx = downloadQ[someNumb!]?.index(of: some1!) {
                downloadQ[someNumb!]?.remove(at: idx)
                print("remove:\(downloadQ)")
            }

            completionHandler(session.getSessionDescription(), Int(session.accessibilityHint!)!, progress.reduce(0.0, +))
        }
    }

    func urlSession(_ session: URLSession,
                    downloadTask: URLSessionDownloadTask,
                    didFinishDownloadingTo location: URL){

        let stringNumb = (session.accessibilityHint ?? "hit")
        let someNumb = Int(stringNumb as String)

        let string1 = (session.sessionDescription ?? "hit")
        let some1 = Int(string1 as String)

        if let idx = downloadQ[someNumb!]?.index(of: some1!) {
            downloadQ[someNumb!]?.remove(at: idx)
            print("remove:\(downloadQ)")
        }

        let fileName = downloadTask.originalRequest?.url?.lastPathComponent
        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        var destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appending("/\(folderPath)"))


        do {
            try fileManager.createDirectory(at: destinationURLForFile, withIntermediateDirectories: true, attributes: nil)
            destinationURLForFile.appendPathComponent(String(describing: fileName!))
            try fileManager.moveItem(at: location, to: destinationURLForFile)
        }catch(let error){
            print(error)
        }



    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

        let stringNumb = (session.accessibilityHint ?? "hit")
        let someNumb = Int(stringNumb as String)

        let string1 = (session.sessionDescription ?? "hit")
        let some1 = Int(string1 as String)

        if let idx = downloadQ[someNumb!]?.index(of: some1!) {
            downloadQ[someNumb!]?.remove(at: idx)
            print("remove:\(downloadQ)")
        }

        if totalBytesExpectedToWrite > 0 {
            if let onProgress = onProgress {
                calculateProgress(session: session, completionHandler: onProgress)
            }
            let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)

        }
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {

        let stringNumb = (session.accessibilityHint ?? "hit")
        let someNumb = Int(stringNumb as String)

        let string1 = (session.sessionDescription ?? "hit")
        let some1 = Int(string1 as String)

        if let idx = downloadQ[someNumb!]?.index(of: some1!) {
            downloadQ[someNumb!]?.remove(at: idx)
            print("remove:\(downloadQ)")
        }

    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...