I am pretty new to SwiftUI and with DispatchGroups and DispatchQueues.
I would like to create a Button which processes some server requests and then use the returned data with a CoreML model to predict some score. Once, the score is predicted, then the app can navigate to the next screen
Here is the sequence of actions which need to be done before moving to the next screen
// exemple of sequence of actions
let group = DispatchGroup()
group.enter()
DispatchQueue.main.async {
self.name = self.names[self.selectedCompanyIndex]
self.fetchTweets(company: self.arobases[self.selectedCompanyIndex])
self.fetchTweets(company: self.hashes[self.selectedCompanyIndex])
group.leave()
}
group.notify(queue: .main) {
print("done")
}
//function for fetching tweets
func fetchTweets(company: String) {
swifter.searchTweet(
using: company,
lang: "en",
count: 100,
tweetMode: .extended,
success: { (results, metadata) in
var tweets = [TextClassifier1Input]()
for i in 0...99 {
if let tweet = results[i]["full_text"].string {
tweets.append(TextClassifier1Input(text: tweet))
}
}
let searchType = String(company.first!)
self.makePrediction(with: tweets, type: searchType)
}) { (error) in
print("There was an error with the Twitter API: --> ", error)
}
}
//function for making predictions via the coreML model
func makePrediction(with tweets: [TextClassifier1Input], type: String) {
do {
let predictions = try self.sentimentClassifier.predictions(inputs: tweets)
var sentimentScore = 0
for pred in predictions {
if pred.label == "pos" {
sentimentScore += 1
} else if pred.label == "neg" {
sentimentScore -= 1
} else {
print("something sent wrong: --> ", pred.label)
}
}
if type == "@" {
arobaseScore = sentimentScore
} else if type == "#" {
hashScore = sentimentScore
}
} catch {
print("There was an error with the ML model: --> ", error)
}
}
The problem is the navigation is executed on the button click whereas I want the previous actions to be done before.
Can anyone let me know how should I use DispatchGroups and DispatchQueue to run my code in the correct sequence
Thanks in advance for your help
2
Answers
welcome to Stack Overflow.
You are not waiting for swifter.searchTweet to complete before doing the update.
The first step is to add a completion handler to
fetchTweets
. The completion handler is a way of reporting whenfetchTweets
has finished the networking.After that is done, then you can enter and leave the group when the networking is done. The code in notify will then be called. It’s in that code block where you need to update the UI.
for those using programmatic navigation, trying to navigate before a call to the backend is done will cause all sorts of problems where the view wants to still stay until the call is over and your navigation logic wants to continue