Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetching the most recent item from CoreData in Swift

I'm new to CoreData, have read a few tutorials but have come up empty-handed. Most tutorials have centered around fetching from CoreData to populate a tableview, which is not what I'm doing at the moment.

Here's how I'm setting the data in CoreData. All types are Double except for date which is an NSDate

let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)

let managedObjectContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Meditation", inManagedObjectContext: managedObjectContext!)
let meditation = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedObjectContext!)

meditation.setValue(settings.minutes, forKey: "length")
meditation.setValue(settings.warmup, forKey: "warmup")
meditation.setValue(settings.cooldown, forKey: "cooldown")
meditation.setValue(NSDate(), forKey: "date")

// fetch stuff from CoreData
var request = NSFetchRequest(entityName: "Meditation")
var error:NSError? = nil
var results:NSArray = managedObjectContext!.executeFetchRequest(request, error: &error)!

for res in results {
    println(res)
}

Here's what I'm trying to do to get the results, but I'm not able to access things like .minutes, .date, etc. I know I'm also not properly getting the last item either, I was just trying to print out attributes on the object first.

I'd love help on how to fetch only the most recent object as well as show it's attributes

Thanks!

like image 258
Zack Shapiro Avatar asked Dec 17 '14 19:12

Zack Shapiro


1 Answers

First, create a "Meditation.swift" file in Xcode with "Editor -> Create NSManagedObject Subclass ...". The generated file should look like

import Foundation
import CoreData

class Meditation: NSManagedObject {

    @NSManaged var length: NSNumber
    @NSManaged var warmup: NSNumber
    @NSManaged var cooldown: NSNumber
    @NSManaged var date: NSDate

}

Now you can use the properties directly instead of Key-Value Coding and create the object as

let meditation = NSEntityDescription.insertNewObjectForEntityForName("Meditation", inManagedObjectContext: managedObjectContext) as Meditation
meditation.length = ...
meditation.warmup = ...
meditation.cooldown = ...
meditation.date = NSDate()

var error : NSError?
if !managedObjectContext.save(&error) {
    println("save failed: \(error?.localizedDescription)")
}

When fetching the object, cast the result of executeFetchRequest() to [Meditation]:

let request = NSFetchRequest(entityName: "Meditation")

var error : NSError?
let result = managedObjectContext.executeFetchRequest(request, error: &error)
if let objects = result as? [Meditation] {
    for meditation in objects {
        println(meditation.length)
        println(meditation.date)
        // ...
    }
} else {
    println("fetch failed: \(error?.localizedDescription)")
}

Finally, to fetch only the latest object, add a sort descriptor to sort the results by date in descending order, and limit the number of results to one:

let request = NSFetchRequest(entityName: "Meditation")
request.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
request.fetchLimit = 1
// ...

Then the objects array contains at most one object, which is the most recent one.

like image 200
Martin R Avatar answered Oct 25 '22 17:10

Martin R