Core Data: Sharing data between Apps and their Widgets

App Extensions, introduced with iOS 8, significantly increase our iOS App’s customizable functionality and extended content. App Extensions allow developers to project quick access to their app.

A Widget or a Today Extension, a particular type of App Extension, provides a quick update to users or lets them perform a simple task in their Notification Center’s today view. Widgets are powerful, but they raise an inherent problem: Sharing data between your App and its Widget. This problem is compounded because, by default, since their security domains are different, an App and its extension cannot access the same data.

In order to solve this problem we need to create an App Group.

Create an App Group

An App Group provides a shared bundle that can be used by the app and its extensions as a shared container in which we can store data.

The next following steps show you how to setup an App Group.

  • Step 1. Create the App Group in the Apple Developer Portal. An App Group ID always starts with the word group like group.com.yourdomain.YourAwesomeGroup.
    App Group ID
  • Step 2. Create an App ID (if you don’t have one) for your App and enable App Groups. App Group ID
  • Step 3. Assign the App Group you created in step 1 to your App ID. App Group Id
  • Step 4. Repeat steps 2 and 3 for your App Extension.
  • Step 5. Create (or update if you already have one) a development provisioning profile for your App, so you can enable the needed entitlements. App Group Id
  • Step 6. In the Xcode project of your App, select the Target for your App and go to the Capabilities tab. There, enable App Groups. Do the same in the Target of your App Extension. App Group Id

Now, your app and its extension are ready to share the container, so it’s time to put the data in it.

Put your database in the shared container

When you create a new Xcode project and select the Core Data checkbox, Xcode automatically generates some boilerplate methods in the App Delegate. This code is used at runtime to generate the Core Data stack of your App.

One of the boilerplate methods is the following one:

This method simply returns the URL of the Documents directory in the App bundle.

We need to modify this method to point to the Shared Bundle, using the identifier of the App Group we recently created. Here, the new implementation:

If you are just starting a new App, that’s all you need to do.

Instead, if you already have an App in the AppStore and you are now adding a Widget, you need some additional work. Since your users might have already an Sqlite file in the Documents directory of your App bundle, you must migrate the Sqlite file to the new shared bundle. You need to perform this migration at the first launch of the App update.

Use Core Data in your App Extension

We need to access the shared Sqlite from the App Extension. Unfortunately, the templates provided by Xcode to create a new target for an App Extension do not provide a Core Data checkbox. So, some manual work is involved, this time. This process, nevertheless, is a great opportunity to increase your understanding of Core Data. I recommend taking a look at the Core Data methods in your App Delegate and moving them into a new class. In this way, the App and its extension will share the same source code. I’ll leave this exercise to you.

Share other data

A good reason to use Core Data in the shared container is that Core Data will handle synchronization of the data accesses, avoiding data corruption.

However, Core Data isn’t always the right choice.

For example, you might want to save just few preferences of your App. You can save this type of information using the NSUserDefaults. To access the user defaults, you usually use the class method +standardUserDefaults. Since we have to access the shared container, we need to use a different initializer and pass the App Group identifier to it:

Conclusion

In this iOS 8 Developer Tutorial, we setup an App Group and used it to share a container between an App and its Today extension. This method, which is essential for secure functionality, applies to any type of App extension.

Keep coding and making awesome apps.

Vicente

iOS Consulting | INVASIVECODE

iOS Training | INVASIVECODE

(Visited 162 times, 1 visits today)