3

I have a problem with SwiftUI Preview not working sometimes (but not giving me any errors, just a blank Canvas). I have narrowed down the problem - it doesn't work when I'm using fetchRequest with init. But I don't know what to do next.

Preview works with this code:

import SwiftUI

struct ListView: View {

    var fetchRequest = FetchRequest<NPBooking>(entity: NPBooking.entity(), sortDescriptors: [])
    var bookings: FetchedResults<NPBooking> { fetchRequest.wrappedValue }

    var body: some View {
        ForEach(bookings, id: \.self) { booking in
            Text("item")
        }
    }

}

struct ListView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        //Test data
        let testBooking = NPBooking.init(context: context)
        testBooking.date = Date()
        testBooking.name = "name"
        return ListView().environment(\.managedObjectContext, context)
    }
}

Preview doesn't work with this code:

import SwiftUI

struct ListView: View {

    var fetchRequest: FetchRequest<NPBooking>
    var bookings: FetchedResults<NPBooking> { fetchRequest.wrappedValue }

    var body: some View {
        ForEach(bookings, id: \.self) { booking in
            Text("item")
        }
    }

    init(startDateOfMonth: Date) {
        fetchRequest = FetchRequest<NPBooking>(entity: NPBooking.entity(), sortDescriptors: [
            NSSortDescriptor(keyPath: \NPBooking.date, ascending: true)
        ], predicate: NSPredicate(format: "date >= %@", startDateOfMonth as NSDate))
    }

}

struct ListView_Previews: PreviewProvider {
    static var previews: some View {
        let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        //Test data
        let testBooking = NPBooking.init(context: context)
        testBooking.date = Date()
        testBooking.name = "name"
        return ListView(startDateOfMonth: Date()).environment(\.managedObjectContext, context)
    }
}

I guess I need to add some test data for this init or fetchRequest or both? Tried few things and I cannot manage to make it work.

3
  • I think the problem is that when you call the initialiser (in previews), you are using Date() for both the startDateOfMonth and endDateOfMonth. You need to calculate the start and end of month - for which see this answer. Commented Jan 29, 2020 at 9:58
  • Thanks, @pbasdf, but that's not it. I have just edited the code to use just startDateOfMonth alone and it still doesn't work. Commented Jan 29, 2020 at 11:33
  • Thanks, @pbasdf. It seems you were on the right track. This part with Date() was causing the problems. CranialDev provided the correct solution. Thanks for your help too :) Commented Jan 31, 2020 at 8:09

1 Answer 1

3

The Code works fine if you change your call in previews to

 ListView(startDateOfMonth: Date().addingTimeInterval(-86400 * 30)).environment(\.managedObjectContext, context)

Your startDateOfMonth var gets set to 30 days before today with this lines

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! It works. I understand this change in previews. But why VStack needed to be added? I think I have sometimes used ForEach alone. But maybe I'm wrong... hmmm
Actually, only thing needed was this addingTimeInterval in Previews part. With this code added everything works. Thanks! Adding VStack was not necessary and it just caused some problems - all the items rendered 3 times. I have edited your answer and left just the code that solved my problem. Thank you very much for your help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.