Sign in with Apple Keychain savedEmail Stored Incorrectly

Using personal physical iPhone for simulations. Can't get Keychain to read or store AppleID name/email. I want to avoid hard reseting physical phone.


Logs confirm Keychain is working, but userIdentifier and savedEmail are not being stored correctly.

🔄 Initializing UserManager... ✅ Saved testKeychain to Keychain: Test Value ✅ Retrieved testKeychain from Keychain: Test Value 🔍 Keychain Test - Retrieved Value: Test Value ⚠️ Keychain Retrieve Warning: No stored value found for userIdentifier ⚠️ Keychain Retrieve Warning: No stored value found for savedEmail 🔍 Debug - Retrieved from Keychain: userIdentifier=nil, savedEmail=nil ⚠️ No stored userIdentifier in Keychain. User needs to sign in. 📦 Converting User to CKRecord: Unknown, No Email ✅ User saved locally: Unknown, No Email ✅ User saved to CloudKit: Unknown, No Email


Below UserManager.swift if someone can help troubleshoot. Or step by step tutorial to configure a project and build a User Login & User Account creation for Apple Only app.

import Foundation
import CloudKit
import AuthenticationServices
import SwiftData

@MainActor
class UserManager: ObservableObject {
    @Published var user: User?
    @Published var isLoggedIn = false
    @Published var errorMessage: String?

    private let database = CKContainer.default().publicCloudDatabase

    init() {
        print("🔄 Initializing UserManager...")

        // 🔍 Keychain Debug Test
        let testKey = "testKeychain"
        KeychainHelper.shared.save("Test Value", forKey: testKey)
        let retrievedValue = KeychainHelper.shared.retrieve(forKey: testKey)
        
        print("🔍 Keychain Test - Retrieved Value: \(retrievedValue ?? "nil")")

        fetchUser() // Continue normal initialization
    }

    // ✅ Sign in & Save User
    func handleSignIn(_ authResults: ASAuthorization) {
        guard let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential else {
            errorMessage = "Error retrieving Apple credentials"
            print("❌ ASAuthorization Error: Invalid credentials received")
            return
        }

        let userIdentifier = appleIDCredential.user
        let fullName = appleIDCredential.fullName?.givenName ?? retrieveSavedName()
        var email = appleIDCredential.email ?? retrieveSavedEmail()

        print("🔍 Apple Sign-In Data: userIdentifier=\(userIdentifier), fullName=\(fullName), email=\(email)")

        // 🔄 If Apple doesn't return an email, check if it exists in Keychain
        if appleIDCredential.email == nil {
            print("⚠️ Apple Sign-In didn't return an email. Retrieving saved email from Keychain.")
        }

        // ✅ Store userIdentifier & email in Keychain
        KeychainHelper.shared.save(userIdentifier, forKey: "userIdentifier")
        KeychainHelper.shared.save(email, forKey: "savedEmail")

        let newUser = User(fullName: fullName, email: email, userIdentifier: userIdentifier)
        saveUserToCloudKit(newUser)
    }
    
    func saveUserToCloudKit(_ user: User) {
        let record = user.toRecord()

        Task {
            do {
                try await database.save(record)
                DispatchQueue.main.async {
                    self.user = user
                    self.isLoggedIn = true
                    self.saveUserLocally(user)
                    print("✅ User saved to CloudKit: \(user.fullName), \(user.email)")
                }
            } catch {
                DispatchQueue.main.async {
                    self.errorMessage = "Error saving user: \(error.localizedDescription)"
                    print("❌ CloudKit Save Error: \(error.localizedDescription)")
                }
            }
        }
    }

    // ✅ Fetch User from CloudKit
    func fetchUser() {
        let userIdentifier = KeychainHelper.shared.retrieve(forKey: "userIdentifier")
        let savedEmail = KeychainHelper.shared.retrieve(forKey: "savedEmail")

        print("🔍 Debug - Retrieved from Keychain: userIdentifier=\(userIdentifier ?? "nil"), savedEmail=\(savedEmail ?? "nil")")

        guard let userIdentifier = userIdentifier else {
            print("⚠️ No stored userIdentifier in Keychain. User needs to sign in.")
            return
        }

        let predicate = NSPredicate(format: "userIdentifier == %@", userIdentifier)
        let query = CKQuery(recordType: "User", predicate: predicate)

        Task { [weak self] in
            guard let self = self else { return }
            do {
                let results = try await self.database.records(matching: query, resultsLimit: 1).matchResults
                if let (_, result) = results.first {
                    switch result {
                    case .success(let record):
                        DispatchQueue.main.async {
                            let fetchedUser = User(record: record)
                            self.user = User(
                                fullName: fetchedUser.fullName,
                                email: savedEmail ?? fetchedUser.email,
                                userIdentifier: userIdentifier
                            )
                            self.isLoggedIn = true
                            self.saveUserLocally(self.user!)
                            print("✅ User loaded from CloudKit: \(fetchedUser.fullName), \(fetchedUser.email)")
                        }
                    case .failure(let error):
                        DispatchQueue.main.async {
                            print("❌ Error fetching user from CloudKit: \(error.localizedDescription)")
                        }
                    }
                }
            } catch {
                DispatchQueue.main.async {
                    print("❌ CloudKit fetch error: \(error.localizedDescription)")
                }
            }
        }
    }

    // ✅ Save User Locally
    private func saveUserLocally(_ user: User) {
        if let encoded = try? JSONEncoder().encode(user) {
            UserDefaults.standard.set(encoded, forKey: "savedUser")
            UserDefaults.standard.set(user.fullName, forKey: "savedFullName")
            UserDefaults.standard.set(user.email, forKey: "savedEmail")
            print("✅ User saved locally: \(user.fullName), \(user.email)")
        } else {
            print("❌ Local Save Error: Failed to encode user data")
        }
    }

    // ✅ Retrieve Previously Saved Name
    private func retrieveSavedName() -> String {
        return UserDefaults.standard.string(forKey: "savedFullName") ?? "Unknown"
    }

    // ✅ Retrieve Previously Saved Email
    private func retrieveSavedEmail() -> String {
        return KeychainHelper.shared.retrieve(forKey: "savedEmail") ?? UserDefaults.standard.string(forKey: "savedEmail") ?? "No Email"
    }

    // ✅ Sign Out
    func signOut() {
        isLoggedIn = false
        user = nil
        UserDefaults.standard.removeObject(forKey: "savedUser")
        print("🚪 Signed Out")
    }
}

Sign in with Apple Keychain savedEmail Stored Incorrectly
 
 
Q