The first thing that comes to mind would be using a notification.
func downloadFiles(remoteFolder rf:String, localFolder lf:String, completion: @escaping (_ success:Bool, _ err: String) -> Void) {
DispatchQueue.global(qos:.background).async {
let fileName:String = (use whatever setter you have from your loop)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateDownloadFileName", object: nil, userInfo: ["fileName":fileName]))
...
DispatchQueue.main.async {
completion(successBool, errorMsg)
}
}
}
In your ViewController:
let myLabel = NSTextField(labelWithString: "")
override func viewDidLoad() {
setupNotificationCenter()
}
func updateDownloadFileName(notification: Notification) {
if let data = notification.userInfo as? [String:String] {
if let string = data["fileName"] {
myDownloadLabel.stringValue = string
}
}
}
func setupNotificationCenter() {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "updateDownloadFileName"), object: nil, queue: nil, using: updateDownloadFileName)
}
If you don't want to use Notifications then you could pass the Label to the method and update the stringValue through a dispatch to the main thread:
func downloadFiles(remoteFolder rf:String, localFolder lf:String, myLabel:NSTextField, completion: @escaping (_ success:Bool, _ err: String) -> Void) {
DispatchQueue.global(qos:.background).async {
let fileName:String = (use whatever setter you have from your loop)
DispatchQueue.main.async {
myLabel.stringValue = fileName
}
...
DispatchQueue.main.async {
completion(successBool, errorMsg)
}
}
}