1

I mean I want to know that is it possible to use CoreData which shares a common resource?

Sti
  • 8,275
  • 9
  • 62
  • 124
user3745635
  • 847
  • 1
  • 8
  • 21

2 Answers2

1

You have the options of sharing the SQLite and user default between your main app and the widgets.

If you want the SQLite to be shared between the Main App and the widget, please follow the steps.

  1. create an app group. Click on the main project -> Capabilities -> App Group -> create a group.. example: group.com.appname.appgroup

  2. While creating the persistent coordinator, create an SQLite file in the app group and provide the path.

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
    // Create the coordinator and store
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.appname.appgroup")!
    let url = directory.appendingPathComponent("somename.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption:true,NSInferMappingModelAutomaticallyOption:true])
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
        dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
        return coordinator}()
    
  3. You can access the core data in widgets like the way you use in main app.

If you want to use the user defaults, then follow the below steps.

  1. create a user deafult object.

    var userDefaults = UserDefaults(suiteName:"group.com.appname.appgroup")!

  2. use this object for setting and retrieving the values.
Kumar Reddy
  • 792
  • 6
  • 15
1

You can share data between extensions and the host app via Keychain Sharing and App Groups (needs to be configured in the capabilities of your target).

Example for Keychain Sharing with KeychainAccess:

import KeychainAccess

let sharedKeychain = Keychain(service: "com.company.App.shared" , accessGroup: "TeamId.App")
sharedKeychain?["username"] = "Test"

Example for User Defaults:

var userDefaults = UserDefaults(suiteName: "group.com.company.App")!

Example for data in App Group:

let fileUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.company.App")!

To share data via CoreData just put the database file into the App Group storage.

Example with CoreStore:

import CoreStore

let dataStack: DataStack = {
    let dataStack = DataStack(xcodeModelName: "App")
    let storagePathUrl = fileUrl.appendingPathComponent("App.sqlite")
    do {
        try dataStack.addStorageAndWait(SQLiteStore(fileURL: storagePathUrl, configuration: "Default", localStorageOptions: .
            recreateStoreOnModelMismatch))
    } catch let error {
        print("Cannot set up database storage: \(error)")
    }
    return dataStack
}()
sundance
  • 2,930
  • 1
  • 20
  • 25