I'm trying to write an iOS app with swiftui that uses amplify and aws cognito to sign users up and navigate to the home/session screen after the user has signed up with a username/password/phone/email and confirmed a code with an email. I'm currently having a problem where after signing up the user, my iOS app navigates back to the login screen as it can't detect that there is a current user using the Amplify.Auth.getCurrentUser() function call. Here is the code that contains this logic:
//
// TheClubMobileApp.swift
// TheClubMobile
//
// Created by Hari S on 12/27/20.
//
import SwiftUI
import Amplify
import AmplifyPlugins
@main
struct TheClubMobileApp: App {
@ObservedObject var sessionManager = SessionManager()
init(){
configureAmplify()
sessionManager.getCurrentAuthUser()
}
var body: some Scene {
WindowGroup {
switch sessionManager.authState {
case .login:
LoginView()
.environmentObject(sessionManager)
case .signUp:
SignUpView()
.environmentObject(sessionManager)
case .confirmCode(let username):
ConfirmationView(username: username)
.environmentObject(sessionManager)
case .session(let user ):
SessionView(user: user)
.environmentObject(sessionManager)
}
}
}
func configureAmplify(){
do{
try Amplify.add(plugin: AWSCognitoAuthPlugin())
try Amplify.configure()
print("Amplify configured successfully")
} catch {
print("failed to configure Amplify ")
}
}
}
import Amplify
enum AuthState {
case signUp
case login
case confirmCode(username: String)
case session(user: AuthUser)
}
final class SessionManager: ObservableObject {
@Published var authState: AuthState = .login
func getCurrentAuthUser() {
if let user = Amplify.Auth.getCurrentUser() {
authState = .session(user: user)
} else {
authState = .login
}
}
func showSignUp() {
authState = .signUp
}
func showLogin() {
authState = .login
}
func signUp(username: String, email: String, phoneNumber: String, password: String){
let attributes = [AuthUserAttribute(.email, value: email), AuthUserAttribute(.phoneNumber, value: phoneNumber)]
let options = AuthSignUpRequest.Options(userAttributes: attributes)
_ = Amplify.Auth.signUp(
username: username,
password: password,
options: options
) { [weak self] result in
switch result {
case .success(let signUpResult):
print("Sign up result: ", signUpResult)
switch signUpResult.nextStep {
case .done:
print("Finished Sign Up")
case .confirmUser(let details, _):
print(details ?? "no details")
DispatchQueue.main.async {
self?.authState = .confirmCode(username: username)
}
}
case .failure(let error):
print("Sign up error: ", error)
}
}
}
func confirm(username: String, code: String){
_ = Amplify.Auth.confirmSignUp(
for: username,
confirmationCode: code
) { [weak self] result in
switch result {
case .success(let confirmResult):
print(confirmResult)
if confirmResult.isSignupComplete {
DispatchQueue.main.async {
self?.getCurrentAuthUser()
}
}
case .failure(let error):
print("failed to confirm code: ", error)
}
}
}
func login(username: String, password: String) {
_ = Amplify.Auth.signIn(
username: username,
password: password
) { [weak self] result in
switch result {
case .success(let signInResult):
print(signInResult)
if signInResult.isSignedIn {
DispatchQueue.main.async {
self?.getCurrentAuthUser()
}
}
case .failure(let error):
print("Login error: ", error)
}
}
}
func signOut() {
_ = Amplify.Auth.signOut(
) { [weak self] result in
switch result {
case .success:
DispatchQueue.main.async {
self?.getCurrentAuthUser()
}
case .failure(let error):
print("Login error: ", error)
}
}
}
}
After the user successfully confirms with a code with the func confirm, I expect the iOS app to navigate to the session view using the getCurrentAuthUser() as there should be a new user. However, it goes into the else case and displays my login view. It works correctly on the backend as I can see the user being signed up and I can login with the same credentials and then navigate to the session view but I can't seem to figure out how to navigate to the session view right after signing up. Any help would be appreciated. Thanks!