Search code examples
iosswiftalamofireprogressuiprogressview

How to update a progress view that is on another UIViewController - SWIFT?


I have a UITableViewController that is embedded in a UINavigationController. When I click on a row I am attempting to upload a file. To show the progress of this upload I have decided to use custom popup (another UIViewController) - if anyone has a better idea to show the progress of the upload in this context I am open to it.

The only idea I have to transfer continuous data from one UIViewController to another (if that is possible) is by using a Singleton. My code is below, my issue at the moment is I do not know how to update the progress view even though now it has access to the progress data via the singleton.

class SharedSingleton{

     private init(){}
     static let shared = SharedSingleton()
     var prog: Float = 0
}   

UITableViewController:

Using Alamofire to get the fraction of upload completed:

 /**TRACK PROGRESS OF UPLOAD**/
 upload.uploadProgress { progress in
 //print(progress.fractionCompleted)

 let mySingleton = SharedSingleton.shared
 mySingleton.prog = Float(progress.fractionCompleted)
 print("mySingleton.prog: \(mySingleton.prog)")

UIViewController containing popup:

@IBOutlet weak var popUpContainer: UIView!
@IBOutlet weak var uploadStatus: UILabel!
@IBOutlet weak var progressBar: UIProgressView!


override func viewDidLoad() {
    super.viewDidLoad()

    // Make popup have rounded corners
    popUpContainer.layer.cornerRadius = 5
    popUpContainer.layer.masksToBounds = true


    // Call Singleton and assign progress of upload to progress view
    // HOW TO UPDATE ??????
    let mySingleton = SharedSingleton.shared
    progressBar.progress = mySingleton.prog

}

enter image description here


Solution

  • One option would be to use NotificationCenter and in your pop-up view controller subscribe to notifications and in your API callback for the progress, publish a notification.

    For example:

    UploadNotifications.swift:

    import Foundation
    
    extension Notification.Name {
        static let UploadProgress = Notification.Name("UploadProgress")
    }
    

    UploadProgressViewController.swift (your pop-up):

    import UIKit
    
    class UploadProgressViewController: UIViewController {
    
        @IBOutlet weak var progressBar: UIProgressView!
    
        private let progress: Progress = {
            let progress = Progress()
            progress.completedUnitCount = 0
            progress.totalUnitCount = 100
            return progress
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
        }
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
    
            NotificationCenter.default.addObserver(self, selector: #selector(self.uploadDidProgress(_:)), name: .UploadProgress, object: nil)
        }
    
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
        }
    
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            NotificationCenter.default.removeObserver(self)
        }
    
        @objc private func uploadDidProgress(_ notification: Notification) {
            if let progress = notification.object as? Int64 {
                self.progress.completedUnitCount = progress
                if progress == 100 {
                    // dismiss/exit
                }
            }
        }
    
    }
    

    Then in your method with the upload progress callback:

    upload.uploadProgress { progress in
        NotificationCenter.default.post(name: .SyncDidProgress, object: Int64(progress))
    }