CoreData Swift and transient attribute getters
core-data, swift
Solution
First, in the data model create a transient attribute (`section`). Because it is transient, it is not physically stored and thus not stored in the managed object context.
The `section` attribute is shown here:
The entity is shown here:
The class NSManagedObject subclass should have computed 'section' attribute. The `NSManagedObject` subclass demonstrating how to accomplish this is shown here:
class Number: NSManagedObject {
@NSManaged var number: NSNumber
var section: String? {
return number.intValue >= 60 ? "Pass" : "Fail"
}
}
Then you must set `sectionForKeyPath` in the NSFetchedResultsController initializer to be the transient attribute key in the data model and the cache name if desired.
override func viewDidLoad() {
super.viewDidLoad()
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "section", cacheName: "Root")
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
tableView.reloadData()
}
func fetchRequest() -> NSFetchRequest {
var fetchRequest = NSFetchRequest(entityName: "Number")
let sortDescriptor = NSSortDescriptor(key: "number", ascending: false)
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
return fetchRequest
}
The result is a `UITableViewController` with grades sorted by pass or fail dynamically:
I made a sample project that can be found on GitHub.
Problem
Any advice on implementing calculated attributes when using Core Data in Swift? with the generated ManagedObject class, I tried to override the getter but I get the error: 'NSManaged' not allowed on computed properties which implies you cannot override the getter for a transient (calculated) attribute. In the code sample below, `dateDue` is defined as a transient attribute in my model. Please note that the @NSManaged lines were generated by Xcode - not added by me. ``` @NSManaged var timeStamp: NSDate @NSManaged var dateDue: String { get { self.willAccessValueForKey("dateDue") var ddtmp = self.primitiveValueForKey("dateDue") as String? self.didAccessValueForKey("dateDue") if (ddtmp == nil) { let calendar = NSCalendar.currentCalendar() let components = calendar.components((NSCalendarUnit.YearCalendarUnit | NSCalendarUnit.MonthCalendarUnit ) , fromDate: self.timeStamp) ddtmp = "\(components.year * 1000 + components.month)" self.setPrimitiveValue(ddtmp, forKey: "dateDue") } return ddtmp! } } ```