Skip to content

Instantly share code, notes, and snippets.

@capttaco
Last active May 3, 2019 17:28
Show Gist options
  • Star 48 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save capttaco/adb38e0d37fbaf9c004e to your computer and use it in GitHub Desktop.
Save capttaco/adb38e0d37fbaf9c004e to your computer and use it in GitHub Desktop.
A utility protocol for custom NSManagedObjects that makes querying contexts simpler and more convenient. Requires Swift 2.
import CoreData
protocol Fetchable
{
typealias FetchableType: NSManagedObject
static func entityName() -> String
static func objectsInContext(context: NSManagedObjectContext, predicate: NSPredicate?, sortedBy: String?, ascending: Bool) throws -> [FetchableType]
static func singleObjectInContext(context: NSManagedObjectContext, predicate: NSPredicate?, sortedBy: String?, ascending: Bool) throws -> FetchableType?
static func objectCountInContext(context: NSManagedObjectContext, predicate: NSPredicate?) -> Int
static func fetchRequest(context: NSManagedObjectContext, predicate: NSPredicate?, sortedBy: String?, ascending: Bool) -> NSFetchRequest
}
extension Fetchable where Self : NSManagedObject, FetchableType == Self
{
static func singleObjectInContext(context: NSManagedObjectContext, predicate: NSPredicate? = nil, sortedBy: String? = nil, ascending: Bool = false) throws -> FetchableType?
{
let managedObjects: [FetchableType] = try objectsInContext(context, predicate: predicate, sortedBy: sortedBy, ascending: ascending)
guard managedObjects.count > 0 else { return nil }
return managedObjects.first
}
static func objectCountInContext(context: NSManagedObjectContext, predicate: NSPredicate? = nil) -> Int
{
let request = fetchRequest(context, predicate: predicate)
let error: NSErrorPointer = nil;
let count = context.countForFetchRequest(request, error: error)
guard error != nil else {
NSLog("Error retrieving data %@, %@", error, error.debugDescription)
return 0;
}
return count;
}
static func objectsInContext(context: NSManagedObjectContext, predicate: NSPredicate? = nil, sortedBy: String? = nil, ascending: Bool = false) throws -> [FetchableType]
{
let request = fetchRequest(context, predicate: predicate, sortedBy: sortedBy, ascending: ascending)
let fetchResults = try context.executeFetchRequest(request)
return fetchResults as! [FetchableType]
}
static func fetchRequest(context: NSManagedObjectContext, predicate: NSPredicate? = nil, sortedBy: String? = nil, ascending: Bool = false) -> NSFetchRequest
{
let request = NSFetchRequest()
let entity = NSEntityDescription.entityForName(entityName(), inManagedObjectContext: context)
request.entity = entity
if predicate != nil {
request.predicate = predicate
}
if (sortedBy != nil) {
let sort = NSSortDescriptor(key: sortedBy, ascending: ascending)
let sortDescriptors = [sort]
request.sortDescriptors = sortDescriptors
}
return request
}
}
@niels-k-86
Copy link

@Logistes

Instead of protocol Fetchable

{
typealias FetchableType: NSManagedObject

wouldn't this be better?

protocol Fetchable
{
typealias FetchableType: NSManagedObject = Self

Yes, that makes things easier. However, you still need to define the typealias when subclassing an NSManagedObject subclass.

class Image: NSManagedObject, Fetchable {
    // This works, without typealias
}

class ThumbnailImage: Image {
    // Need redefining of FetchableType if you want the Fetchable methods to return instances of ThumbnailImage
    typealias FetchableType = ThumbnailImage
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment