From 740f7903fd09af84a224b2814243d46ba1733486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=87=E6=B6=9B?= Date: Thu, 15 May 2025 15:40:48 +0800 Subject: [PATCH 1/3] Add description by parameter-packs after swift5.9 That's a classic situation for using `each T` --- ...DescribingCoreDataEntity+EntityDescription.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Sources/ProgrammaticCoreData/SelfDescribingCoreDataEntity+EntityDescription.swift b/Sources/ProgrammaticCoreData/SelfDescribingCoreDataEntity+EntityDescription.swift index d79a4eb..c207703 100644 --- a/Sources/ProgrammaticCoreData/SelfDescribingCoreDataEntity+EntityDescription.swift +++ b/Sources/ProgrammaticCoreData/SelfDescribingCoreDataEntity+EntityDescription.swift @@ -21,6 +21,19 @@ public extension SelfDescribingCoreDataEntity { ) } + #if swift(>=5.9) + // even more than A24... + static func description( + _ parameters: repeat EntityDescriptionAttribute + ) -> NSEntityDescription { + var properties: [NSPropertyDescription] = [] + for para in repeat each parameters { + properties.append(para.nsPropertyDescription) + } + return NSEntityDescription(Self.self, properties: properties) + } + #endif + static func description( _ a0: EntityDescriptionAttribute, _ a1: EntityDescriptionAttribute, From e4d7ea27e6de3bdedb8de087d8ff74a7e43e8c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=87=E6=B6=9B?= Date: Thu, 15 May 2025 15:56:39 +0800 Subject: [PATCH 2/3] Add sync-version of NSPersistentContainer.create for normal call. --- .../NSPersistentContainer+Extensions.swift | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Sources/ProgrammaticCoreData/NSPersistentContainer+Extensions.swift b/Sources/ProgrammaticCoreData/NSPersistentContainer+Extensions.swift index 343cc42..4d4bc1e 100644 --- a/Sources/ProgrammaticCoreData/NSPersistentContainer+Extensions.swift +++ b/Sources/ProgrammaticCoreData/NSPersistentContainer+Extensions.swift @@ -89,4 +89,29 @@ public extension NSPersistentContainer { try await container.loadPersistentStores() return container } + + static func createSync( + name: String, + model: NSManagedObjectModel, + location: Location + ) throws -> NSPersistentContainer { + let container: NSPersistentContainer + switch location { + case .cloud(let cloudContainerIdentifier, let options): + container = try model.createCloudContainer( + name: name, + cloudContainerIdentifier: cloudContainerIdentifier, + options: options + ) + case .local(let subdirectory): + container = try model.createLocalContainer(name: name, subdirectory: subdirectory) + case .inMemory: + container = try model.createInMemoryContainer(name: name) + } + var callback: (desc: NSPersistentStoreDescription?, error: (any Error)?) = (nil, nil) + container.loadPersistentStores { callback = ($0, $1) } + if let desc = callback.desc { debugPrint("[createSync]", desc) } + if let error = callback.error { throw error } + return container + } } From 81379931e07a4021380e423b9cfe2478837ce91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=87=E6=B6=9B?= Date: Thu, 15 May 2025 15:58:29 +0800 Subject: [PATCH 3/3] Mod NSManagedObjectModel.createLocalContainer Be lazy to type names, provide a basically unique prefix for naming. --- .../NSManagedObjectModel+Extensions.swift | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Sources/ProgrammaticCoreData/NSManagedObjectModel+Extensions.swift b/Sources/ProgrammaticCoreData/NSManagedObjectModel+Extensions.swift index 68a775c..537a788 100644 --- a/Sources/ProgrammaticCoreData/NSManagedObjectModel+Extensions.swift +++ b/Sources/ProgrammaticCoreData/NSManagedObjectModel+Extensions.swift @@ -33,6 +33,17 @@ public extension NSManagedObjectModel { ) } + func createContainerSync( + name: String? = nil, + location: NSPersistentContainer.Location + ) throws -> NSPersistentContainer { + try NSPersistentContainer.createSync( + name: prefixName(name), + model: self, + location: location + ) + } + func createCloudContainer( name: String, cloudContainerIdentifier: String, @@ -45,13 +56,13 @@ public extension NSManagedObjectModel { options: options ) } - - func createLocalContainer(name: String, path: URL) -> NSPersistentContainer { - NSPersistentContainer(name: name, managedObjectModel: self, path: path) + + func createLocalContainer(name: String? = nil, path: URL) -> NSPersistentContainer { + NSPersistentContainer(name: prefixName(name), managedObjectModel: self, path: path) } - func createLocalContainer(name: String, subdirectory: String?) throws -> NSPersistentContainer { - try NSPersistentContainer(name: name, managedObjectModel: self, subdirecotry: subdirectory) + func createLocalContainer(name: String? = nil, subdirectory: String?) throws -> NSPersistentContainer { + try NSPersistentContainer(name: prefixName(name), managedObjectModel: self, subdirecotry: subdirectory) } func createInMemoryContainer(name: String) throws -> NSPersistentContainer { @@ -61,4 +72,13 @@ public extension NSManagedObjectModel { container.persistentStoreDescriptions = [description] return container } + + /// Be lazy to type names, provide a basically unique prefix for naming. + func prefixName(_ name: String?) -> String { + if let name = name { name } else { + Self.prefix + String(describing: Self.self) + } + } + + private static let prefix: String = "ProgrammaticCoreData." }