Home > Enterprise >  Save onboarding in storage using Swift
Save onboarding in storage using Swift

Time:10-31

So I need to utilize app storage to save the state of onboarding, but I can't seem to figure it out with a @Published variable which I have, so I wanted to reach out and see if anyone know what I can do to switch things up.

So here is the code:

class MainViewModel: ObservableObject {
    @Published var showOnboarding = true
}

@main
struct MapGlider: App {
    @StateObject private var model = MainViewModel()
    var body: some Scene {
        WindowGroup {
            MainScreenContainer(
                model: model,
                showOnboarding: $model.showOnboarding
            )
        }
    }
}

struct MainScreenContainer: View {
    @ObservedObject var model: MainViewModel
    @Binding var showOnboarding: Bool
    var body: some View {
        if showOnboarding {
            OnboardingView(
                model: model,
                showOnboarding: $model.showOnboarding
            )
        } else {
            MainView(model: model)
        }
    }
}

struct OnboardingView: View {
    @Binding var showOnboarding: Bool
    var body: some View {
        NavigationStack {
            ZStack(alignment: .top) {
                VStack {
                    LazyVGrid(columns: [GridItem(), GridItem(), GridItem(alignment: .topTrailing)], content: {
                        Button(action: {
                            showOnboarding = false
                        }, label: {
                            Image(systemName: "xmark")
                        })
                    })
                }
            }
        }
    }
}

I want to be able to click on the button inside OnboardingView and then set the app storage of showOnboarding to false, so next time the app runs, it can check MainScreenContainer and go directly to MainView if the storage is set to false.

CodePudding user response:

In your use case i would actually use @AppStorage property wrapper link which is a wrapper over UserDefaults, and i would get rid of that ViewModel. The code would look something like this:

struct MainScreenContainer: View {
    @AppStorage("show_onboarding") var showOnboarding: Bool = false
    var body: some View {
        if showOnboarding {
            OnboardingView(
                model: model
            )
        } else {
            MainView(model: model)
        }
    }
}

struct OnboardingView: View {
    @AppStorage("show_onboarding") var showOnboarding: Bool = false
    var body: some View {
        NavigationStack {
            ZStack(alignment: .top) {
                VStack {
                    LazyVGrid(columns: [GridItem(), GridItem(), GridItem(alignment: .topTrailing)], content: {
                        Button(action: {
                            showOnboarding = false
                        }, label: {
                            Image(systemName: "xmark")
                        })
                    })
                }
            }
        }
    }
}
  • Related