SwiftUI use relationship predicate with struct parameter in FetchRequest
Asked Answered
S

2

5

How do I do use @FetchRequest with a parameter passed to a struct?

struct TodoItemView: View {
    var todoList: TodoList
    @FetchRequest(
        entity: TodoItem.entity(),
        sortDescriptors: [NSSortDescriptor(key: "order", ascending: true)],
        predicate: NSPredicate(format: "todoList == %@", todoList)
    ) var todoItems: FetchedResults<TodoItem>
    ...

I have todoList set up as a One relationship of TodoItem via TodoList.

It is giving me the error:

Cannot use instance member 'todoList' within property initializer; property initializers run before 'self' is available

How do I do a @FetchRequest with this relationship if I can't use it in the initializer? Also, should I be using todoList.objectID somewhere here instead?

Selfexcited answered 9/11, 2019 at 21:34 Comment(0)
S
12

Figured it out:

var todoList: TodoList
@FetchRequest var todoItems: FetchedResults<TodoItem>

init(todoList: TodoList) {
    self.todoList = todoList
    self._todoItems = FetchRequest(
        entity: TodoItem.entity(),
        sortDescriptors: [NSSortDescriptor(key: "order", ascending: true)],
        predicate: NSPredicate(format: "todoList == %@", todoList)
    )
}

Thanks to similar answers here: SwiftUI View and @FetchRequest predicate with variable that can change

Selfexcited answered 9/11, 2019 at 22:7 Comment(0)
T
-1

Another way is to split up the request and results vars (as is documented in the header) and apply the predicate in the results var, e.g.

    let todoList: TodoList

    private var request = FetchRequest<TodoItem>(
        sortDescriptors: [SortDescriptor(\.createdAt)],
        predicate: NSPredicate(value: false),
        animation: .default)

    private var todoItems: FetchedResults<TodoItem> {

         // Setting the same predicate again does not seem
         // to cause a refetch (according to SQL debug output).

         request.wrappedValue.nsPredicate = NSPredicate(format: "todoList = %@", todoList)

         // Here you could also change the sort from a state.

         return request.wrappedValue
    }
    
    ...
Trifoliate answered 8/10, 2023 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.