This post discusses how to use Couchbase Lite as an embedded database to share data between your iOS App and iOS App Extension. App Extensions implement a specific task or functionality that can be exposed to other apps on the device or to the Operating System. In this post, we will walk through an example of how a Today Extension can be used with a Couchbase Lite embedded database in standalone mode.
NOTE: We will be discussing Couchbase Mobile v1.4 which is the current production release. But everything we discuss here applies to the newer Developer Preview version 2.0 of Couchbase Mobile
Background
Apple supports many kinds of App Extensions , each of which enables functionality that is relevant to a particular subsystem on the device. In this post, we will discuss how Couchbase Lite can be used with a Today Extension. This type of extension, also known as a “Widget”, appears in the Today view of the Notification Center and allows users get quick updates. You can learn more about how App Extensions work in the Apple Developer documents.
I’ll assume you’re familiar with developing iOS Apps in Swift and have a basic understanding of integrating Couchbase Lite into your iOS App. This Getting Started guide is a great place to begin. If would like to read up more on Couchbase, refer to the resources at the end of this post.
Couchbase Lite
Couchbase Lite is an embedded database that runs on devices. It can be used in several deployment modes. It can be used as a standalone embedded database or it can be used in conjunction with a remote Sync Gateway that would allow it to sync data across devices. In this post, we will use Couchbase Lite in standalone deployment mode. In this post, we will not go over the details of integrating with Couchbase Lite. The Getting Started With Couchbase Lite blog is a good place to get started on that.
Demo App
- Download the Demo Xcode project from the Github repo . We will use this app as an example in the rest of the blog.
1 |
git clone git@github.com:couchbaselabs/couchbase-mobile-ios-app-extension.git |
- Follow the instructions in the README file to install and run the app
This is a simple Task List app that allows users to add, edit, delete tasks. A user can mark tasks as completed. A Today Extension is bundled with the app that shows the top 2 tasks right in your notification center without the need to open the app. The user can mark tasks as completed right from the notification center.
All tasks are stored in a local Couchbase Lite database. This implies that the Container app and the extension will both need access to the database.
App Architecture
App Extensions are not standalone apps. They are bundled within an App, referred to as a “Container App”. Although App Extensions are bundled in the Container app, they run independent of the Container App in a separate process . App Extensions are launched by other apps that need the extension’s functionality. The App that launches the App Extension is referred to as the “Host App“. The extension’s UI is displayed in the context of the Host App.
Although the Container App and the corresponding extension are independent processes running in their own sandbox, they can share data through a Shared Container.
The Shared Container can be set up by registering a unique App Group and enabling it for for both the container app and the extension. You will learn about setting this up in the next section.
Configuring App Groups
Refer to the Apple Developer Docs to learn more about configuring App Groups in your iOS app
Open the CBLiteApp.xcworkspace of the demo app project that you downloaded.
- Open the “Capabilities” tab of CBLiteApp Container App target . You should see the App Group group.com.example.CBLiteSharedData enabled.

Enabling App Group for App
- Open the “Capabilities” tab of CBLiteTaskExtension target. You should see the same App Group, group.com.example.CBLiteSharedData enabled.

Configuring App group in Extension
Enabling the App Group capabilities for a target adds it to the Entitlements files for the container app and it’s extension.
- In addition , you will have to add the App Groups feature to your App Id registered in the Apple Developer Portal.

Configuring App Group for App in Apple Developer Portal
App Walkthrough
Build and Run the App by choosing the App Target “CBLiteApp”. Now switch to the Today view of the Notification Center
- Add your new Extension Widget to the Today View as shown below
- Switch to the App and add couple of tasks tapping on the “+” button. Switch to the corresponding Today widget. You will notice that the tasks that you added are displayed in the widget.
- Mark a task as “Completed” by tapping on the task. Now switch back to the Container app. You will notice the completion status of the tasks is updated to correspond to actions taken from the Today widget.
- Similarly edits or delete a task in the Container app by swiping the task entry. Switch to the Today widget. You will see the updated task list.
- If your device supports 3D Touch, you can do a force touch on the app icon on home screen to reveal the Top Tasks extension right there from the icon and you can interact with it. Pretty cool !
- Finally, terminate the Container App. Switch to the Today Widget and update the Completed status of a task. Relaunch the app. The tasks will be listed with the updated status.
Code Walkthrough
Tasks are stored in a local Couchbase Lite embedded database. This implies that both the container app and the Today Extension need access to the database. As discussed earlier, the way to share data between the container app and the extension is through the Shared Container. This implies that the Couchbase Lite database must be located in the Shared Container.
The code to enable this is straightforward.
Open the DatabaseManager.swift file.
The DatabaseManager is a singleton class that handles basic database management functions.
- Locate appGroupContainerURL function
This function constructs the path to the shared container folder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// 1. Get URL to shared group container let fileManager = FileManager.default guard let groupURL = fileManager .containerURL(forSecurityApplicationGroupIdentifier: "group.com.example.CBLiteSharedData") else { return nil } let storagePathUrl = groupURL.appendingPathComponent("CBLite") let storagePath = storagePathUrl.path // 2: Create a folder in the shared container location with name"CBLite" if !fileManager.fileExists(atPath: storagePath) { do { try fileManager.createDirectory(atPath: storagePath, withIntermediateDirectories: false, attributes: nil) } catch let error { print("error creating filepath: \(error)") return nil } } return storagePathUrl |
- Return the URL to the shared group container. Group containers are stored in ~/Library/Group Containers/<application-group-id>
- Create a folder named CBLite in the shared group container.
- Locate configureCBManagerForSharedData function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
do { // 1. Set the file protection mode for the Couchbase Lite database folder let options = CBLManagerOptions(readOnly: false, fileProtection: Data.WritingOptions.completeFileProtectionUnlessOpen) let cblpoptions = UnsafeMutablePointer<CBLManagerOptions>.allocate(capacity: 1) cblpoptions.initialize(to: options) if let url = self.appGroupContainerURL() { // 2. Initialize the CBLManager with the directory of the shared container _cbManager = try CBLManager.init(directory: url.relativePath, options: cblpoptions) } return true } catch { return false } |
- Create CBLManagerOptions options object with the appropriate file protections. A value of completeFileProtectionUnlessOpen implies that read/write access to the file is restricted unless file is open
- Initialize the CBLManager with the path to the shared container. When the database is created, it will be created in the shared container.That’s it! The Couchbase Lite database is now in the Shared Container that both the App and the Extension can read and write to.
What Next?
Explore the rest of the demo sample code to understand how documents are added, edited and deleted. Specifically look at the TaskPresenter.swift file. This is where all the interactions with the Couchbase Lite database is handled.
If you have any questions, feel free to reach out to me on Twitter. If you would like to suggest improvements, submit a pull request to the GitHub repo. You can learn more about integrating with Couchbase Lite in this Getting started with Couchbase Lite blog. The Couchbase Forums are another great place to post your questions.
While this post discusses the use of Couchbase Lite in standalone mode, stay tuned for an upcoming post that will enhance the capability to include synchronization with the cloud.