Files
SideStore/Sources/SideStoreCore/Protocols/Fetchable.swift

65 lines
2.8 KiB
Swift
Raw Normal View History

2019-06-06 14:46:23 -07:00
//
// NSManagedObject+Conveniences.swift
// AltStore
//
// Created by Riley Testut on 6/6/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import CoreData
public typealias FetchRequest = NSFetchRequest<NSFetchRequestResult>
2023-03-01 00:48:36 -05:00
public protocol Fetchable: NSManagedObject {}
2019-06-06 14:46:23 -07:00
2023-03-01 00:48:36 -05:00
public extension Fetchable {
static func first(satisfying predicate: NSPredicate? = nil, sortedBy sortDescriptors: [NSSortDescriptor]? = nil, in context: NSManagedObjectContext,
2023-03-01 00:48:36 -05:00
requestProperties: [PartialKeyPath<FetchRequest>: Any?] = [:]) -> Self? {
let managedObjects = Self.all(satisfying: predicate, sortedBy: sortDescriptors, in: context, requestProperties: requestProperties, returnFirstResult: true)
2019-06-06 14:46:23 -07:00
return managedObjects.first
}
2023-03-01 00:48:36 -05:00
static func all(satisfying predicate: NSPredicate? = nil, sortedBy sortDescriptors: [NSSortDescriptor]? = nil, in context: NSManagedObjectContext,
2023-03-01 00:48:36 -05:00
requestProperties: [PartialKeyPath<FetchRequest>: Any?] = [:]) -> [Self] {
let managedObjects = Self.all(satisfying: predicate, sortedBy: sortDescriptors, in: context, requestProperties: requestProperties, returnFirstResult: false)
2019-06-06 14:46:23 -07:00
return managedObjects
}
2023-03-01 00:48:36 -05:00
static func fetch(_ fetchRequest: NSFetchRequest<Self>, in context: NSManagedObjectContext) -> [Self] {
do {
let managedObjects = try context.fetch(fetchRequest)
return managedObjects
2023-03-01 00:48:36 -05:00
} catch {
print("Failed to fetch managed objects. Fetch Request: \(fetchRequest). Error: \(error).")
return []
}
}
2023-03-01 00:48:36 -05:00
private static func all(satisfying predicate: NSPredicate? = nil, sortedBy sortDescriptors: [NSSortDescriptor]? = nil, in context: NSManagedObjectContext, requestProperties: [PartialKeyPath<FetchRequest>: Any?], returnFirstResult: Bool) -> [Self] {
let registeredObjects = context.registeredObjects.lazy.compactMap { $0 as? Self }.filter { predicate?.evaluate(with: $0) != false }
if let managedObject = registeredObjects.first, returnFirstResult {
2019-06-06 14:46:23 -07:00
return [managedObject]
}
2023-03-01 00:48:36 -05:00
2019-06-06 14:46:23 -07:00
let fetchRequest = self.fetchRequest() as! NSFetchRequest<Self>
fetchRequest.predicate = predicate
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.returnsObjectsAsFaults = false
2023-03-01 00:48:36 -05:00
for (keyPath, value) in requestProperties {
// Still no easy way to cast PartialKeyPath back to usable WritableKeyPath :(
guard let objcKeyString = keyPath._kvcKeyPathString else { continue }
fetchRequest.setValue(value, forKey: objcKeyString)
}
2023-03-01 00:48:36 -05:00
let fetchedObjects = fetch(fetchRequest, in: context)
if let fetchedObject = fetchedObjects.first, returnFirstResult {
return [fetchedObject]
2023-03-01 00:48:36 -05:00
} else {
return fetchedObjects
2019-06-06 14:46:23 -07:00
}
}
}