Search code examples
swiftui

Getting The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions


I know this question has been asked many times and it boils down to make your code better, but i can not figure out where the issue is. I am hoping someone with more knowledge can help me out.

fineDine.swift

import SwiftUI
import SwiftData

@main
struct fineDineApp: App {
    var body: some Scene {
        WindowGroup {
            searchResults(searchValue: "")
                .modelContainer(for: Review.self)
        }
    }
}

searchresults.swift

import SwiftUI
import SwiftData

struct searchResults: View {
    @State private var isPresentingNewMealView = false
    @State var searchValue: String
    @Query var review: [Review]
    @Environment(\.modelContext) var modelContext
    
    var body: some View {  <---Where the error always pops up
        NavigationStack {
            ZStack {
                LinearGradient(gradient: Gradient(colors: [Color(red: 0.9725490196078431, green: 0.9607843137254902, blue: 0.8627450980392157, opacity: 1), Color(red: 0.9137254901960784, green: 0.9254901960784314, blue: 0.8509803921568627, opacity: 1), Color(red: 0.9882352941176471, green: 0.7529411764705882, blue: 0.13333333333333333, opacity: 1), Color(red: 0.9450980392156862, green: 0.47058823529411764, blue: 0.08627450980392157, opacity: 1)]), startPoint: .top, endPoint: .bottom).ignoresSafeArea()
                VStack{
                    Text("Which Food...")
                        .font(.system(size: 30, weight: .bold, design: .default))
                        .padding()
                    Image(systemName: "fork.knife.circle.fill")
                        .font(.system(size: 100))
                        .foregroundStyle(.black)
                    TextField("Enter Food or Restaurant", text: $searchValue)
                        .frame(width: 300, height: 50, alignment: .center)
                        .background(Color.white.opacity(0.4).cornerRadius(10))
                        .fontWeight(.medium)
                        .foregroundColor(Color.black)
                        .multilineTextAlignment(TextAlignment.center)
                    
                    Spacer()
                    
                    List {
                        
                        ForEach(review) { review in
                            NavigationLink(destination: IndividualItemView())
                            {
                                VStack(alignment: .leading)
                                {
                                    Text(review.foodName)
                                        .font(.headline)
                                }
                            }
                        }.listRowBackground(Color.white.opacity(0.4).cornerRadius(5))
                    }  .scrollContentBackground(.hidden)
                    
                    .toolbar {
                     Button(action: {isPresentingNewMealView = true}
                    ) {
                     Image(systemName: "plus")
                     }
                    
                    .sheet(isPresented: $isPresentingNewMealView) {
                         EditMealView(isPresentingNewMealView: $isPresentingNewMealView, mealImage: Image(""), review: Review(foodName: "", restaurantName: "", rating: 3, foodType: "", reviewNotes: "Enter Notes"))
                     }
                     
                     }
                     
                    
                }
            }
                }
            
            }
        
        }

#Preview {
    searchResults(searchValue: "")
}

individualItemView.swift

import SwiftUI
import SwiftData

struct IndividualItemView: View {
    @Bindable var review: Review <---- commenting this out and then fixing the other issues seems to resolve the error but then nothing shows.
    @Environment(\.modelContext) private var modelContext

    var body: some View {
        NavigationStack {
        ZStack {
            LinearGradient(gradient: Gradient(colors: [Color(red: 0.9725490196078431, green: 0.9607843137254902, blue: 0.8627450980392157, opacity: 1), Color(red: 0.9137254901960784, green: 0.9254901960784314, blue: 0.8509803921568627, opacity: 1), Color(red: 0.9882352941176471, green: 0.7529411764705882, blue: 0.13333333333333333, opacity: 1), Color(red: 0.9450980392156862, green: 0.47058823529411764, blue: 0.08627450980392157, opacity: 1)]), startPoint: .top, endPoint: .bottom).ignoresSafeArea()
            
            VStack {
            VStack(alignment: .leading)
            {
                Text(review.foodName)
                   .font(.system(size: 30, weight: .bold, design: .default))
                Text(review.restaurantName)
                Text(review.foodType)
            }
                VStack {
                    Image("friedFood")
                        .resizable()
                    .frame(width: 300, height: 300)
                        .cornerRadius(5)
                        .padding()
                    Label("\(review.rating)", systemImage: "star.fill")
                        .foregroundStyle(Color.mint)
                        .multilineTextAlignment(.center)
                        .padding()
                    Text(review.reviewNotes)
                        .padding(.horizontal)
                }
            }

        }
    }
    }
}

#Preview {
    //IndividualItemView(review: Review(backingData: any ))
      IndividualItemView(review: Review(foodName: "", restaurantName: "", rating: 0, foodType: "", reviewNotes: ""))
}

EditMealView.swift

import SwiftUI
import PhotosUI
import SwiftData


