UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Efficient way of passing children CoreData objects between SwiftUI views

Forums > SwiftUI

I have a Category (structure) Word (structure) with a simple one to many relationship defined between Category and Word i.e Category has many Words.

I have a master detail style view setup using NavigationViews, the master view picks a list of Categories and displays them on a list.

struct CategoryView: View {

    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Category.name, ascending: true)],
        animation: .default)
    private var categories: FetchedResults<Category>

    var body: some View {
        List {
            Section {
                ForEach(self.categories) { category in
                    NavigationLink(destination:
                                    WordListView(title: category.name!,
                                                 words: category.words!.allObjects as! [Word])) {
                        Text("\(category.name!)")
                    }
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
    }
}

What I am wanting to do is pass the words property (presumably Core Data will fetch these once it's accessed) to a child view to display a list of Words:

struct CategoryView: View {

    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Category.name, ascending: true)],
        animation: .default)
    private var categories: FetchedResults<Category>

    var body: some View {
        List {
            Section {
                ForEach(self.categories) { category in
                    NavigationLink(destination:
                                    WordListView(title: category.name!,
                                                 words: category.words!.allObjects as! [Word])) {
                        Text("\(category.name!)")
                    }
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
    }
}

Core Data makes the property available as a NSSet, which I am converting to an Array.

Is this al efficient thing to do? I feel like I am beating all the nice lazy loading Core Data would do.

Any suggestions out there on doing this better?

Thank you for your time.

3      

hi,

i would simply change the WordListView to accept a category:

    NavigationLink(destination: WordListView(category: category)) { ...

and then let the WordListView pull out the name and the words when it is displayed.

that way, you are not pulling in all the words of all the categories to seed multiple WordListViews; only when you navigate to a WordListView will the words be pulled in for that one associated category.

hope that helps,

DMG

3      

Thanks @delawaremathguy, that did occur to me. I am trying to reuse WordListView for other use cases, e.g group words by letter where I was going to pass in a set of Words

Hence I went for passing a title as a String and the set of Words.

Otherwise I agree, that would have worked a treat.

3      

hi @devraj,

if you want to preserve an option for WordListView(title: words:), consider using an intermediate view such as:

struct WordListView2() {
    var category: Category
    var body: some View {
        WordListView(title: category.name!, words: category.words!.allObjects as! [Word])
    }
}

and now calling this from CategoryView

        NavigationLink(destination: WordListView2(category: category)) { ...

hope that helps,

DMG

3      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.