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

Sequential FetchRequests in SwiftUI View

Forums > SwiftUI

Background

I have a flashcard app which is using an NSPersistentCloudKitContainer with an NSManagedObjectModel that essentially looks like:

Card Entity (Private Store)

Attribute Type Example
contentID String fruit1
order Integer 1

Content Entity (Public Store)

Attribute Type Example
id String fruit1
content String Apple
order Integer 1

Because NSPersistentCloudKitContainer doesn't allow for relationships between the public and private stores, each Card has an attribute that is an ID of a Content which I can use in my FetchRequest.

The Content is learned sequentially and when the user learns the next Content a new Card is created to keep track of what they need to learn next.

Problem

I have a SwiftUI View that is supposed to show the next n Content the user will learn. This means I need one FetchRequest that will tell me the Card with the highest order attribute (i.e. the last thing learned) so that I can then make a second FetchRequest for the next n Content.

I would like to do something like this:

extension Card {
    static var lastCard: NSFetchRequest<Card> {
        let request = Card.fetchRequest()
        request.sortDescriptors = [NSSortDescriptor(keyPath: \Card.order, ascending: false)]
        request.fetchLimit = 1
        return request
    }
}

extension Content {
    static func nextContent(fetchOffset: Int, fetchLimit: Int) -> NSFetchRequest<Content> {
        let request = Content.fetchRequest()
        request.sortDescriptors = [NSSortDescriptor(keyPath: \Content.order, ascending: true)]
        request.fetchOffset = fetchOffset
        request.fetchLimit = fetchLimit
        return request
    }
}

struct ToLearnList: View {
    @FetchRequest var lastCard: FetchedResults<Card>
    @FetchRequest var content: FetchedResults<Content>

    var body: some View {
        List(content) { 
            Text($0.content)
        }
    }

    init() {
        // I don't know what the user most recently learned so I must fetch it.
        _lastCard = FetchRequest(fetchRequest: Card.lastCard) 

        let fetchOffset = // <- How can I get this from `lastCard`?
        let fetchLimit = UserDefaults.standard.integer(forKey: "remainingDailyLearns")

        // This is what I actually need but I can't create a `FetchRequest` without 
        // knowing the most recent card.
        _content = FetchRequest(fetchRequest: Content.nextContent(fetchOffset: fetchOffset, fetchLimit: fetchLimit))
    }
}

I want to use @FetchRequest because if the CloudKit public store changes or if the user adds a new Card on another device, the NSPersistentCloudKitContainer will synchronize the stores and the @FetchRequest will update the view.

What is the best approach to get some offset number of fetched results from a different entity?

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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.