In trying to follow Paul Hudson's guide on pre-populating an app with an existing SwiftData database, I've found an error I'm stuck on, it only appears on a physical device, it works fine in the Simulator. Thanks in advance
I'm seeding the database in one app:
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button("Seed") {
create()
}
}
.padding()
}
func create() {
let container = NSPersistentContainer(name: "Model")
let storeURL = URL.documentsDirectory.appending(path: "Model.store")
if let description = container.persistentStoreDescriptions.first {
try? FileManager.default.removeItem(at: storeURL)
description.url = storeURL
description.setValue("DELETE" as NSObject, forPragmaNamed: "journal_mode")
}
container.loadPersistentStores { description, error in
do {
for _ in 1...100 {
let user = Entity(context: container.viewContext)
user.identifier = UUID().uuidString
container.viewContext.insert(user)
}
try container.viewContext.save()
try? FileManager.default.removeItem(at: URL(filePath: "/Users/engies/Downloads/Model.store"))
let destination = URL(filePath: "/Users/engies/Downloads/Model.store")
try FileManager.default.copyItem(at: storeURL, to: destination)
} catch {
print("Failed to create data: \(error.localizedDescription)")
}
}
}
}
Entity+CoreDataClass.swift
import Foundation
import CoreData
public class Entity: NSManagedObject {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Entity> {
return NSFetchRequest<Entity>(entityName: "Entity")
}
@NSManaged public var identifier: String
}
In the SwiftData App, I get the error when initializing the ModelContainer:
import SwiftUI
import SwiftData
@main
struct TestSeededApp: App {
let container: ModelContainer
var body: some Scene {
WindowGroup {
ContentView()
}
.modelContainer(container)
}
init() {
do {
guard let storeURL = Bundle.main.url(forResource: "Model", withExtension: "store") else {
fatalError("Failed to find users.store")
}
let config = ModelConfiguration(url: storeURL)
container = try ModelContainer(for: Entity.self, configurations: config) // <- Erroring here
} catch {
fatalError("Failed to create model container: \(error)")
}
}
}
The error: NSUnderlyingException=error during SQL execution : attempt to write a readonly database, reason=error during SQL execution : attempt to write a readonly database
Full(ish) error: UserInfo={sourceURL=file:///private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store, reason=Cannot migrate store in-place: error during SQL execution : attempt to write a readonly database, destinationURL=file:///private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store, NSUnderlyingError=0x283df0bd0 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=8, NSFilePath=/private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store, NSUnderlyingException=error during SQL execution : attempt to write a readonly database, reason=error during SQL execution : attempt to write a readonly database}}} with userInfo { NSUnderlyingError = "Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSSQLiteErrorDomain=8, NSFilePath=/private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store, NSUnderlyingException=error during SQL execution : attempt to write a readonly database, reason=error during SQL execution : attempt to write a readonly database}"; destinationURL = "file:///private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store"; reason = "Cannot migrate store in-place: error during SQL execution : attempt to write a readonly database"; sourceURL = "file:///private/var/containers/Bundle/Application/0C1F96BC-D734-4E21-82A0-75BC9C1D6ADD/TestSeeded.app/Model.store"; } TestSeeded/TestSeededApp.swift:28: Fatal error: Failed to create model container: SwiftDataError(_error: SwiftData.SwiftDataError._Error.loadIssueModelContainer)
Found the answer here: How to pre-populate an app with a read-only store located in the app's bundle?
This should probably be marked as duplicate