Home > OS >  SwiftUI Preview doesn't work with Core Data
SwiftUI Preview doesn't work with Core Data

Time:08-03

I have been trying to get my detail view working but when giving the preview arguments of the currently selected item from the list it keeps giving me an error Cannot convert value of type 'Item.Type' to expected argument type 'Item'

Here is the detailview

import SwiftUI
import CoreData

struct FishDetailView: View {

    var item: Item

    @State var image : Data = .init(count: 0)
    
    var body: some View {
        Text(item.title ?? "")
        Text(item.details ?? "")
        Image(uiImage: UIImage(data: item.imageData ?? self.image)!)
            .resizable()
            .frame(width: UIScreen.main.bounds.width - 34, height: 210)
            .cornerRadius(15)
    }
}

struct FishDetailView_Previews: PreviewProvider {
    static var previews: some View {
        
        FishDetailView(item: Item) **<--- THE ERROR HAPPENS HERE**
    }
}

Contentview.swift

import SwiftUI
import CoreData

struct ContentView: View {
    // MARK: - PROPERTY

    @State var title: String = ""
    @State private var showSheet: Bool = false
    @State var image : Data = .init(count: 0)
    @Environment(\.managedObjectContext) var viewContext

        @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>
    
    // MARK: - FUNCTION
    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
    
    //: MARK - BODY

    var body: some View {
        NavigationView {
            VStack {
              
                List {
                    ForEach(items, id: \.self) { item in
                        NavigationLink(destination: FishDetailView(item: item)) {
                            Image(uiImage: (UIImage(data: item.imageData ?? self.image) ?? UIImage(systemName: "photo"))!)
                                .resizable()
                                .frame(width: UIScreen.main.bounds.width - 34, height: 210)
                                .cornerRadius(15)
                            HStack {
                                Text("\(item.details ?? "")")
                                
                            }//:HSTACK
                        }
                        // TODO: Insert timestamp here with .footnote font
                        }
                    }
                    
                    if showSheet {
                        AddFishView()
                    }
                }//: LIST
                .navigationBarTitle("Fishes", displayMode: .large)
                .navigationBarItems(trailing: Button(action: {
                    self.showSheet.toggle()
                })
                   {
                    Image(systemName: "camera.fill")
                })
                .sheet(isPresented: self.$showSheet) {
                    AddFishView()
                }
            } //: VSTACK
        } //: NAVIGATION
    }

// MARK: - PREVIEW

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        let persistenceController = PersistenceController.shared
        ContentView().environment(\.managedObjectContext, persistenceController.container.viewContext)
    }
}

The detailview does work if I remove the preview section of the code but it's not really ideal since I would like to see what I'm doing without having to open the app in simulator every time I do a change.

I can't seem to work out why it does it or how to fix it. Someone with better brains can help out?

The code is little bit messy because this is just a test I'm doing where I'm saving a users image into Core Data.

EDIT: already tried this that was suggested but didn't seem to fix my issue Entity image

CodePudding user response:

import SwiftUI
import CoreData

struct FishDetailView: View {

    @ObservedObject var item: Item

    var body: some View {
        Text(item.title ?? "")
        ...
        // fyi your image should be a transformable attribute on the Item entity
    }
}

struct FishDetailView_Previews: PreviewProvider {
    static var previews: some View {
        let context = PersistenceController.preview.container.viewContext
        let item = context.firstItem
        FishDetailView(item: item) 
    }
}


extension NSManagedObjectContext {
    var firstItem: Item {
        let fetchRequest = Item.fetchRequest()
        fetchRequest.fetchLimit = 1
        let result = try! fetch(fetchRequest)
        return result.first!
    }
}

CodePudding user response:

It looks like you're trying to feed the preview a type rather than an instance of a type:

FishDetailView(item: Item)

Perhaps this is what you're trying to do instead:

let item = Item(/* init here */)
return FishDetailView(item: item)

or

FishDetailView(item: Item(/* init here */))
  • Related