Search code examples
iosswiftcore-datansmanagedobjectcomputed-properties

Why can't I use a relationship in a NSManagedObject subclass computed property? (CoreData, swift)


I'm using CoreData and I have a Book entity and a ReadingSession entity. Each Book has many ReadingSessions.

If I add this computed property to the Book class, it works:

var sessions: [ReadingSession] {
    let request = NSFetchRequest(entityName: "ReadingSession")
    let predicate = NSPredicate(format: "book = %@", self)
    request.predicate = predicate
    return try! DataController.sharedInstance.managedObjectContext.executeFetchRequest(request) as! [ReadingSession]
}

But if I add this one, it doesn't:

var sessions: [ReadingSession] {
    return readingSession?.allObjects as! [ReadingSession]
}

This last example sometimes returns the correct array and sometimes just returns an empty array. I tried the same thing with other relationships inside computed properties and the results are the same.

Why is that? Is there a reason why I shouldn't try doing this? Is my first example a valid workaround, or will it cause me problems later on? Should I give up using computed properties for this and just repeat the code when I need it?

Thanks in advance!

Daniel


Solution

  • Answering my own question, as Wain pointed out in the comments I should be able to use relationships inside computed properties, and my problem was actually somewhere else.

    If you're interested in the details read the next paragraph, but, long story short, if you're having the same problem you should look into your relationships and make sure they're set properly as To One or To Many. Also check if you're setting all your properties in the right places and only when necessary.

    I edited my question to remove lots of unnecessary details and make it more readable, but in the end the problem was that I had a User entity with a selectedBook property which was set when a user selected a row. I had set it up as a To Many relationship, but a user can have only one selectedBook at a time, so it should have been a To One relationship there. Also when I created a book I set user.selectedBook to it, but the selectedBook property should only be set when a user selected a book from a row. So I was setting and trying to access some of my relationships at all the right times. I tried to access a user.selectedBook before a user had even selected a row, for instance, and then it obviously returned nil, which messed up many other computed properties. Now I fixed all that and I'm able to access all my relationships from within computed properties without any issues.