SwiftUI: Check user authentication upon launch

1.2k views Asked by At

I am curious as how to check for user authentication upon launch of my app. In my app delegate I am doing the following. The loggedIn variable is going to be set based on if the user is currently signed in with "Sign In With Apple" button

extension UIApplication {
    func switchHostingController() {
        var loggedIn = false
        let provider = ASAuthorizationAppleIDProvider()
        let userID = UserDefaults.standard.object(forKey: "userID") as? String
        provider.getCredentialState(forUserID: userID!) { state, error in
          switch state {
          case .authorized:
            // Credentials are valid.
            loggedIn = true
            break
          case .revoked:
            // Credential revoked, log them out
            loggedIn = false
            break
          case .notFound:
            // Credentials not found, show login UI
            loggedIn = false
            break
          case .transferred:
            loggedIn = false
          @unknown default:
            loggedIn = false
          }
        }
        if (loggedIn == false)
        {
            let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            window?.rootViewController = UIHostingController(rootView: ContentView())
        } else {
            let main = Main()
            let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
            window?.rootViewController = UIHostingController(rootView: main)
        }
    }
}

For some reason the above loggedIn var always returns false. I know it has something to do with forUserID: userID! not returning anything. But it works in others views...

1

There are 1 answers

0
Papi On

Solved it by making a function to check if authentication is made. If so, set bool to true. Then check bool to display the correct view. Also had to make a dispatch group so that the provider method can finish before returning the value.

struct MeusicApp: App {
    func checkit() -> Bool {
        let group = DispatchGroup()
            group.enter()
        let userID = UserDefaults.standard.object(forKey: "userID") as? String
        let provider = ASAuthorizationAppleIDProvider()
        var stateBool = false
        provider.getCredentialState(forUserID: userID ?? "") { [self] state, error in
          switch state {
          case .authorized:
            // Credentials are valid.
            stateBool = true
            group.leave()
            break
          case .revoked:
            // Credential revoked, log them out
            stateBool = false
            group.leave()
            break
          case .notFound:
            // Credentials not found, show login UI
            stateBool = false
            group.leave()
            break
          case .transferred:
            print("Transferred")
          @unknown default:
            stateBool = false
            group.leave()
          }
        }
        group.wait()
        return stateBool
    }
    var body: some Scene {
        WindowGroup {
            if checkit() {
                Main()
            } else {
                ContentView()
            }
        }
    }
}