0
votes

I run the code, then get this Error message: Fatal error: Unexpectedly found nil while unwrapping an Optional value

  1. AppData file
struct Shortcut {
    var title: String
    var option: String
}

struct ShortcutViewModel: Identifiable {
    var id = UUID()
    var shortcut: Shortcut
    
    var title: String {
        return shortcut.title.capitalized
    }
    
    var option: String {
        return shortcut.option
    }
}

class AppData: ObservableObject {
    @Published var userData: [ShortcutViewModel]
    
    @Published var showTitle: String {
        didSet {
            UserDefaults.standard.set(showTitle, forKey: "TitleInput")
        }
    }
    
    @Published var showOption: String {
        didSet {
            UserDefaults.standard.set(showOption, forKey: "OptionInput")
        }
    }
    
    init() {
        userData = [
            ShortcutViewModel(shortcut: Shortcut(title: "What for Dinner?", option: "Chinese")),
            ShortcutViewModel(shortcut: Shortcut(title: "What for Lunch?", option: "Pasta")),
            ShortcutViewModel(shortcut: Shortcut(title: "What for Breakfast?", option: "Toast"))
        ]
        self.showTitle = UserDefaults.standard.string(forKey: "TitleInput")!   // *here I get Fatal Error msg*
        self.showOption = UserDefaults.standard.string(forKey: "OptionInput")!
    }
}
  1. ContentView file
struct ContentView: View {
    // MARK: - PROPERTY
    let createpage = CreateView()
    // MARK: - BODY
    var body: some View {
        ZStack {
            VStack {
                NavigationBarView()
                NavigationView{
                    ScrollView{
                        HStack {
                            NavigationLink("+ create a shortcut", destination: CreateView())
                                .font(.title3)
                                .foregroundColor(.blue)
                                .padding()
                                .frame(width: 200, height: 60)
                                .background(
                                RoundedRectangle(cornerRadius: 10,
                                                 style: .continuous)
                                    .fill(
                                        Color(red:0.2, green: 0.45, blue: 1.0, opacity: 0.3)))
                                    
                            Spacer()
                        } //: HStack - link to create page
                        //.frame(minWidth: 0, maxWidth: .infinity, maxHeight: 120)
                        .padding()
                    } //: ScrollView
                    
                    .navigationTitle("All Shortcuts")
                    
                } //: NavigationView
            
            } //: VStack
            .ignoresSafeArea(.all, edges: .all)
        } //: ZStack
        .ignoresSafeArea(.all, edges: .top)
    } //: var Body
}



// MARK: - PREVIEW
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(text: .constant(""))
        
    }
}
  1. CreateView
struct CreateView: View {
    // MARK: - PROPERTY
    @Environment(\.presentationMode) var presentationMode
    @EnvironmentObject var appData: AppData
    @State var titleInput2 = ""
    @State var optionInput2 = ""
    
    // MARK: - BODY
    var body: some View {
        ZStack {
            VStack {
                NavigationView{
                    ScrollView{
                        HStack {
                            TextField("what is the title?", text: $titleInput2)
                                .font(.title2)
                                .foregroundColor(.white)
                                .padding()
                                .frame(width: 320, height: 80)
                                .background(
                                    RoundedRectangle(
                                        cornerRadius: 20,
                                        style: .continuous)
                                        .fill(
                                            Color(red:0.2, green: 0.45, blue: 1.0, opacity: 0.3)))
                                .padding()
                        } //: HStack - Textfield - title
                        .padding()
                        
                        HStack (spacing: 10) {
                            TextField("options", text: $optionInput2)
                                .font(.body)
                                .foregroundColor(.white)
                                .padding()
                                .frame(width: 120, height: 60, alignment: .leading)
                                .background(
                                    RoundedRectangle(
                                        cornerRadius: 10,
                                        style: .continuous)
                                        .fill(
                                            Color(red: 1.0, green: 0.2, blue: 0.2, opacity: 0.3)))
                                .padding()
                        } //: HStack - Textfield - option
                        .padding()
                        
                        Button(action: {
                            self.appData.showTitle = titleInput2 
                            self.appData.showOption = optionInput2
                            presentationMode.wrappedValue.dismiss()
                        }, label: {
                            Text("Save")
                                .padding()
                                .background(
                                    Circle()
                                        .fill(
                                            Color(red: 0.25, green: 0.1, blue: 0.6, opacity: 0.25))
                                        .frame(width: 120, height: 120))
                                
                        }) //: Button - save
                        .padding(.top, 150)
                    } //: Scroll View
                    .navigationTitle("Create a Shortcut")
                }//: Navigation View
            } //: VStack
            .ignoresSafeArea(.all, edges: .all)
        } //: ZStack
        .ignoresSafeArea(.all, edges: .all)
    } //: Body
}

struct CreateView_Previews: PreviewProvider {
    static var previews: some View {
        CreateView().environmentObject(AppData())
    }
}
  1. App file
@main  // *here I get Fatal Error msg*
struct WFT_demo2App: App {
    var body: some Scene {
        WindowGroup {    // *here I get Fatal Error msg*
            ContentView(text: .constant(""))
                .environmentObject(AppData())    // *here I get Fatal Error msg*
        }
    }
}

When I run the code (when I simulate it), I get the same fatal error msgs in several lines where I marked above.. I think I'm missing something big. Also, in 3. CreateView file, is it okay to use @State var titleInput2 = "" and @State var optionInput2 = "" ? Thank you for your advice!

2

2 Answers

0
votes

If you're going to be passing your data through environmentObject then you need to receive the data on your page. You're sending it but not receiving it. If you want to receive it then add this above your body in your views.

@EnvironmentObject var appData: AppData

Also you're using NavigationView wrong, there should only be one NavBar so delete those other navbars and use this code for your App.swift

 @main  // *here I get Fatal Error msg*
struct WFT_demo2App: App {
    var body: some Scene {
        WindowGroup {    // *here I get Fatal Error msg*
         NavigationView {
            ContentView(text: .constant(""))
         }
                .environmentObject(AppData())    // *here I get Fatal Error msg*
        }
    }
}

Again: Delete every other nav bar except for the one in this code snippet. And you have to pass the data once with this method. But note you will still have to declare `@EnvironmentObject var appData: AppData on every view that depends on its data

0
votes

Remove the following line, it is not a place a view to be created and it is the place where you created it w/o injecting environment object:

struct ContentView: View {
    // MARK: - PROPERTY
    let createpage = CreateView()    // << this one !!

...