To get my feet wet with SwiftUI app development I’m making a simple app with login functionality using the AppAuth library. I’ve got basic login and logout functionality working and can make a request using the received access token. During refactoring to cleanup my code I’ve encountered a purple warning saying:
Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
This is my simplified code:
@main
struct MyApp: App {
@ObservedObject var authStore = AuthStore()
var body: some Scene {
WindowGroup {
if authStore.isAuthenticated {
MainView().environmentObject(authStore)
} else {
LoginView()
}
}
}
}
class AuthStore: ObservableObject {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
private var authState : OIDAuthState?
@Published var isAuthenticated = false // <- Xcode gives the warning for this line.
func login() {
// Prepare the necessary data like the authorization URL, clientID, etc. necessary for authentication
self.appDelegate.currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, presenting: scene!.keyWindow!.rootViewController!) { authState, error in
if let authState = authState {
self.setAuthState(authState)
print("Got authorization tokens. Access token: " +
"(authState.lastTokenResponse?.accessToken ?? "nil")")
} else {
print("Authorization error: (error?.localizedDescription ?? "Unknown error")")
self.setAuthState(nil)
}
}
}
private func setAuthState(_ authState: OIDAuthState?) {
if (self.authState == authState) {
return;
}
self.authState = authState
self.isAuthenticated = authState?.isAuthorized == true
}
}
I’ve tried to annotate the AuthStore
class with @MainActor
, surround assigning a new value to the isAuthenticated
variable with DispatchQueue.main.async { }
and use .receive(on:)
in the MyApp
struct for the authStore.isAuthenticated
usage. No matter what I tried the warning persists.
How can I resolve this warning?