-
-
Save shakemno/9786bd6bd0319b4ee96c372dab681f2b to your computer and use it in GitHub Desktop.
AECoreData
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * https://gist.github.com/tadija/6003830264d67a87193ff0c3d20373e7 | |
| * Copyright (c) Marko Tadić 2018 | |
| * Licensed under the MIT license. See LICENSE file. | |
| */ | |
| import CoreData | |
| extension NSFetchRequestResult where Self: NSManagedObject { | |
| // MARK: Queries | |
| public static func findOrCreate(with predicate: NSPredicate? = nil, in context: NSManagedObjectContext) -> Self { | |
| return find(with: predicate, in: context) ?? self.init(context: context) | |
| } | |
| public static func find(key: String, value: Any, in context: NSManagedObjectContext?) -> Self? { | |
| return find(with: predicate(key: key, value: value), in: context) | |
| } | |
| public static func find(with predicate: NSPredicate? = nil, in context: NSManagedObjectContext?) -> Self? { | |
| if let objectFromMemory = context?.registeredObjects.first(where: { | |
| let isFulfilled = !$0.isFault | |
| let matchesPredicate = predicate?.evaluate(with: $0 as? Self) ?? false | |
| return isFulfilled && matchesPredicate | |
| }) as? Self { | |
| /// - Note: object is already in memory, this is way more performant than making a fetch request | |
| return objectFromMemory | |
| } else { | |
| return all(with: predicate, limit: 1, in: context).first | |
| } | |
| } | |
| public static func incrementedInteger(for attribute: String, in context: NSManagedObjectContext?) -> Int { | |
| let sortDescriptor = NSSortDescriptor(key: attribute, ascending: false) | |
| guard | |
| let object = all(orderedBy: [sortDescriptor], limit: 1, in: context).first, | |
| let max = object.value(forKey: attribute) as? Int | |
| else { return 0 } | |
| return max + 1 | |
| } | |
| public static func all(with predicate: NSPredicate? = nil, | |
| orderedBy sortDescriptors: [NSSortDescriptor] = [], | |
| limit: Int? = nil, | |
| in context: NSManagedObjectContext?) -> [Self] { | |
| guard let context = context | |
| else { return [] } | |
| let request = fetchRequest(predicate: predicate, sortDescriptors: sortDescriptors, limit: limit) | |
| let result = try? fetch(request, in: context) | |
| return result ?? [] | |
| } | |
| public static func unmanaged() -> Self { | |
| return self.init(entity: self.entity(), insertInto: nil) | |
| } | |
| public func `in`(_ context: NSManagedObjectContext?) -> Self? { | |
| guard let context = context, let object = context.object(with: objectID) as? Self else { | |
| return nil | |
| } | |
| return object | |
| } | |
| // MARK: Predicate & Fetch Request | |
| public static func predicate(key: String, value: Any) -> NSPredicate { | |
| return NSPredicate(format: "%K = %@", argumentArray: [key, value]) | |
| } | |
| public static func predicate(attributes: [String: Any], | |
| type: NSCompoundPredicate.LogicalType = .and) -> NSPredicate { | |
| let predicates = attributes.map { predicate(key: $0.key, value: $0.value) } | |
| let compoundPredicate = NSCompoundPredicate(type: type, subpredicates: predicates) | |
| return compoundPredicate | |
| } | |
| public static func fetchRequest(predicate: NSPredicate? = nil, sortDescriptors: [NSSortDescriptor] = [], | |
| limit: Int? = nil, offset: Int? = nil, batchSize: Int? = nil, | |
| relationshipKeyPathsForPrefetching: [String] = []) -> NSFetchRequest<Self> { | |
| let request = NSFetchRequest<Self>(entityName: String(describing: Self.self)) | |
| request.predicate = predicate | |
| request.sortDescriptors = sortDescriptors | |
| request.fetchLimit = limit ?? request.fetchLimit | |
| request.fetchOffset = offset ?? request.fetchOffset | |
| request.fetchBatchSize = batchSize ?? request.fetchBatchSize | |
| request.relationshipKeyPathsForPrefetching = relationshipKeyPathsForPrefetching | |
| return request | |
| } | |
| public static func fetch(_ request: NSFetchRequest<Self> = fetchRequest(), | |
| in context: NSManagedObjectContext) throws -> [Self] { | |
| return try context.fetch(request) | |
| } | |
| // MARK: Batch Update & Delete | |
| @discardableResult | |
| public static func batchUpdate(properties: [String: Any], predicate: NSPredicate? = nil, | |
| resultType: NSBatchUpdateRequestResultType = .updatedObjectsCountResultType, | |
| in context: NSManagedObjectContext) -> NSBatchUpdateResult? { | |
| let request = NSBatchUpdateRequest(entityName: String(describing: Self.self)) | |
| request.propertiesToUpdate = properties | |
| request.predicate = predicate | |
| request.resultType = resultType | |
| do { | |
| let result = try context.execute(request) | |
| return result as? NSBatchUpdateResult | |
| } catch { | |
| return nil | |
| } | |
| } | |
| @discardableResult | |
| public static func batchDelete(with predicate: NSPredicate? = nil, | |
| resultType: NSBatchDeleteRequestResultType = .resultTypeCount, | |
| in context: NSManagedObjectContext) -> NSBatchDeleteResult? { | |
| guard let request = fetchRequest(predicate: predicate) as? NSFetchRequest<NSFetchRequestResult> | |
| else { return nil } | |
| let deleteRequest = NSBatchDeleteRequest(fetchRequest: request) | |
| deleteRequest.resultType = resultType | |
| do { | |
| let result = try context.execute(deleteRequest) | |
| return result as? NSBatchDeleteResult | |
| } catch { | |
| return nil | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment