CDShare 0.1.2

CDShare 0.1.2

Maintained by Voda Ion.



CDShare 0.1.2

CDShare

CI Status Version License Platform

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Requirements

iOS 11.0+ 
Xcode 10

Installation

CDShare is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'CDShare'

Usage

This work was inspired by how Apple iWork office suite applications work in iOS and a specific feature of how the documents are sharing between apps even in offline mode.

CDShare will answer the question:
How do we share CoreData between 2*n application, where n >= 1?

Before to go direct to the subject, let's have a short introduction for each part that is touched in this tutorial.

What is CoreData?

CoreData is a framework created by Apple, is used for object layer modeling management. It provides a general solution for functions associated with the object lifecycle, object management, and persistence. What should be mentioned in this framework are the following classes:

NSPersitentStoreCoordinator / NSPersitentStoreContainer
NSManagedObjectModel
NSManagedObjectContext
NSManagedObject

alt tag alt tag

iOS Application structure:

In order to share CoreData between 2*n applications, we have some impediments.

In iOS, each application is totally isolated from other applications through a Sandbox. This was intentionally done by Apple for security reasons. The limits are interprocess communication and accessing directories/files between applications. Normally you do not have access to the other applications directory structure, outside of the application running process.

Application directory structure with iCloud:

alt tag

Application directory structure without iCloud:

alt tag

App Group

You do have the support of accessing and communicate between applications if the applications are in the same App Group.

Each application when is running in a separate process, even if the applications are part of the same App Group, they do not access each other's directories, but they have access to the Shared Container that has a Sandbox-like directory structure.

Process structure between Applications

alt tag

First of all, you need to create App Group for your application. Go to Apple Developer Member Center and register App Group. Fill the description and identifier and follow the instructions.

alt tag alt tag alt tag

After that when you will create an identifier for an application or an extension, don’t forget to enable the service App Groups.

alt tag

Then go to the application or the extension and edit services. It’s really simple, see the next screenshots:

alt tag alt tag alt tag alt tag alt tag alt tag alt tag alt tag

It’s all settings, now open the Xcode and let’s go to write code. In the Xcode for the each target enable App Groups in target settings.

alt tag alt tag

And please, perform this procedure for all applications or extensions of the App Group.

CDShare Logic

A folder will be created in the Shared Container, in that folder the SQLite files will be saved and for each application will be created a sub-folder, the sub-folder name will be the bundle ID of each application. In these folders, we will save files with a unique name in which they will contain the payload received in the notification with the name .CoreDataSaveNotification.

FolderWatcher is one of the key components in the CDShare.framework. For each application, we will have a FolderWatcher, the readingEndpoint we will receive events from each application each time one of the application will write anything in that folder. For each event will we will process all the files that we did write in that folder. For each application, we will handle CoreData notification .CoreDataSaveNotification, if notification contain any changes of the models that we are interest with .sharedInScopeEntityNames then, that notification will be saved in the writing folders as a file with a unique name, The writing event will fire a reading event in each other applications. After reading and merging in the applications the new changes the files are deleted. alt tag

iOS Application states

Applications in IOS have 5 states, these states are shown in the schematic below:
alt tag
FolderWatcher will work as long as the application is active when it enters the background, fileDescriptor EventHandler is put in a queue when the application will come in the active state, events from the queue will be fired. The fileDescriptor does it automatically you do not have to make any extra handlers.

Example description

Under the Example folder, you will find a project of how to use the CDShare.framework. The project will contain a showcase for an Application and an Extension for it and they will share the CoreData.

The example will be based on another tutorial that you can find here.

The logic of the framework looks like this:

  1. Create a class/struct that implement ApplicationGroupInfo protocol.
struct ApplicationGroupInfoModel: ApplicationGroupInfo {
    var group: ApplicationIdentifier = ApplicationIdentifierModel(identifier: "group.voda.the.cdshare")
    var reading: ApplicationIdentifier = ApplicationIdentifierModel(identifier: "com.CDShareExample")
    var writing: [ApplicationIdentifier] = [ApplicationIdentifierModel(identifier: "com.CDShareExample.CDShareExampleToday")]
}

You can have diferent context for reading and writing, for the sake of the example I did use the same context.

Each parameter of the ApplicationGroupInfo protocol require to be descedent of the ApplicationIdentifier protocol.

struct ApplicationIdentifierModel: ApplicationIdentifier {
    var identifier: String
}
  1. Create the CoreDataShareConfiguration instance.
let context: NSManagedObjectContext = ...
let configuration = try! CoreDataShareConfiguration(ApplicationGroupInfoModel(), readingContext: context, writingContext: context)
  1. Create CoreDataShare instance.
let coreDataShare = try! CoreDataShare(configuration: configuration, viewContext: context)
  1. Do not forget to add the class type that you want to update/reload objects in memory.
coreDataShare.sharedInScopeEntityNames = [String(describing: Counter.self)]
  1. Add the notification of .CoreDataShareDidSave:.
let selector = #selector(reloadObjects)
NotificationCenter.default.addObserver(self, selector: selector, name: .CoreDataShareDidSave, object: nil)

Author

vodaion, [email protected]

License

CDShare is available under the MIT license. See the LICENSE file for more info. Application documentation.