struct EditMealView: View {
    @Binding var isPresentingNewMealView: Bool
    @Environment(\.modelContext) private var modelContext
    @State var mealImage: Image?
    @State var imageSelection: PhotosPickerItem? = nil
    @Bindable var review: Review
    
    let foodType: [String] = ["Select One...", "Fast Food", "Vegetarian", "Central African", "East African", "North African", "Southern Africa", "West African", "Latin American", "Native American", "Canadian", "Carribean", "Mexican", "American", "Southern American", "Fusion", "Central American", "South American", "Chinese", "Japanese", "Korean", "Indian", "Middle Eastern", "Thai", "Turkish", "Vietnamese", "Italian", "French", "German", "Spanish", "Greek", "Romanian", "Russian", "Eastern European", "Scandinavian", "British", "Dutch", "Swedish", "Norwegian", "Icelandic", "Irish", "Polynesian", "Australian", "New Zealand", "Other"]
    
    var body: some View {
        NavigationStack {
            ZStack {
                LinearGradient(gradient: Gradient(colors: [Color(red: 0.9725490196078431, green: 0.9607843137254902, blue: 0.8627450980392157, opacity: 1), Color(red: 0.9137254901960784, green: 0.9254901960784314, blue: 0.8509803921568627, opacity: 1), Color(red: 0.9882352941176471, green: 0.7529411764705882, blue: 0.13333333333333333, opacity: 1), Color(red: 0.9450980392156862, green: 0.47058823529411764, blue: 0.08627450980392157, opacity: 1)]), startPoint: .top, endPoint: .bottom).ignoresSafeArea()
                
                    .navigationTitle("Add Meal")
                
                VStack{
                    Form {
                        
                        TextField("Food Name", text: $review.foodName)
                            .listRowBackground(Color.clear)
                        
                        TextField("Restaurant", text: $review.restaurantName)
                            .listRowBackground(Color.clear)
                        
                        Picker(selection: $review.foodType, label: Text("Select Style")) {
                            ForEach(0..<foodType.count, id: \.self) {
                                Text(foodType[$0])
                            }
                        }
                            .listRowBackground(Color.clear)
                        
                        VStack{
                            Text("Current \(Image(systemName: "star.fill")) Rating: \((review.rating), format: .number.rounded(increment: 0.1))")
                            Slider(value: $review.rating, in: 1...5, step: 0.5)
                        }
                        .listRowBackground(Color.clear)
                        .padding()
                        VStack{
                            HStack {
                                mealImage?
                                    .resizable()
                                    .frame(width: 300, height: 300)
                                
                            }
                            HStack {
                                Spacer()
                                PhotosPicker( selection: $imageSelection) {
                                    Image(systemName: "photo.circle.fill").imageScale(.large)
                                }
                                .task(id: imageSelection) {
                                    mealImage = try? await imageSelection?.loadTransferable(type: Image.self)
                                }
                                Spacer()
                            }.padding()
                        }
                        .listRowBackground(Color.clear)
                        .padding()
                        
                        TextEditor(text: $review.reviewNotes)
                            .listRowBackground(Color.clear)
                    }
                }
                
                
                
                .scrollContentBackground(.hidden)
                .toolbar {
                    ToolbarItem(placement: .cancellationAction) {
                        Button("Dismiss") {
                            isPresentingNewMealView = false
                        }
                    }
                    ToolbarItem(placement: .confirmationAction) {
                        Button("Add") {
                            let newReview = review
                            modelContext.insert(newReview)
                            isPresentingNewMealView = false
                            
                        }
                    }
                }
                
            }
        }
        

    }
    
}

#Preview {
    do {
        let config = ModelConfiguration(isStoredInMemoryOnly: true)
        let container = try ModelContainer(for: Review.self, configurations: config)
        
        let example = Review(foodName: "Cheetos", restaurantName: "House", rating: 3, foodType: "American", reviewNotes: "Delicious")
       return EditMealView(isPresentingNewMealView: .constant(true), mealImage: Image(""), review: example)
            .modelContainer(container)
    } catch {
        fatalError("Failed to create model container.")
    }

}

I have tried everything i could find. with this error being so vague and dependent on code efficiency, its hard to figure it out as a new developer.


Solution

  • You have several issues with your code. In searchResults you should use

      @State var searchValue: String = ""
    

    that is, give the @State var an initial value.

    You should use the common practice of starting the name of a View in uppercase, for example SearchResults.

    Importantly, you should use

      NavigationLink(destination: IndividualItemView(review: review))
    

    that is, IndividualItemView expects a Review to be passed to it.

    Note the NavigationStack in IndividualItemView and EditMealView are not use for any navigation. It is best not to nest NavigationStack like you do, IndividualItemView stack is inside the SearchResults stack. Try using NavigationPath.

    With these changes your code compiles and runs in my test on a real device not Preview.