NSModelObjectContextExecutor.swift 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. import CoreData
  2. import Foundation
  3. public final class NSModelObjectContextExecutor: @unchecked Sendable, SerialExecutor {
  4. public let context: NSManagedObjectContext
  5. public init(context: NSManagedObjectContext) {
  6. self.context = context
  7. }
  8. // Enqueue the job to the context's queue.
  9. public func enqueue(_ job: consuming ExecutorJob) {
  10. let unownedJob = UnownedJob(job)
  11. let unownedExecutor = asUnownedSerialExecutor()
  12. context.perform {
  13. unownedJob.runSynchronously(on: unownedExecutor)
  14. }
  15. }
  16. // Return an unowned serial executor reference.
  17. public func asUnownedSerialExecutor() -> UnownedSerialExecutor {
  18. UnownedSerialExecutor(ordinary: self)
  19. }
  20. }
  21. // A protocol to define common functionalities for Core Data-based actors
  22. protocol CoreDataActor {
  23. var modelExecutor: NSModelObjectContextExecutor { get }
  24. var modelContainer: NSPersistentContainer { get }
  25. }
  26. // Extend the protocol with default implementations and helpers
  27. extension CoreDataActor {
  28. public var modelContext: NSManagedObjectContext {
  29. modelExecutor.context
  30. }
  31. public var unownedExecutor: UnownedSerialExecutor {
  32. modelExecutor.asUnownedSerialExecutor()
  33. }
  34. // Provide a generic subscript to fetch objects by NSManagedObjectID
  35. public subscript<T>(id: NSManagedObjectID, as _: T.Type) -> T? where T: NSManagedObject {
  36. try? modelContext.existingObject(with: id) as? T
  37. }
  38. }