From c077bdb08ebfd9fc0184a688e937d87900d0b8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Vacic=CC=81?= Date: Sat, 23 Mar 2024 19:05:59 +0100 Subject: [PATCH 1/8] Enable strict-concurrency --- Package.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 38fc3dd..e42bcf4 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,13 @@ let package = Package( .package(url: "https://github.com/apple/swift-syntax.git", from: "509.0.0") ], targets: [ - .target(name: "ManagedModels", dependencies: [ "ManagedModelMacros" ]), + .target( + name: "ManagedModels", + dependencies: [ "ManagedModelMacros" ], + swiftSettings: [ + .enableExperimentalFeature("StrictConcurrency") + ] + ), .macro( name: "ManagedModelMacros", From 075ad96817d6ee255fbe47b83ca330d100b3e708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Vacic=CC=81?= Date: Sat, 23 Mar 2024 19:06:15 +0100 Subject: [PATCH 2/8] Light sprinkling of Sendable, as needed --- Sources/ManagedModels/Container/ModelConfiguration.swift | 8 ++++---- Sources/ManagedModels/Schema/AttributeOption.swift | 4 ++-- Sources/ManagedModels/Schema/RelationshipOption.swift | 4 ++-- .../SchemaCompatibility/CoreDataPrimitiveValue.swift | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/ManagedModels/Container/ModelConfiguration.swift b/Sources/ManagedModels/Container/ModelConfiguration.swift index 3e861c7..ef420ad 100644 --- a/Sources/ManagedModels/Container/ModelConfiguration.swift +++ b/Sources/ManagedModels/Container/ModelConfiguration.swift @@ -3,9 +3,9 @@ // Copyright © 2023 ZeeZide GmbH. // -import CoreData +@preconcurrency import CoreData -public struct ModelConfiguration: Hashable { +public struct ModelConfiguration: Hashable, Sendable { // TBD: Some of those are `let` in SwiftData public var path : String @@ -83,7 +83,7 @@ extension ModelConfiguration: Identifiable { public extension ModelConfiguration { - struct GroupContainer: Hashable { + struct GroupContainer: Hashable, Sendable { enum Value: Hashable { case automatic, none case identifier(String) @@ -100,7 +100,7 @@ public extension ModelConfiguration { public extension ModelConfiguration { - struct CloudKitDatabase: Hashable { + struct CloudKitDatabase: Hashable, Sendable { enum Value: Hashable { case automatic, none case `private`(String) diff --git a/Sources/ManagedModels/Schema/AttributeOption.swift b/Sources/ManagedModels/Schema/AttributeOption.swift index 4af7fcf..0e9aa86 100644 --- a/Sources/ManagedModels/Schema/AttributeOption.swift +++ b/Sources/ManagedModels/Schema/AttributeOption.swift @@ -7,7 +7,7 @@ import class Foundation.ValueTransformer extension NSAttributeDescription { - public struct Option: Equatable { + public struct Option: Equatable, Sendable { let value : Value @@ -39,7 +39,7 @@ extension NSAttributeDescription { extension NSAttributeDescription.Option { - enum Value { + enum Value: Sendable { case unique, externalStorage, preserveValueOnDeletion, ephemeral, spotlight case transformableByType(ValueTransformer.Type) case transformableByName(String) diff --git a/Sources/ManagedModels/Schema/RelationshipOption.swift b/Sources/ManagedModels/Schema/RelationshipOption.swift index 271c371..2ad1c84 100644 --- a/Sources/ManagedModels/Schema/RelationshipOption.swift +++ b/Sources/ManagedModels/Schema/RelationshipOption.swift @@ -7,9 +7,9 @@ import CoreData public extension NSRelationshipDescription { - struct Option: Equatable { + struct Option: Equatable, Sendable { - enum Value { + enum Value: Sendable { case unique } let value : Value diff --git a/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift b/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift index 1228903..46ece1f 100644 --- a/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift +++ b/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift @@ -6,7 +6,7 @@ import CoreData public extension CoreData.NSAttributeDescription { - struct TypeConfiguration { + struct TypeConfiguration: Sendable { let attributeType : NSAttributeType let isOptional : Bool let attributeValueClassName : String? From 6f632da7a30cc3b83bd535f461d55e5e159120aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Vacic=CC=81?= Date: Sat, 23 Mar 2024 19:19:18 +0100 Subject: [PATCH 3/8] Minor re-write to avoid concurrency issues. --- .../NSPropertyDescription+Data.swift | 21 +++++------ .../NSRelationshipDescription+Data.swift | 36 ++++++++++--------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift index 4f3f28a..c314cc7 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift @@ -3,29 +3,30 @@ // Copyright © 2023 ZeeZide GmbH. // -private var _propertyIsUniqueAssociatedKey: UInt8 = 42 - extension NSPropertyDescription { - + private struct AssociatedKeys { + nonisolated(unsafe) static var propertyIsUniqueAssociatedKey: Void? = nil + } + public internal(set) var isUnique: Bool { // Note: isUnique is only used during schema construction! set { if newValue { - objc_setAssociatedObject(self, &_propertyIsUniqueAssociatedKey, + objc_setAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey, type(of: self), .OBJC_ASSOCIATION_ASSIGN) } else { - objc_setAssociatedObject(self, &_propertyIsUniqueAssociatedKey, nil, .OBJC_ASSOCIATION_RETAIN) + objc_setAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey, nil, .OBJC_ASSOCIATION_RETAIN) } - #if false // do we need this? The entity might not yet be setup? +#if false // do we need this? The entity might not yet be setup? guard !entity.isPropertyUnique(self) else { return } entity.uniquenessConstraints.append( [ self ]) - #endif +#endif } get { - objc_getAssociatedObject(self, &_propertyIsUniqueAssociatedKey) != nil - ? true - : entity.isPropertyUnique(self) + objc_getAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey) != nil + ? true + : entity.isPropertyUnique(self) } } } diff --git a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift index f4264f5..43f3510 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift @@ -13,9 +13,9 @@ extension CoreData.NSRelationshipDescription { extension CoreData.NSRelationshipDescription: SchemaProperty {} public extension CoreData.NSRelationshipDescription { - + @inlinable var isToOneRelationship : Bool { !isToMany } - + @inlinable var isAttribute : Bool { return false } @inlinable var isRelationship : Bool { return true } @@ -109,7 +109,7 @@ extension CoreData.NSRelationshipDescription { // MARK: - Initializer public extension CoreData.NSRelationshipDescription { - + // Note: This matches what the `Relationship` macro takes. convenience init(_ options: Option..., deleteRule: NSDeleteRule = .nullify, minimumModelCount: Int? = 0, maximumModelCount: Int? = 0, @@ -122,16 +122,16 @@ public extension CoreData.NSRelationshipDescription { precondition(minimumModelCount ?? 0 >= 0) precondition(maximumModelCount ?? 0 >= 0) self.init() - + self.name = name ?? "" self.valueType = valueType self.renamingIdentifier = originalName ?? "" self.versionHashModifier = hashModifier self.deleteRule = deleteRule self.inverseKeyPath = inverse - + if options.contains(.unique) { isUnique = true } - + if let minimumModelCount { self.minCount = minimumModelCount } if let maximumModelCount { self.maxCount = maximumModelCount @@ -140,8 +140,8 @@ public extension CoreData.NSRelationshipDescription { if valueType is any RelationshipCollection.Type { self.maxCount = 0 } - else if valueType is NSOrderedSet.Type || - valueType is Optional.Type + else if valueType is NSOrderedSet.Type || + valueType is Optional.Type { self.maxCount = 0 } @@ -155,10 +155,8 @@ public extension CoreData.NSRelationshipDescription { // MARK: - Storage -private var _relationshipInfoAssociatedKey: UInt8 = 72 - extension CoreData.NSRelationshipDescription { - + func internalCopy() -> Self { guard let copy = self.copy() as? Self else { fatalError("Could not copy relationship \(self)") @@ -187,7 +185,7 @@ extension CoreData.NSRelationshipDescription { var inverseName : String? var destination : String? var isToOneRelationship : Bool? - + override func copy() -> Any { internalCopy() } func internalCopy() -> MacroInfo { @@ -201,10 +199,14 @@ extension CoreData.NSRelationshipDescription { return copy } } - + + private struct AssociatedKeys { + nonisolated(unsafe) static var relationshipInfoAssociatedKey: Void? = nil + } + var writableRelationshipInfo : MacroInfo { if let info = - objc_getAssociatedObject(self, &_relationshipInfoAssociatedKey) + objc_getAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey) as? MacroInfo { return info @@ -214,15 +216,15 @@ extension CoreData.NSRelationshipDescription { self.relationshipInfo = info return info } - + var relationshipInfo: MacroInfo? { // Note: isUnique is only used during schema construction! set { - objc_setAssociatedObject(self, &_relationshipInfoAssociatedKey, + objc_setAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey, newValue, .OBJC_ASSOCIATION_RETAIN) } get { - objc_getAssociatedObject(self, &_relationshipInfoAssociatedKey) + objc_getAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey) as? MacroInfo } } From 7ce2bfb659519fa0b5c67b99a8e6ac4c0bfa0f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Vacic=CC=81?= Date: Sat, 23 Mar 2024 19:45:34 +0100 Subject: [PATCH 4/8] Hm...kind of squint and pretend all is fine. --- .../SchemaCompatibility/NSManagedObjectModel+Data.swift | 4 ++-- Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift index d42b2c4..23231e0 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift @@ -37,8 +37,8 @@ public extension NSManagedObjectModel { // MARK: - Cached ManagedObjectModels private let lock = NSLock() -private var map = [ Set : NSManagedObjectModel ]() -private let sharedBuilder = SchemaBuilder() +nonisolated(unsafe) private var map = [ Set : NSManagedObjectModel ]() +nonisolated(unsafe) private let sharedBuilder = SchemaBuilder() public extension NSManagedObjectModel { diff --git a/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift b/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift index c8e5a89..9ff8195 100644 --- a/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift +++ b/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift @@ -113,7 +113,7 @@ public extension Scene { // MARK: - Primitive // Note: The docs say that a container is only ever created once! So cache it. -private var modelToContainer = [ ObjectIdentifier: NSPersistentContainer ]() +nonisolated(unsafe) private var modelToContainer = [ ObjectIdentifier: NSPersistentContainer ]() private func makeModelContainer( for modelTypes : [ any PersistentModel.Type ], From c9d363a83236f9692ae91e5ee0c1a195b63339ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Vacic=CC=81?= Date: Sat, 23 Mar 2024 21:24:43 +0100 Subject: [PATCH 5/8] Another close your eyes and pretend all is fine Is this is not Sendable then static let schemaMetadata on each Model object will error out in Swift 6. But this can't be truly Sendable because of AnyKeyPath. --- Sources/ManagedModels/PersistentModel/PropertyMetadata.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/ManagedModels/PersistentModel/PropertyMetadata.swift b/Sources/ManagedModels/PersistentModel/PropertyMetadata.swift index d7692b0..5551ad1 100644 --- a/Sources/ManagedModels/PersistentModel/PropertyMetadata.swift +++ b/Sources/ManagedModels/PersistentModel/PropertyMetadata.swift @@ -13,7 +13,7 @@ public extension NSManagedObjectModel { * All (code defined) properties of the ``NSManagedObjectModel`` are stored * in the `schemaMetadata` static property. */ - struct PropertyMetadata { + struct PropertyMetadata: @unchecked Sendable { /// The name of the property instance variable, e.g. `street`. public let name : String From c5e69c582a9355ddd5f1dc4bfdce7f91c3a1cd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helge=20He=C3=9F?= Date: Sun, 24 Mar 2024 12:44:28 +0100 Subject: [PATCH 6/8] Fix indent Tabs. --- .../CoreDataPrimitiveValue.swift | 2 +- .../NSPropertyDescription+Data.swift | 18 ++++++++++++++---- .../NSRelationshipDescription+Data.swift | 18 ++++++++++-------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift b/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift index 46ece1f..b84feb5 100644 --- a/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift +++ b/Sources/ManagedModels/SchemaCompatibility/CoreDataPrimitiveValue.swift @@ -6,7 +6,7 @@ import CoreData public extension CoreData.NSAttributeDescription { - struct TypeConfiguration: Sendable { + struct TypeConfiguration: Sendable { let attributeType : NSAttributeType let isOptional : Bool let attributeValueClassName : String? diff --git a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift index c314cc7..5a46b18 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift @@ -12,11 +12,18 @@ extension NSPropertyDescription { // Note: isUnique is only used during schema construction! set { if newValue { - objc_setAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey, - type(of: self), .OBJC_ASSOCIATION_ASSIGN) + objc_setAssociatedObject( + self, &AssociatedKeys.propertyIsUniqueAssociatedKey, + type(of: self), // Just used as a flag, type won't go away + .OBJC_ASSOCIATION_ASSIGN + ) } else { - objc_setAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey, nil, .OBJC_ASSOCIATION_RETAIN) + objc_setAssociatedObject( + self, &AssociatedKeys.propertyIsUniqueAssociatedKey, + nil, // clear // clear flag + .OBJC_ASSOCIATION_ASSIGN + ) } #if false // do we need this? The entity might not yet be setup? guard !entity.isPropertyUnique(self) else { return } @@ -24,7 +31,10 @@ extension NSPropertyDescription { #endif } get { - objc_getAssociatedObject(self, &AssociatedKeys.propertyIsUniqueAssociatedKey) != nil + objc_getAssociatedObject( + self, + &AssociatedKeys.propertyIsUniqueAssociatedKey + ) != nil ? true : entity.isPropertyUnique(self) } diff --git a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift index 43f3510..8f74f2a 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift @@ -141,7 +141,7 @@ public extension CoreData.NSRelationshipDescription { self.maxCount = 0 } else if valueType is NSOrderedSet.Type || - valueType is Optional.Type + valueType is Optional.Type { self.maxCount = 0 } @@ -205,9 +205,8 @@ extension CoreData.NSRelationshipDescription { } var writableRelationshipInfo : MacroInfo { - if let info = - objc_getAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey) - as? MacroInfo + if let info = objc_getAssociatedObject( + self, &AssociatedKeys.relationshipInfoAssociatedKey) as? MacroInfo { return info } @@ -220,12 +219,15 @@ extension CoreData.NSRelationshipDescription { var relationshipInfo: MacroInfo? { // Note: isUnique is only used during schema construction! set { - objc_setAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey, - newValue, .OBJC_ASSOCIATION_RETAIN) + objc_setAssociatedObject( + self, &AssociatedKeys.relationshipInfoAssociatedKey, + newValue, .OBJC_ASSOCIATION_RETAIN + ) } get { - objc_getAssociatedObject(self, &AssociatedKeys.relationshipInfoAssociatedKey) - as? MacroInfo + objc_getAssociatedObject( + self, &AssociatedKeys.relationshipInfoAssociatedKey + ) as? MacroInfo } } } From 72287ccbe5c8be6098884065085fa0a9327575b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helge=20He=C3=9F?= Date: Sun, 24 Mar 2024 12:56:25 +0100 Subject: [PATCH 7/8] Use proper main actor isolation for modelToContainer Only backing SwiftUI modifiers, aka main. --- .../ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift b/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift index 9ff8195..5d7437e 100644 --- a/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift +++ b/Sources/ManagedModels/SwiftUI/ModelContainer+SwiftUI.swift @@ -25,6 +25,7 @@ public extension View { self.modelContext(container.viewContext) } + @MainActor @ViewBuilder func modelContainer( for modelTypes : [ any PersistentModel.Type ], @@ -48,6 +49,7 @@ public extension View { } } + @MainActor @inlinable func modelContainer( for modelType : any PersistentModel.Type, @@ -73,6 +75,7 @@ public extension Scene { self.modelContext(container.viewContext) } + @MainActor @SceneBuilder func modelContainer( for modelTypes : [ any PersistentModel.Type ], @@ -92,6 +95,7 @@ public extension Scene { self.modelContainer(try! result.get()) } + @MainActor @inlinable func modelContainer( for modelType : any PersistentModel.Type, @@ -113,8 +117,10 @@ public extension Scene { // MARK: - Primitive // Note: The docs say that a container is only ever created once! So cache it. -nonisolated(unsafe) private var modelToContainer = [ ObjectIdentifier: NSPersistentContainer ]() +@MainActor +private var modelToContainer = [ ObjectIdentifier: NSPersistentContainer ]() +@MainActor private func makeModelContainer( for modelTypes : [ any PersistentModel.Type ], inMemory : Bool = false, From 054aef47ab0de763483d607565197b5512062c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Helge=20He=C3=9F?= Date: Sun, 24 Mar 2024 13:26:24 +0100 Subject: [PATCH 8/8] Fix Swift 5.9 build 5.10 not available on GH yet. Disabled concurrency checks, given that they are not fully supported in 5.9 yet. --- Package.swift | 12 ++++++++---- .../NSManagedObjectModel+Data.swift | 8 +++++++- .../NSPropertyDescription+Data.swift | 4 ++++ .../NSRelationshipDescription+Data.swift | 4 ++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index e42bcf4..25afafc 100644 --- a/Package.swift +++ b/Package.swift @@ -2,6 +2,12 @@ import PackageDescription import CompilerPluginSupport +#if swift(>=5.10) +let settings = [ .enableExperimentalFeature("StrictConcurrency") ] +#else +let settings = [ SwiftSetting ]() +#endif + let package = Package( name: "ManagedModels", @@ -16,11 +22,9 @@ let package = Package( .target( name: "ManagedModels", dependencies: [ "ManagedModelMacros" ], - swiftSettings: [ - .enableExperimentalFeature("StrictConcurrency") - ] + swiftSettings: settings ), - + .macro( name: "ManagedModelMacros", dependencies: [ diff --git a/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift index 23231e0..00cdf2c 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSManagedObjectModel+Data.swift @@ -37,8 +37,14 @@ public extension NSManagedObjectModel { // MARK: - Cached ManagedObjectModels private let lock = NSLock() -nonisolated(unsafe) private var map = [ Set : NSManagedObjectModel ]() +#if swift(>=5.10) +nonisolated(unsafe) +private var map = [ Set : NSManagedObjectModel ]() nonisolated(unsafe) private let sharedBuilder = SchemaBuilder() +#else // 5.9: nonisolated(unsafe) not available, nonisolated nor working on var +private var map = [ Set : NSManagedObjectModel ]() +nonisolated private let sharedBuilder = SchemaBuilder() +#endif public extension NSManagedObjectModel { diff --git a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift index 5a46b18..b4365fa 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSPropertyDescription+Data.swift @@ -5,7 +5,11 @@ extension NSPropertyDescription { private struct AssociatedKeys { + #if swift(>=5.10) nonisolated(unsafe) static var propertyIsUniqueAssociatedKey: Void? = nil + #else // 5.9: nonisolated(unsafe) not available + static var propertyIsUniqueAssociatedKey: Void? = nil + #endif } public internal(set) var isUnique: Bool { diff --git a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift index 8f74f2a..c47ee9c 100644 --- a/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift +++ b/Sources/ManagedModels/SchemaCompatibility/NSRelationshipDescription+Data.swift @@ -201,7 +201,11 @@ extension CoreData.NSRelationshipDescription { } private struct AssociatedKeys { + #if swift(>=5.10) nonisolated(unsafe) static var relationshipInfoAssociatedKey: Void? = nil + #else // 5.9: nonisolated(unsafe) not available + static var relationshipInfoAssociatedKey: Void? = nil + #endif } var writableRelationshipInfo : MacroInfo {