I have Pet entities that can have multiple Events:

public class Pet: NSManagedObject { 
    @NSManaged var dbName: String
    @NSManaged var events: NSSet?    // 1-to-many relationship with events
}

public class Event: NSManagedObject {
    @NSManaged var key: String
    @NSManaged var date: Int64
}

I've set Events to be indexed based on their date. I've made a function that returns all Events for a given pet.

func fetchEventsForPet(pet: String) -> [Event]? {
    let request = NSFetchRequest<NSFetchRequestResult>(entityName: Pet.entityName)
    let predicate = NSPredicate(format: "dbName == %@", pet)
    request.predicate = predicate
    request.fetchLimit = 1
    do {
        let result = try self.fetch(request) as? [Pet]
        if let pets = result {
            for pet in pets {
                if let events = pet.events {
                    if let evts = events.allObjects as? [Event] {
                        return evts                      // Return pets events
                    }
                }
            }
        }
    } catch {}
    return nil
}

How would I modify this function to only return the last event (the lastest event based on date)? Do I have to fetch all events each time or is there a faster way to do this?

score:1

Accepted answer

Your entity class definitions imply that you do not have an inverse relationship from Event to Pet. You should create one (there are very, very few occasions where you are better off without an inverse). You can then fetch Events directly, rather than fetching Pets and using the events relationship. Assuming you name the inverse relationship "pet", you would use a predicate like this:

  let predicate = NSPredicate(format: "pet.dbName == %@", pet)

You can then apply sort descriptors and fetch limit to return only the most recent Event for a given pet name.


More questions