0

There are no compile errors and runs fine in simulator, but every view that contains this specific @ObservedObject, the preview crashes.

AzureAccount.swift

import Foundation
import MSAL

class AzureAccount: ObservableObject {
    @Published var account: MSALAccount? = nil
}

The azureAccount is instantiated in the AccountTypeSelectionView. The preview works fine on this view:

import SwiftUI
import MSAL

struct AccountTypeSelectionView: View {
    @StateObject var azureAccount = AzureAccount()
    @State private var showTeacherHome = false

// some login processes

    .navigationDestination(isPresented: $showTeacherHome, destination: {
        TeacherHomeView(azureAccount: azureAccount)
    })
}

struct AccountTypeSelectionView_Previews: PreviewProvider {
    static var previews: some View {
        AccountTypeSelectionView()
    }
}

TeacherHomeView.swift

import SwiftUI
import MSAL

struct TeacherHomeView: View {
    
    @State var selection = "roster"

    @ObservedObject var azureAccount: AzureAccount
    
    var body: some View {
        TabView(selection: $selection) {
            TeacherClassView(azureAccount: azureAccount)
                .tabItem {
                    Label("Students", systemImage: "person.3.fill")
                }
                .tag("roster")
            TeacherToolkitView()
                .tabItem {
                    Label("Toolkit", systemImage: "briefcase.fill")
                }
                .tag("toolkit")
        }
        .navigationTitle(selection == "roster" ? "Roster" : "Toolkit")
        .toolbar(.hidden)
    }
}

struct TeacherHomeView_Previews: PreviewProvider {
    static var previews: some View {
        TeacherHomeView(azureAccount: AzureAccount())
    }
}

Updated Edit: Using environmentObjects, the preview now appears with a red X and message "Preview Crashed". App still functions correctly in simulator.

ClassMateApp.swift

@main
struct ClassMateApp: App {
    @StateObject var azureAccount = AzureAccount()
    var body: some Scene {
        WindowGroup {
            AccountTypeSelectionView()
                .environmentObject(azureAccount)
}

TeacherHomeView:

struct TeacherHomeView: View {
    @EnvironmentObject var azureAccount: AzureAccount
    var body: some View {
        // unchanged
    }
}
struct TeacherHomeView_Previews: PreviewProvider {
    static var previews: some View {
        TeacherHomeView()
            .environmentObject(AzureAccount())
    }
}
wuwut
  • 33
  • 4

1 Answers1

0

You need a singleton of your store object to use for previewing, e.g.

struct TeacherHomeView_Previews: PreviewProvider {
    static var previews: some View {
        TeacherHomeView(azureAccount: AzureAccount.preview)
    }
}
class AzureAccount: ObservableObject {
    static var preview = AzureAccount(preview: true)

Note usually the store object is an .environmentObject so you don't need to pass it down through every View that might not need it, e.g.

struct TeacherHomeView_Previews: PreviewProvider {
    static var previews: some View {
        TeacherHomeView()
            .environmentObject(ModelStore.preview)
    }
}
malhal
  • 26,330
  • 7
  • 115
  • 133
  • Thanks for the reply. You're right, I should hav been using .environmentObject for this. I edited the question with my updated code, but preview is still crashing. Not crashing outright with a crash log anymore, but now just displaying a red X and "Preview Crashed" message. – wuwut Apr 13 '23 at 11:25