Reputation: 35953
I have a core data entity called images that has just 2 fields:
imageName = NSString
timeStamp = NSNumber
I am trying to simulate a kind of stack LIFO (last in first out). Inserting a new entry is easy but what about reading the last entry added to the entity?
All images are added with a timestamp, obtained by using
time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970];
an integer that is equal to the number of seconds since 1970
so, how do I retrieve the last inserted record of a core data (= the record that has the biggest timestamp number)???
thanks
Upvotes: 4
Views: 15238
Reputation: 3138
In Swift 4, declare:
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let entity = [Entity]()
func getLastRecord() {
let entityCount = (entity.count - 1)
let lastRecord = entity[entityCount] // This is the las attribute of your core data entity
print(lastRecord)
}
Upvotes: -1
Reputation: 2668
I have tried using the method that Chris Doble mentioned and found it to be very slow, especially if there are lot of records that would need to be pulled and checked against the timeStamp. If you want to speed things up, I am now setting an attribute called isMostRecent on my ManagedObject's that I may ever want to get the most recent from. When a new record is to be stored I just grab the most recent record that has this attribute set to YES and change it to NO then set the new record that is being stored to YES. The next time I need to grab to most recent record all I have to do is this...
+ (Photo*)latestPhotoForMOC:(NSManagedObjectContext*)context {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:kCoreDataEntityNamePhoto
inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isMostRecent == %@", [NSNumber numberWithBool:YES]];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"isMostRecent" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
Photo* photo = nil;
if (mutableFetchResults && mutableFetchResults.count > 0) {
photo = [mutableFetchResults objectAtIndex:0];
}
return photo;
}
I have found this to be much faster. Yes, it requires a little more on your part to ensure it is used properly and that you don't ever end up with more than one record marked as isMostRecent but for me this was the best option.
Hope this helps someone else too.
Upvotes: 0
Reputation:
Perform a fetch request, sorting the results by timeStamp
.
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:...];
// Results should be in descending order of timeStamp.
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"timeStamp" ascending:NO];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSArray *results = [managedObjectContext executeFetchRequest:request error:NULL];
Entity *latestEntity = [results objectAtIndex:0];
You might also want to restrict the number of results using NSFetchRequest
's setFetchLimit:
.
Upvotes: 25