fix tests

This commit is contained in:
John Estropia
2026-07-15 19:54:47 +09:00
parent 890e150b95
commit 1ea9ad7c4a
12 changed files with 109 additions and 58 deletions
+2 -2
View File
@@ -3047,7 +3047,7 @@
SWIFT_COMPILATION_MODE = singlefile;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 17.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -3112,7 +3112,7 @@
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
TVOS_DEPLOYMENT_TARGET = 17.0;
VALIDATE_PRODUCT = YES;
@@ -50,11 +50,11 @@ extension Advanced.EvolutionDemo {
}
self.mutateItemAtIndex = { index in
let object = listPublisher.snapshot[index]
let persistentID = listPublisher.snapshot[index].persistentID()
dataStack.perform(
asynchronous: { transaction in
object
persistentID
.asEditable(in: transaction)?
.mutate(in: transaction)
},
@@ -26,7 +26,7 @@ extension Classic.ColorsDemo {
/**
Sample 2: We can end monitoring updates anytime. `removeObserver()` was called here for illustration purposes only. `ListMonitor`s safely remove deallocated observers automatically.
*/
deinit {
isolated deinit {
self.listMonitor.removeObserver(self)
}
@@ -40,59 +40,86 @@ extension Classic.ColorsDemo {
typealias ListEntityType = Classic.ColorsDemo.Palette
func listMonitorWillChange(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
nonisolated func listMonitorWillChange(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
self.tableView.beginUpdates()
MainActor.assumeIsolated {
self.tableView.beginUpdates()
}
}
func listMonitorDidChange(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
nonisolated func listMonitorDidChange(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
self.tableView.endUpdates()
MainActor.assumeIsolated {
self.tableView.endUpdates()
}
}
func listMonitorDidRefetch(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
nonisolated func listMonitorDidRefetch(_ monitor: ListMonitor<Classic.ColorsDemo.Palette>) {
self.tableView.reloadData()
MainActor.assumeIsolated {
self.tableView.reloadData()
}
}
// MARK: ListObjectObserver
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertObject object: ListEntityType, toIndexPath indexPath: IndexPath) {
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertObject object: ListEntityType, toIndexPath indexPath: IndexPath) {
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didDeleteObject object: ListEntityType, fromIndexPath indexPath: IndexPath) {
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didUpdateObject object: ListEntityType, atIndexPath indexPath: IndexPath) {
if case let cell as Classic.ColorsDemo.ItemCell = self.tableView.cellForRow(at: indexPath) {
cell.setPalette(object)
MainActor.assumeIsolated {
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
}
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didMoveObject object: ListEntityType, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didDeleteObject object: ListEntityType, fromIndexPath indexPath: IndexPath) {
self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
self.tableView.insertRows(at: [toIndexPath], with: .automatic)
MainActor.assumeIsolated {
self.tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didUpdateObject object: sending ListEntityType, atIndexPath indexPath: IndexPath) {
MainActor.assumeIsolated {
if case let cell as Classic.ColorsDemo.ItemCell = self.tableView.cellForRow(at: indexPath) {
cell.setPalette(object)
}
}
}
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didMoveObject object: ListEntityType, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
MainActor.assumeIsolated {
self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
self.tableView.insertRows(at: [toIndexPath], with: .automatic)
}
}
// MARK: ListSectionObserver
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) {
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) {
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
MainActor.assumeIsolated {
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
}
}
func listMonitor(_ monitor: ListMonitor<ListEntityType>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
nonisolated func listMonitor(_ monitor: ListMonitor<ListEntityType>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
MainActor.assumeIsolated {
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
}
}
@@ -131,11 +158,11 @@ extension Classic.ColorsDemo {
switch editingStyle {
case .delete:
let object = self.listMonitor[indexPath]
let persistentID = self.listMonitor[indexPath].persistentID()
Classic.ColorsDemo.dataStack.perform(
asynchronous: { (transaction) in
transaction.delete(object)
transaction.delete(persistentID)
},
completion: { _ in }
)
-2
View File
@@ -65,7 +65,6 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
Do not call this directly. This is exposed as public only as a required initializer.
- Important: subclasses that need a custom initializer should override both `init(rawObject:)` and `init(asMeta:)`, and to call their corresponding super implementations.
*/
@_spi(Internals)
public required init(rawObject: NSManagedObject) {
self.isMeta = false
@@ -85,7 +84,6 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
Do not call this directly. This is exposed as public only as a required initializer.
- Important: subclasses that need a custom initializer should override both `init(rawObject:)` and `init(asMeta:)`, and to call their corresponding super implementations.
*/
@_spi(Internals)
public required init(asMeta: Void) {
self.isMeta = true
+1 -1
View File
@@ -46,7 +46,7 @@ extension DataStack {
Thread.isMainThread,
"Attempted to observe objects from \(Internals.typeName(self)) outside the main thread."
)
return .init(objectID: object.cs_id(), context: self.unsafeContext())
return .init(managedObjectID: object.cs_id(), context: self.unsafeContext())
}
/**
-8
View File
@@ -91,14 +91,6 @@ public nonisolated protocol DynamicObject: AnyObject, SendableMetatype {
extension DynamicObject {
// MARK: Public
public func persistentID() -> DynamicObjectID<Self> {
return .init(managedObjectID: self.cs_id())
}
// MARK: Internal
internal func runtimeType() -> Self.Type {
+5
View File
@@ -95,6 +95,11 @@ public struct DynamicObjectID<O: DynamicObject>: Hashable, ObjectRepresentation,
public typealias ObjectType = O
public func persistentID() -> ObjectType.ObjectID {
return self
}
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<ObjectType> {
let context = dataStack.unsafeContext()
+17 -12
View File
@@ -170,7 +170,7 @@ public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentati
@_spi(Internals)
public func cs_id() -> NSManagedObjectID {
return self.id
return self.managedObjectID
}
@_spi(Internals)
@@ -184,43 +184,48 @@ public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentati
public typealias ObjectType = O
public func persistentID() -> O.ObjectID {
return .init(managedObjectID: self.managedObjectID)
}
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
return dataStack.unsafeContext().objectPublisher(managedObjectID: self.id)
return dataStack.unsafeContext().objectPublisher(managedObjectID: self.managedObjectID)
}
public func asReadOnly(in dataStack: DataStack) -> O? {
return dataStack.unsafeContext().fetchExisting(self.id)
return dataStack.unsafeContext().fetchExisting(self.managedObjectID)
}
public func asEditable(in transaction: BaseDataTransaction) -> O? {
return transaction.unsafeContext().fetchExisting(self.id)
return transaction.unsafeContext().fetchExisting(self.managedObjectID)
}
public func asSnapshot(in dataStack: DataStack) -> ObjectSnapshot<O>? {
let context = dataStack.unsafeContext()
return ObjectSnapshot<O>(managedObjectID: self.id, context: context)
return ObjectSnapshot<O>(managedObjectID: self.managedObjectID, context: context)
}
public func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<O>? {
let context = transaction.unsafeContext()
return ObjectSnapshot<O>(managedObjectID: self.id, context: context)
return ObjectSnapshot<O>(managedObjectID: self.managedObjectID, context: context)
}
// MARK: Internal
internal init(
objectID: NSManagedObjectID,
managedObjectID: NSManagedObjectID,
context: NSManagedObjectContext
) {
let fetchRequest = Internals.CoreStoreFetchRequest<NSManagedObject>()
fetchRequest.entity = objectID.entity
fetchRequest.entity = managedObjectID.entity
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchRequest.sortDescriptors = []
@@ -230,13 +235,13 @@ public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentati
let fetchedResultsController = Internals.CoreStoreFetchedResultsController(
context: context,
fetchRequest: fetchRequest,
from: From<O>([objectID.persistentStore?.configurationName]),
applyFetchClauses: Where<O>("SELF", isEqualTo: objectID).applyToFetchRequest
from: From<O>([managedObjectID.persistentStore?.configurationName]),
applyFetchClauses: Where<O>("SELF", isEqualTo: managedObjectID).applyToFetchRequest
)
let fetchedResultsControllerDelegate = Internals.FetchedResultsControllerDelegate()
self.id = objectID
self.managedObjectID = managedObjectID
self.fetchedResultsController = fetchedResultsController
self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate
@@ -355,7 +360,7 @@ public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentati
// MARK: Private
private let id: NSManagedObjectID
private let managedObjectID: NSManagedObjectID
private let fetchedResultsController: Internals.CoreStoreFetchedResultsController
private let fetchedResultsControllerDelegate: Internals.FetchedResultsControllerDelegate
private let lastCommittedAttributes: Internals.Mutex<[String: NSObject]> = .init([:])
+5
View File
@@ -177,6 +177,11 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
public typealias ObjectType = O
public func persistentID() -> O.ObjectID {
return .init(managedObjectID: self.managedObjectID)
}
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
let context = dataStack.unsafeContext()
+14
View File
@@ -59,6 +59,11 @@ public protocol ObjectRepresentation: AnyObjectRepresentation {
*/
associatedtype ObjectType: DynamicObject
/**
The `Sendable` ID to use for referencing the object between isolation contexts.
*/
func persistentID() -> ObjectType.ObjectID
/**
An instance that may be observed for object changes.
*/
@@ -85,6 +90,7 @@ public protocol ObjectRepresentation: AnyObjectRepresentation {
func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<ObjectType>?
}
extension NSManagedObject: ObjectRepresentation {}
extension CoreStoreObject: ObjectRepresentation {}
@@ -92,6 +98,14 @@ extension CoreStoreObject: ObjectRepresentation {}
extension DynamicObject where Self: ObjectRepresentation {
// MARK: Public
/**
The `Sendable` ID to use for referencing the object between isolation contexts.
*/
public func persistentID() -> Self.ObjectID {
return .init(managedObjectID: self.cs_id())
}
/**
An `ObjectPublisher` wrapper for the exact same object
+5
View File
@@ -69,6 +69,11 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable,
public typealias ObjectType = O
public func persistentID() -> ObjectType.ObjectID {
return .init(managedObjectID: self.managedObjectID)
}
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
let context = dataStack.unsafeContext()
@@ -41,7 +41,7 @@ extension UnsafeDataTransaction {
_ object: O
) -> ObjectMonitor<O> {
return .init(objectID: object.cs_id(), context: self.unsafeContext())
return .init(managedObjectID: object.cs_id(), context: self.unsafeContext())
}
/**