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?