Tomasz Nazarenko
Tomasz Nazarenko

Reputation: 1194

How to solve Core Data error: Attempt to add read-only file at path when trying to access Core Data container in the app extension today widget?

I am trying to access a database using Core Data inside a today extension widget.

The function that creates the Core Data container is this:

func createContainer(completion: @escaping (NSPersistentContainer) -> ()) {
    let applicationGroupIdentifier = "group.com.name.exampleApp.sharedContainer"

    guard let newURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: applicationGroupIdentifier)
        else { fatalError("Could not create persistent store URL") }

    let persistentStoreDescription = NSPersistentStoreDescription()

    persistentStoreDescription.url = newURL

    let container = NSPersistentContainer(name: "ContainerName")

    container.persistentStoreDescriptions = [persistentStoreDescription]

    container.loadPersistentStores { (_, error) in
        guard error == nil else { fatalError("Failed to load store:\(String(describing: error))") }
        DispatchQueue.main.async { completion(container) }
    }
}

However, I get the following error:

CoreData: error: Attempt to add read-only file at path file:///private/var/mobile/Containers/Shared/AppGroup/C9324B65B-265C-4264-95DE-B5AC5C9DAFD0/ read/write. Adding it read-only instead. This will be a hard error in the future; you must specify the NSReadOnlyPersistentStoreOption.

If I specify the NSReadOnlyPersistentStoreOption like this:

persistentStoreDescription.isReadOnly = false

I get the error:

Failed to load store:Optional(Error Domain=NSCocoaErrorDomain Code=513 "The file couldn’t be saved because you don’t have permission."):

What might be the cause and the solution?

Upvotes: 4

Views: 2090

Answers (2)

Bendi
Bendi

Reputation: 21

  1. In extension's info.plist set: NSExtension --> NSExtensionAttributes --> RequestOpenAccess --> YES
  2. In Settings on device set: Your app --> (Extension type - eg.: Keyboard) --> Allow Full Access

Upvotes: 2

Fabian
Fabian

Reputation: 5348

Had the same problem and solved it by adding

let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.identifier")!
let url = directory.appendingPathComponent("MyDatabaseName.sqlite")

CoreData probably tried to open the base folder as its sqlite database, which did not go so well.

Adding isReadOnly didn't allow CoreData to repurpose the Folder either :)

Source: https://github.com/maximbilan/iOS-Shared-CoreData-Storage-for-App-Groups

Upvotes: 1

Related Questions