hugh-h
10/18/2017 - 8:49 PM

CoreDataService

CoreDataService implementation that takes a moc and exposes findExisting, create, save, fetchedResultsController

protocol CoreDataService {
    func findExisting<ObjectType:NSManagedObject>(ids: [String]) -> [ObjectType]?
    func create<ObjectType:NSManagedObject>(type:ObjectType.Type) -> ObjectType?
    func save()
    func fetchedResultsController<ObjectType:NSManagedObject>(sortedBy sortKey:String) -> NSFetchedResultsController<ObjectType>?
    var context: NSManagedObjectContext {
        get
    }
}


class AppCoreDataService: CoreDataService {
    
    private(set) var context:NSManagedObjectContext
    
    init(context: NSManagedObjectContext) {
        self.context = context
    }
    
    func findExisting<ObjectType:NSManagedObject>(ids: [String]) -> [ObjectType]? {
        guard let request:NSFetchRequest<ObjectType> = ObjectType.fetchRequest() as? NSFetchRequest<ObjectType> else {
            return []
        }
        
        request.predicate = NSPredicate(format: "id in %@", argumentArray: [ids])
        
        do {
            return try context.fetch(request)
            
        } catch {
            fatalError("Failed to find existing users: \(error)")
        }
    }
    
    func create<ObjectType:NSManagedObject>(type:ObjectType.Type) -> ObjectType? {
        return type.init(context: context)
    }
    
    func save() {
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                fatalError("Failed to save changes")
            }
        }
    }
    
    func fetchedResultsController<ObjectType:NSManagedObject>(sortedBy sortKey:String) -> NSFetchedResultsController<ObjectType>? {
        guard let fetchRequest:NSFetchRequest<ObjectType> = ObjectType.fetchRequest() as? NSFetchRequest<ObjectType> else {
            return nil
        }
        
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: sortKey, ascending: true)]
        let resultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        return resultsController
    }
    
}