{"id":4243,"date":"2017-11-28T09:28:16","date_gmt":"2017-11-28T17:28:16","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=4243"},"modified":"2025-06-13T20:09:26","modified_gmt":"2025-06-14T03:09:26","slug":"sharing-data-ios-app-extensions-sync-capability","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/","title":{"rendered":"Sharing and Syncing Data between iOS Apps and App Extensions across devices"},"content":{"rendered":"<p>This post discusses\u00a0how to use Couchbase Mobile to share data between your iOS App and iOS App Extension across devices. In an earlier <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-lite-with-ios-app-extensions\/\">post<\/a>, we discussed how you can use Couchbase Lite as a standalone, embedded data store to share data between your iOS App and it\u2019s App Extension on the same device. In this post, we will extend that to leverage the Sync Gateway to enable data synchronization across the Apps and the corresponding App Extension across iOS devices.<\/p>\n<p><!--more--><\/p>\n<p>NOTE:\u00a0 We will be using <a href=\"https:\/\/www.couchbase.com\/downloads\/\">Couchbase Lite v1.4.1<\/a> which is the current production release. But everything we discuss here applies to the newer <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/2.0\/whatsnew.html?language=ios\">Developer Preview version 2.0<\/a> of Couchbase Mobile.<\/p>\n<h3 id=\"background\">Background<\/h3>\n<p>I\u2019ll assume you\u2019re familiar with developing iOS Apps in Swift and have a basic understanding of integrating Couchbase Lite into your iOS App. This <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/1.5\/installation\/index.html\">Getting Started guide<\/a> is a great place to begin.<\/p>\n<p>If you haven\u2019t already done so, please read this <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-lite-with-ios-app-extensions\/\">related blog post<\/a> on the basics of App Extensions and how to configure your app to support the same.<\/p>\n<p>As in the earlier post, we will discuss how Couchbase Mobile can be used with a Today Extension. This type of extension, also known as a \u201cWidget\u201d, appears in the Today view of the Notification Center and allows users get quick updates.<\/p>\n<h3 id=\"couchbaselite\">Couchbase Lite<\/h3>\n<p>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 not go over\u00a0the details\u00a0of integrating with\u00a0Couchbase Lite. The\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-lite-embedded-in-ios-app-part1\/\">Getting Started With Couchbase Lite<\/a> blog\u00a0is a good place to get started on that.<\/p>\n<h3 id=\"syncgateway\">Sync Gateway<\/h3>\n<p>The Sync Gateway is an Internet facing component that your mobile apps connect to. It is responsible for data synchronization across the clients, routing and authorization. It can be configured to persist data in a <a href=\"https:\/\/developer.couchbase.com\/documentation\/server\/current\/introduction\/intro.html\">Couchbase Server<\/a>. In this post we will use Couchbase Server in <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/installation\/sync-gateway\/index.html#walrus-mode\">\u201cwalrus\u201d<\/a> mode wherein the data is persisted in-memory. So in other words, in this demo application, our Sync Gateway will not be backed by Couchbase Server. This is suitable for development purposes. In a real world app, you will probably want to persist your data in a server.<\/p>\n<h2 id=\"sampletasklistapp\">Sample Task List App<\/h2>\n<p>Download the sample project from the Github and switch to <strong><code>syncsupport<\/code> branch<\/strong>.<\/p>\n<pre><code> git clone git@github.com:couchbaselabs\/couchbase-mobile-ios-app-extension.git<\/code><\/pre>\n<pre><code>git checkout syncsupport <\/code><\/pre>\n<p>Our sample app 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.<\/p>\n<p>All tasks are stored in a local Couchbase Lite database and synched with the remote Sync Gateway so changes are made available to apps\/app extensions on other devices.<\/p>\n<p>This implies that the Container app and the extension will both need access to\u00a0the Couchbase Lite database which is synched up with the Sync Gateway.<\/p>\n<h2 id=\"installingrunningsyncgateway\">Installing\/Running Sync Gateway<\/h2>\n<ul>\n<li>First, <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/1.5\/installation\/sync-gateway\/index.html#macos\">download and install<\/a> the Sync<br \/>\n<h2 id=\"installingrunningsyncgateway\" style=\"margin-bottom: 35px\"><\/h2>\n<p>Gateway if you haven\u2019t done so already.<\/li>\n<li>We will Launch the Sync Gateway with the <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-mobile-ios-app-extension\/blob\/syncsupport\/sync-gateway-config.json\">sample configuration file<\/a> that you downloaded from the sample app repo.<\/li>\n<li>Let\u2019s first open and review the contents of <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-mobile-ios-app-extension\/blob\/syncsupport\/sync-gateway-config.json\">sample configuration file<\/a><\/li>\n<\/ul>\n<pre class=\"lang:js decode:true \">{\r\n \"log\": [\"*\"],\r\n \"CORS\": {\r\n \"Origin\":[\"*\"]\r\n },\r\n \"databases\": {\r\n \"demo\": {\r\n      \"server\": \"walrus:\",\r\n      \"bucket\": \"default\",\r\n      \"users\": { \"GUEST\": { \"disabled\": false, \"admin_channels\": [\"*\"] } },\r\n      \"unsupported\": {\r\n         \"user_views\": {\r\n               \"enabled\":true\r\n              }\r\n        }\r\n     }\r\n  }\r\n }<\/pre>\n<p>&nbsp;<\/p>\n<p>Some noteworthy items &#8211;<br \/>\n&#8211; The name of the database is <code>demo<\/code><br \/>\n&#8211; The Sync Gateway is configured to be deployed in <code>walrus<\/code> mode. Note that this is suited only for development purposes.<br \/>\n&#8211; We have enabled <code>guest<\/code> access. Note that this is suited only for development purposes. In a real world application, you should disable guest access.<\/p>\n<ul>\n<li>First, switch to the folder into which you cloned the sample app repo.<\/li>\n<\/ul>\n<pre><code> cd \/path\/to\/couchbase-mobile-ios-app-extension<\/code><\/pre>\n<ul>\n<li>Then launch the Sync Gateway with the config file.<\/li>\n<\/ul>\n<pre><code> \/path\/to\/sync-gateway sync-gateway-config.json<\/code><\/pre>\n<h2 id=\"architecture\">Architecture<\/h2>\n<p>App Extensions are not standalone apps. They are bundled within an App, referred to as a <strong><em>Container App<\/em><\/strong>.\u00a0 Although App Extensions are bundled in the Container app, they run independent of the Container App in a separate process. App Extensions\u00a0are launched by other apps that need the extension\u2019s functionality. The App that launches the App Extension is\u00a0referred to as\u00a0the <strong><em>Host App<\/em><\/strong>.\u00a0 The extension\u2019s UI is displayed in the context of the Host App.<\/p>\n<p>In our sample app, the <code>CBLiteTaskExtension<\/code> is the Today widget type App Extension and <code>CBLiteTaskApp<\/code> is the corresponding container app. The system <code>Notification Center<\/code> is effectively the host app for our App extension.<\/p>\n<p>Although the Container App and the corresponding extension are independent processes running in their own sandbox, they can share data through a <strong><em>Shared Container<\/em>.<\/strong><\/p>\n<p>So this implies that if our Couchbase Lite database is located in the <em>Shared Container<\/em>, that would allow both <code>CBLiteTaskExtension<\/code> and <code>CBLiteTaskApp<\/code> to get access to it. The Couchbase Lite database is then responsible for pushing up changes to the Sync Gateway the usual way regardless of whether the content was locally updated by the App or the Today widget. Likewise, changes pulled in from the Sync Gateway are available to both the App and the Today widget.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/app_extension_sync.png\" alt=\"\" \/><\/figure>\n<h3 id=\"settingupasharedcontainer\">Setting up a Shared Container<\/h3>\n<p>The Shared Container can be set up by registering a unique <strong><em>App Group<\/em><\/strong> and enabling it for use by both the Container App and the corresponding App Extension.<\/p>\n<p>Please review the related <a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-lite-with-ios-app-extensions\/\">post<\/a> on how to configure your app to use <em>\u201cApp Groups\u201d<\/em><\/p>\n<h2 id=\"appwalkthrough\">App Walkthrough<\/h2>\n<ul>\n<li>Open the <code>CBLiteApp.xcworkspace<\/code> using Xcode. Although the app should work on Xcode 8.3 and above, I prefer to use Xcode 9 because it includes support for launching multiple simulators which would come in handy while testing the sync capabilities across devices. So if you have the option, please use Xcode 9.<\/li>\n<li>Build and Run the App on an iOS simulator by choosing the App Target \u201cCBLiteTaskApp\u201d. Now switch to the Today view of the Notification Center<\/li>\n<li>Add your new Extension Widget to the Today View as shown below<\/li>\n<\/ul>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/app_extension_first-1.gif\" alt=\"\" \/><\/p>\n<ul>\n<li>If you are using Xcode 9, launch the app in a second simulator and add the extension widget to the Today View as shown earlier. So now, you have two simulators running the Task List App.<\/li>\n<\/ul>\n<ul>\n<li>On one simulator, using the app, add a couple of tasks tapping on the \u201c+\u201d button.\u00a0You will see it updated in the Today widget of the second simulator in real time. If you are running a single simlator, you can switch to the Today widget on the same device. You will notice that the tasks that you added are displayed in the widget.<\/li>\n<\/ul>\n<figure><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5659 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/app_extension_second-min-compressed.gif\" alt=\"\" width=\"600\" height=\"625\" \/><\/figure>\n<ul>\n<li>Similarly, on one simulator, mark tasks as \u201ccompleted\u201d via the Today widget.\u00a0You will see the status being updated in the corresponding app on the second simulator in real time. If you are running a single simlator, you can switch to the app on the same device. You will notice that the completion status of the<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5656 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2018\/08\/app_extension_third-min-compressed.gif\" alt=\"\" width=\"600\" height=\"619\" \/><\/p>\n<ul>\n<li>Now, we will add a task to the Sync Gateway via the Sync Gateway\u2019s <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/1.5\/references\/sync-gateway\/index.html\">REST API<\/a>. You will see the new task show up in both the app and the today widget on both simulators all in real time! Pretty cool!<\/li>\n<\/ul>\n<p>You can use any HTTP client to make the REST API calls to update a document on the Sync Gateway. But I will use Postman.<\/p>\n<ul>\n<li>Open a terminal and type in the following curl command that adds a task named \u201ctask3\u201d to the database<\/li>\n<\/ul>\n<pre><code> curl -X PUT https:\/\/localhost:4984\/demo\/task3 \r\n -H 'accept: application\/json' \r\n -H 'cache-control: no-cache' \r\n -H 'content-type: application\/json' \r\n -d '{\r\n \"createdOn\": 1510933574.672683,\r\n \"isCompleted\": false,\r\n \"name\": \"task3\"\r\n }'<\/code><\/pre>\n<p>You should see the newly added task show up on the app and the widget<\/p>\n<figure><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5658 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/11\/app_extension_fourth-min-compressed.gif\" alt=\"\" width=\"600\" height=\"342\" \/><\/figure>\n<h2 id=\"codewalkthrough\">Code Walkthrough<\/h2>\n<p>The app is architectured using the [<a href=\"https:\/\/(https:\/\/www.priyaontech.com\/download\/28\/\">Model-View-Presenter (MVP)<\/a>] pattern.<\/p>\n<h3 id=\"databasemanager\">DatabaseManager<\/h3>\n<p>The <code>DatabaseManager<\/code> is the <em>Model<\/em>, implemented as a singleton class that handles the Couchbase Lite database management functions. This is the class that initializes the Couchbase Lite database in the <em>Shared Container<\/em> so it is now available to both the App Extension and App processes<\/p>\n<p>Open the <em>DatabaseManager.swift<\/em> file and locate the <em>appGroupContainerURL()<\/em> function. This function creates a folder in the <em>Shared Container<\/em> for use by the app<\/p>\n<pre><code class=\"swift\"> \/\/ 1. Get URL to shared group container\r\n let fileManager = FileManager.default\r\n guard let groupURL = fileManager\r\n .containerURL(forSecurityApplicationGroupIdentifier: \"group.com.example.CBLiteSharedData\") else {\r\n return nil\r\n }\r\nlet storagePathUrl = groupURL.appendingPathComponent(&amp;quot;CBLite&amp;quot;)\r\nlet storagePath = storagePathUrl.path\r\n\r\n\/\/ 2: Create a folder in the shared container location with name&amp;quot;CBLite&amp;quot;\r\nif !fileManager.fileExists(atPath: storagePath) {\r\n    do {\r\n        try fileManager.createDirectory(atPath: storagePath,\r\n                                        withIntermediateDirectories: false,\r\n                                        attributes: nil)\r\n    } catch let error {\r\n        print(&amp;quot;error creating filepath: \\(error)&amp;quot;)\r\n        return nil\r\n    }\r\n}<\/code><\/pre>\n<ol>\n<li>Return the URL to the shared group container. Group containers are stored in <em>~\/Library\/Group Containers\/<\/em><\/li>\n<li>Create a folder named CBLite in the shared group container.<\/li>\n<\/ol>\n<p>Locate the <em>configureCBManagerForSharedData()<\/em> function. This is where we configure the <code>CBLManager<\/code> object with the URL to the folder that we created in the <em>appGroupContainerURL()<\/em> function<\/p>\n<pre><code class=\"swift\"> \/\/ 1. Set the file protection mode for the Couchbase Lite database folder\r\n let options = CBLManagerOptions(readOnly: false, fileProtection: Data.WritingOptions.completeFileProtectionUnlessOpen)\r\n let cblpoptions = UnsafeMutablePointer.allocate(capacity: 1)\r\n cblpoptions.initialize(to: options)\r\n if let url = self.appGroupContainerURL() {\r\n    \/\/ 2. Initialize the CBLManager with the directory of the shared container\r\n    _cbManager = try CBLManager.init(directory: url.relativePath, options: cblpoptions)\r\n    \r\n}<\/code><\/pre>\n<ol>\n<li>Create <code>CBLManagerOptions<\/code> object with the appropriate file protections. A value of <a href=\"https:\/\/developer.apple.com\/reference\/foundation\/nsdata.writingoptions\/1616278-completefileprotectionunlessopen\"><em>completeFileProtectionUnlessOpen<\/em><\/a> implies that read\/write access to the file is restricted unless file is open<\/li>\n<li>Initialize the <code>CBLManager<\/code> with the path to the shared container. Subsequently, when the database is created, it will be created in the shared container.That\u2019s it!<\/li>\n<\/ol>\n<p>Locate the <em>openOrCreateDatabaseInSharedContainer()<\/em> function. This is where we initialize the Couchbase Lite database using the CBLManager<\/p>\n<pre><code class=\"swift\"> \/\/ 1: Set Database Options\r\n let options = CBLDatabaseOptions()\r\n options.storageType = kCBLSQLiteStorage\r\n options.create = true\r\n \/\/ 2: Create a DB for logged in user if it does not exist else return handle to existing one\r\n  _db  = try _cbManager?.openDatabaseNamed(kDBName.lowercased(), with: options)<\/code><\/pre>\n<ol>\n<li>Create <code>CBLDatabaseOptions<\/code> object<\/li>\n<li>Initialize the <code>CBLDatabase<\/code> using the <code>CBLManager<\/code> instance that was created earlier. When the database is created, it will be created in the shared container specified by the manager.<\/li>\n<\/ol>\n<p>That\u2019s it! The Couchbase Lite database is now in the Shared Container that both the App and the Extension can read and write to.<\/p>\n<p>The next step is to enable synchornization with the remote Sync Gateway<\/p>\n<p>Locate the <em>startDBPullReplication()<\/em> function. This is where we configure the <em>Pull<\/em> replicator to pull data from Sync Gateway to the Couchbase Lite database.<\/p>\n<pre><code class=\"swift\"> if (pullRepl == nil) {\r\n \/\/ 1: Create a Pull replication to start pulling from remote source\r\n pullRepl = _db?.createPullReplication(URL(string: self.kDBName.lowercased(), relativeTo: URL.init(string: kRemoteSyncUrl))!)\r\n        \/\/ 2. Continuously look for changes\r\n        _pullRepl?.continuous = true\r\n     }\r\n\r\n    \/\/ 3. Start the pull replicator\r\n    _pullRepl?.start()<\/code><\/pre>\n<ol>\n<li>Create <code>CBLReplication<\/code> Pull replicator object<\/li>\n<li>Set it to pull documents in continuous mode. This will enable changes to be propagated in real time.<\/li>\n<li>Start the replication<\/li>\n<\/ol>\n<p>Locate the <em>startDBPushReplication()<\/em> function. This is where we configure the <em>Push<\/em> replicator to push data from Couchbase Lite database to the Sync Gateway.<\/p>\n<pre><code class=\"swift\"> if (_pushRepl == nil) {\r\n       \/\/ 1: Create a push replication to start pushing to remote source\r\n        _pushRepl = _db?.createPushReplication(URL(string: self.kDBName.lowercased(), relativeTo: URL.init(string:kRemoteSyncUrl))!)\r\n\r\n        \/\/ 2. Continuously push  changes\r\n        _pushRepl?.continuous = true\r\n\r\n     }\r\n\r\n    \/\/ 3. Start the push replicator\r\n    _pushRepl?.start()<\/code><\/pre>\n<ol>\n<li>Create <code>CBLReplication<\/code> Push replicator object<\/li>\n<li>Set it to push documents in continuous mode. This will enable changes to be propagated in real time.<\/li>\n<li>Start the replication<\/li>\n<\/ol>\n<p>Once you have enabled the replication, you add observers to be notified of changes. This is implemented in the <em>addReplicationChangeObserverForReplicator()<\/em> function.<br \/>\nWith these simple steps, you have the shared Couchbase Lite database replicating changes with the remote Sync Gateway.<\/p>\n<h3 id=\"taskpresenter\">TaskPresenter<\/h3>\n<p>The <code>TaskPresenter<\/code> is the Presenter, that handles UI interactions from both the <code>CBLiteTaskExtension<\/code> task extension and the <code>CBLiteTaskApp<\/code> app and interfaces with the <code>DatabaseManager<\/code>. It is the go-between the app\/ app extension and the DatabaseManager.<\/p>\n<p>Review the <em>TaskPresenter.swift<\/em> file. You will see that it implements the CRUD functions to interact with the Couchbase Lite database. But notice that the implementation of these functions uses the <code>DatabaseManager<\/code>.<\/p>\n<h3 id=\"whatnext\">What Next?<\/h3>\n<p>The post discusses how easy it is for you to use Couchbase Lite as a shared data store between your iOS App and corresponding Today App widget. With the shared database syncing with remote Sync Gatway, we can now replicate changes across the apps\/ app extensions across multiple devices.<\/p>\n<p>If you have any questions, feel free to reach out to me on Twitter <a href=\"https:\/\/twitter.com\/rajagp?lang=en\">@rajagp<\/a> or email me\u00a0<a href=\"mailto:priya.rajagopal@couchbase.com\">priya.rajagopal@couchbase.com<\/a>. If you would like to suggest improvements, submit a pull request to the <a href=\"https:\/\/github.com\/couchbaselabs\/couchbase-mobile-ios-app-extension\">GitHub<\/a> repo. You can learn more about integrating with Couchbase Lite in this\u00a0<a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-lite-embedded-in-ios-app-part1\/\">Getting started with Couchbase Lite<\/a> blog.<\/p>\n<p>The <a href=\"https:\/\/www.couchbase.com\/forums\/\">Couchbase Forums<\/a> are another great place to post your questions.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post discusses\u00a0how to use Couchbase Mobile to share data between your iOS App and iOS App Extension across devices. In an earlier post, we discussed how you can use Couchbase Lite as a standalone, embedded data store to share [&hellip;]<\/p>\n","protected":false},"author":1423,"featured_media":5656,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1821,7667,1810],"tags":[1964,1536],"ppma_author":[8948],"class_list":["post-4243","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-architecture","category-couchbase-lite","category-couchbase-mobile","tag-app-extension","tag-ios"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Share data between iOS Apps &amp; App Extensions across devices<\/title>\n<meta name=\"description\" content=\"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sharing and Syncing Data between iOS Apps and App Extensions across devices\" \/>\n<meta property=\"og:description\" content=\"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-28T17:28:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:09:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"600\" \/>\n\t<meta property=\"og:image:height\" content=\"619\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@rajagp\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Rajagopal, Senior Director, Product Management\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\"},\"author\":{\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c\"},\"headline\":\"Sharing and Syncing Data between iOS Apps and App Extensions across devices\",\"datePublished\":\"2017-11-28T17:28:16+00:00\",\"dateModified\":\"2025-06-14T03:09:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\"},\"wordCount\":1839,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif\",\"keywords\":[\"app extension\",\"ios\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Architecture\",\"Couchbase Lite\",\"Couchbase Mobile\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\",\"name\":\"Share data between iOS Apps & App Extensions across devices\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif\",\"datePublished\":\"2017-11-28T17:28:16+00:00\",\"dateModified\":\"2025-06-14T03:09:26+00:00\",\"description\":\"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif\",\"width\":600,\"height\":619},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sharing and Syncing Data between iOS Apps and App Extensions across devices\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c\",\"name\":\"Priya Rajagopal, Senior Director, Product Management\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g\",\"caption\":\"Priya Rajagopal, Senior Director, Product Management\"},\"description\":\"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security.\",\"sameAs\":[\"https:\/\/x.com\/rajagp\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/priya-rajagopalcouchbase-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Share data between iOS Apps & App Extensions across devices","description":"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/","og_locale":"en_US","og_type":"article","og_title":"Sharing and Syncing Data between iOS Apps and App Extensions across devices","og_description":"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices","og_url":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-11-28T17:28:16+00:00","article_modified_time":"2025-06-14T03:09:26+00:00","og_image":[{"width":600,"height":619,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif","type":"image\/gif"}],"author":"Priya Rajagopal, Senior Director, Product Management","twitter_card":"summary_large_image","twitter_creator":"@rajagp","twitter_misc":{"Written by":"Priya Rajagopal, Senior Director, Product Management","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/"},"author":{"name":"Priya Rajagopal, Senior Director, Product Management","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c"},"headline":"Sharing and Syncing Data between iOS Apps and App Extensions across devices","datePublished":"2017-11-28T17:28:16+00:00","dateModified":"2025-06-14T03:09:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/"},"wordCount":1839,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif","keywords":["app extension","ios"],"articleSection":["Best Practices and Tutorials","Couchbase Architecture","Couchbase Lite","Couchbase Mobile"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/","url":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/","name":"Share data between iOS Apps & App Extensions across devices","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif","datePublished":"2017-11-28T17:28:16+00:00","dateModified":"2025-06-14T03:09:26+00:00","description":"Use Couchbase Mobile Database in a shared container to share data between an iOS App and corresponding App Extension and to sync data across devices","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2018\/08\/app_extension_third-min-compressed.gif","width":600,"height":619},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/sharing-data-ios-app-extensions-sync-capability\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Sharing and Syncing Data between iOS Apps and App Extensions across devices"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/c2da90e57717ee4970c48a87a131ac2c","name":"Priya Rajagopal, Senior Director, Product Management","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/4b50a54778b979d8c345b036ab138734","url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","caption":"Priya Rajagopal, Senior Director, Product Management"},"description":"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security.","sameAs":["https:\/\/x.com\/rajagp"],"url":"https:\/\/www.couchbase.com\/blog\/author\/priya-rajagopalcouchbase-com\/"}]}},"authors":[{"term_id":8948,"user_id":1423,"is_guest":0,"slug":"priya-rajagopalcouchbase-com","display_name":"Priya Rajagopal, Senior Director, Product Management","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/acfb2349788955262cd069497a9e7bdb0e97c26326f2e55811e7c1174e9ef1be?s=96&d=mm&r=g","author_category":"","last_name":"Rajagopal, Senior Director, Product Management","first_name":"Priya","job_title":"","user_url":"","description":"Priya Rajagopal is a Senior Director of Product Management at Couchbase responsible for developer platforms for the cloud and the edge. She has been professionally developing software for over 20 years in several technical and product leadership positions, with 10+ years focused on mobile technologies. As a TISPAN IPTV standards delegate, she was a key contributor to the IPTV standards specifications. She has 22 patents in the areas of networking and platform security."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/4243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/1423"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=4243"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/4243\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/5656"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=4243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=4243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=4243"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=4243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}