I have two versionedSchema V1VersionedSchema, V2VersionedSchema.
When i create schema with versionedSchema like code below and check version using breakpoint, V1, V2 Schema encodingVersion is same.
let v3Schema = Schema(versionedSchema: V1VersionedSchema.self)
// encodingVersion: 1.0.0
// schemaEncodingVersion: 1.0.0
let v2Schema = Schema(versionedSchema: V2VersionedSchema.self)
// encodingVersion: 1.0.0
// schemaEncodingVersion: 2.0.0
Why encoding version is same? (I think migration plan v1 to v2 isn't work becaus of that)
Post
Replies
Boosts
Views
Activity
I have v3 models in coredata (model: Event, Lecture), and make new model in v4 with swiftdata but model name, property is different (model: EventModel, LectureModel).
For migration, I add V3Schema, V4Schema and MigrationPlan.
enum V4Schema: VersionedSchema {
static var models: [any PersistentModel.Type] = [LectureModel.self, EventModel.self ]
static var versionIdentifier = Schema.Version(4, 0, 0)
}
enum V3Schema: VersionedSchema {
static var models: [any PersistentModel.Type] = [Event.self, Lecture.self]
static var versionIdentifier = Schema.Version(3, 5, 2)
}
enum ModelMigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] = [V3Schema.self, V4Schema.self]
static var stages: [MigrationStage] = [migrateV3ToV4]
}
extension ModelMigrationPlan {
static let migrateV3ToV4 = MigrationStage.custom(fromVersion: V3Schema.self,
toVersion: V4Schema.self,
willMigrate: willMigrate,
didMigrate: { _ in Log.debug(message: "Migration Complete") })
}
private func willMigrate(context: ModelContext) throws {
try migrateLectures(context: context)
try migrateEvents(context: context)
try context.save()
}
private func migrateEventTypes(context: ModelContext) throws {
// create new v4 event model using v3 event model.
}
private func migrateLectures(context: ModelContext) throws {
// create new v4 lecture model using v3 lecture model.
}
static let release: ModelContainer = {
let v4Schema = Schema(V4Schema.models)
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "app group id")
let databaseURL = containerURL?.appending(path: "**.sqlite")
let configuration = ModelConfiguration("**",
schema: v4Schema,
url: databaseURL!,
cloudKitDatabase: .private("**"))
#if DEBUG
do {
try autoreleasepool {
let desc = NSPersistentStoreDescription(url: configuration.url)
let opts = NSPersistentCloudKitContainerOptions(containerIdentifier: configuration.cloudKitContainerIdentifier!)
desc.cloudKitContainerOptions = opts
desc.shouldAddStoreAsynchronously = false
if let model = NSManagedObjectModel.makeManagedObjectModel(for: V4Schema.models) {
let container = NSPersistentCloudKitContainer(name: "**", managedObjectModel: model)
container.persistentStoreDescriptions = [desc]
container.loadPersistentStores(completionHandler: { _, err in
if let err {
Log.error(message: "Store open failed: \(err.localizedDescription)")
}
})
try container.initializeCloudKitSchema()
Log.debug(message: "Initialize Cloudkit Schema")
if let store = container.persistentStoreCoordinator.persistentStores.first {
try container.persistentStoreCoordinator.remove(store)
}
}
}
} catch {
Log.error(message: "Failed: \(error.localizedDescription)")
}
#endif
return try! ModelContainer(for: v4Schema, migrationPlan: ModelMigrationPlan.self, configurations: configuration)
}()
But when I run, I got error message.
CoreData: CloudKit: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _scheduleAutomatedExportWithLabel:activity:completionHandler:]_block_invoke(3508): <NSCloudKitMirroringDelegate: 0x1036b1540> - Finished automatic export - ExportActivity - with result: <NSCloudKitMirroringResult: 0x1035da810> storeIdentifier: ***** success: 0 madeChanges: 0 error: Error Domain=NSCocoaErrorDomain Code=134407 "Request '*****' was cancelled because the store was removed from the coordinator." UserInfo={NSLocalizedFailureReason=Request '****' was cancelled because the store was removed from the coordinator.}
I don't know why store was removed from the coordinator.
Any have solutions?
TabView {
SummaryView()
.toolbar(.hidden, for: .tabBar, .bottomBar)
.tabItem { Text("Title.Summary") }
.tag(TabItems.summary)
CalendarView()
.toolbar(.hidden, for: .tabBar, .bottomBar)
.tabItem { Text("Title.Calendar") }
.tag(TabItems.calendar)
EventTypeView()
.toolbar(.hidden, for: .tabBar, .bottomBar)
.tabItem { Text("Title.EventType") }
.tag(TabItems.group)
LectureView()
.toolbar(.hidden, for: .tabBar, .bottomBar)
.tabItem { Text("Title.Lecture") }
.tag(TabItems.lecture)
NotificationView()
.toolbar(.hidden, for: .tabBar, .bottomBar)
.tabItem { Text("Title.Notifications") }
.tag(TabItems.notification)
}
Tabbar is hidden when first opened but tabbar is appeared when I change tab selection.
I tested it on iOS 17.1, iOS 17.4, and this bug is only appeared in iOS 17.4.
I use SwiftData, CloudKit, and App Groups. An error occurs on the first run, but it works on the second run.
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate tearDown:]_block_invoke(792): <NSCloudKitMirroringDelegate: 0x12df73750>: Told to tear down with reason: Store Removed
error: CoreData+CloudKit: -[NSCloudKitMirroringDelegate _performSetupRequest:]_block_invoke(1192): <NSCloudKitMirroringDelegate: 0x12df73750>: Failed to set up CloudKit integration for store: (null)
Error Domain=NSCocoaErrorDomain Code=134060 "" UserInfo={NSLocalizedFailureReason=The mirroring delegate could not initialize because it's store was removed from the coordinator.}
I don't know why store path is null in error message.
I passed the store url and CloudKit database name in ModelConfiguration.
static var release: ModelContainer = {
do {
let schema = Schema(versionedSchema: ModelSchema.self)
let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group-identifier")
let databaseURL = appGroupURL?.appending(path: "Database.sqlite")
let databaseName = "Database"
let configuration = ModelConfiguration(schema: schema,
url: databaseURL!,
cloudKitDatabase: .private("iCloud.database.name"))
return try ModelContainer(for: schema,
migrationPlan: ModelMigrationPlan.self,
configurations: [configuration])
} catch {
fatalError(error.localizedDescription)
}
}()
I have 2 vesrion schema and Migration plan.
Version 2: Add new properties and Property renamed.
static let release: ModelContainer = {
do {
let schema = Schema(versionedSchema: V2Schema.self)
let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "***")
let databaseURL = appGroupURL?.appending(path: "Models.sqlite")
let databaseName = "Models"
let configuration = ModelConfiguration(databaseName,
schema: schema,
url: databaseURL!,
cloudKitDatabase: .automatic)
return try ModelContainer(for: schema,
migrationPlan: ModelMigrationPlan.self,
configurations: [configuration])
} catch {
fatalError(error.localizedDescription)
}
}()
enum ModelMigrationPlan: SchemaMigrationPlan {
static var schemas: [VersionedSchema.Type] {
[V1Schema.self, V2Schema.self]
}
static var stages: [MigrationStage] {
[v1ToV2MigrationStage]
}
}
When I test migration in UnitTest, It works fine. But In running in device, error is occurred.
error: Store failed to load. <NSPersistentStoreDescription: 0x1077aa330> (type: SQLite, url: file:///private/var/mobile/Containers/Shared/AppGroup/***/Model.sqlite) with error = Error Domain=NSCocoaErrorDomain Code=134504 "Cannot use staged migration with an unknown model version." UserInfo={NSLocalizedDescription=Cannot use staged migration with an unknown model version.} with userInfo {
NSLocalizedDescription = "Cannot use staged migration with an unknown model version.";
}
Has anyone experienced this same problem or know a solution?
I'm using Music Kit in swiftUI and I try to get duration information from MusicPlayer.queue.currentEntry. But I can't find the solution. How can I get Song duration from MusicPlayer.Queue.currentEntry?