JFortYork
JFortYork

Reputation: 145

SwiftUI Error Regarding Publishing Changes from Background Thread

I am not quite sure how to fix an error that appears three times in my View Model:

import SwiftUI

class GHViewModel: ObservableObject {
    
    let columns: [GridItem] = [
        GridItem(.flexible()),
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    
    @Published var followers: [Follower] = []
    @Published var page = 1
    @Published var user: User = PlaceholderData.user
    @Published var networkError: GFError = .invalidURL
    @Published var shouldShowNetworkError = false
    @Published var shouldShowFollowerDetails = false
    
    func getFollowers(userID: String) {
        NetworkManager.shared.getFollowers(for: userID, page: self.page) { result in
            switch result {
            case .success(let followers):
                if !followers.isEmpty {
                    self.followers += followers
                    print("**** GHViewModel -> FollowersScreen has retrieved the followers.  I see \(self.followers.count) followers for this user.")
                }
            case .failure(let error):
                self.shouldShowNetworkError = true
                self.networkError = error
            }
        }
    }
    
    func getFollowerDetails(userID: String) {
        NetworkManager.shared.getUserInfo(for: userID) { result in
            switch result {
            case .success(let ghUser):
                self.user = ghUser
                self.shouldShowFollowerDetails = true
            case .failure(let error):
                self.shouldShowNetworkError = true
                self.networkError = error
            }
        }
    }
}

The 3 warnings are happening at:

@Published var followers: [Follower] = []

and..

case .success(let ghUser):
  self.user = ghUser
  self.shouldShowFollowerDetails = true

What is this error actually saying? I suppose it's suggesting that I should be using

DispatchQueue.main.async { // code here }

around the code that's generating the warnings?

Please advise?

Upvotes: 0

Views: 109

Answers (1)

Yrb
Yrb

Reputation: 9775

Yes, it is telling your to use DispatchQueue.main.async. Remember, network calls are asynchoronous. You don't know when you are getting a response, so they are automatically performed on a background thread, but you always need to update your data that is being displayed on your main thread. Therefore, every time you hit .success, you need to update the variables on the main thread by enclosing the updates in DispatchQueue.main.async.

        case .success(let followers):
            if !followers.isEmpty {
                DispatchQueue.main.async {
                    self.followers += followers
                    print("**** GHViewModel -> FollowersScreen has retrieved the followers.  I see \(self.followers.count) followers for this user.")
                }
            }

and

case .success(let ghUser):
  DispatchQueue.main.async {
      self.user = ghUser
      self.shouldShowFollowerDetails = true
  }

I suspect the @Published error will go away as I suspect that is thrown due to the other issues.

Upvotes: 2

Related Questions