I have a loop in my app that can take a few seconds to process.
I want the screen to dismiss immediately while the loop runs in the background.
Is this possible?
I've tried adding only the loop:
DispatchQueue.main.async {
for _ in 1...self.numberOfTransactionsToAdd {
let newTransaction = Transaction()
var timeAdded = 1.months
newTransaction.transactionAmount = self.amountTextField.text!.toDouble()
newTransaction.transactionDescription = self.descriptionTextField.text
newTransaction.transactionDate = self.datePicked
newTransaction.transactionCategory = self.categoryPicked
newTransaction.repeatInterval = self.repeatInterval
newTransaction.transactionSubCategory = self.subcategoryPicked
newTransaction.subCategoryName = self.subcategoryPicked!.subCategoryName
try! self.realm.write {
self.realm.add(newTransaction)
}
self.datePicked = self.datePicked + timeAdded
}
}
}
I've tried adding the whole function:
@IBAction func doneButtonPressed(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
DispatchQueue.main.async {
self.saveTransaction()
}
}
But the screen still hangs before the view is dismissed.
This is my first time using DispatchQueue. I've read Apple's documentation on it, but it is extremely vague.
Is this even the right way to go about this?
Can someone help guide a newbie to the correct way to do this?
The problem is the asynchronous call to the the main queue itself for the non-ui work(background work). Replace
DispatchQueue.main.async
withDispatchQueue.global().async
. The reason being all the non-ui tasks should run asynchronously off the main queue.After doing the above fix, you will still have another issue which will be accessing the UI elements from the non-main queue(as now our code will be running on global queue). The reason being you will be fetching the UI elements data(like amountTextField's text etc) from the global queue. Store the UI's data in local variable and use the local variables in your loop code instead of calling amountTextField and other textfields as well.