ios – How to reload a view in swiftUI


I’m working on an auto login feature where upon the app opening, a cloudkit query is ran to determine if this device has known user info or not and that info is loaded to my Model class.

Here is the code:

Vino App

struct vinoApp: App {
//    @StateObject private var dataController = DataController()
    @ObservedObject var model = Model()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear(perform: {
                    Task {
                        do{
                            try await loadActiveUser()
                        }
                        catch {
                            print("Error: \(error)")
                        }
                    }
                })
        }
    }
    
    private func loadActiveUser() async throws {
        let record = try await queryUserRecord()
        if record != [] {
            //this line works
            model.activeUser = try await UserObj(ckrecord: record[0])
            model.userDoesntExist = false
        }
        else { model.activeUser = UserObj() }
    }
    
    /**
     Queries Account Info from private 'AccountInformation' Record Zone
     
     What does this mean?: Passing argument of non-sendable type 'NSPredicate' outside of main actor-isolated context may introduce data races
     */
    private func queryUserRecord() async throws -> [CKRecord] {
        let cloudDB = CKContainer.default().publicCloudDatabase
        let device = UIDevice.current.identifierForVendor
        
        //set pred
        let pred = NSPredicate(format: "LastKnownDevice == %@", device!.uuidString)
        print(device!.uuidString)
        let query = CKQuery(recordType: "AccountInfo", predicate: pred)
        //query public record
        let (userResults, _) = try await cloudDB.records(matching: query)
        //return the public CKRecord of the user
        return userResults.compactMap { _, result in
            guard let record = try? result.get() else { return nil }
            return record
        }
    }
}

Content View

struct ContentView: View {
    //State vars
    @ObservedObject var model = Model()
    
    var body: some View {
        VinoMainView()
        /**
         when app is opened we must evaluate if a user exists
         if user exists : model.userDoesntExits = false
         else : model.userDoesntExits = true
         */
            .fullScreenCover(isPresented: $model.userDoesntExist, content: {
                NavigationStack {
                    ZStack {
                        LoginForm()
                        NavigationLink(
                            "Dont Have an Account? Sign-Up Here",
                            destination: SignUpView(
                                userNotSignedin: $model.userDoesntExist
                            )
                        )
                            .font(.custom("DMSerifDisplay-Regular", size: 15))
                            .padding([.top], 300)
                        //Add loading view here?
                    }
                }
            })
        }
    /**
     check if user exists in privateDB zone
     -also sets active user to the user found
     */
    func checkIfUserDoesntExists() -> Bool {
        //if the array of CKRecords returned by 'queryUserRecords()' is not empty -> userDoesntExist = false
        if model.activeUser.isEmpty() {
            //create UserObj from record[0] because the private account zone queried from should only have one record
            //MARK: need to reload views
            return true
        }
        else { return false }
    }
}

Model

class Model: ObservableObject {
    @Published var activeUser = UserObj()
    @Published var userDoesntExist = true
}

I know the actual query is working because when I debug it I can see the results like so in the deugger:
CKRecord in Debugger

And I can see that model.userDoesntExist gets changed as well, like so:
model values

Even though I can see the code is working for the most part the fullScreenCover in ContentView is still displayed so I’m wondering how to refresh the ContentView to make the full screen cover go away once model.userDoesntExist is set to false.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img