Skip to content

Latest commit

 

History

History
280 lines (200 loc) · 11.6 KB

README.md

File metadata and controls

280 lines (200 loc) · 11.6 KB

Couchbase Lite Retail Demo - iOS

A retail inventory management app for iOS demonstrating Couchbase Lite's offline-first capabilities, real-time sync with Capella App Services, and peer-to-peer sync between devices.

Prerequisites

Important

Before proceeding with the iOS setup, you must complete the Capella backend configuration described in the root README. This includes creating a Capella cluster, deploying an App Service, setting up the bucket/scopes/collections, importing the sample dataset, creating App Endpoints and App Users, and recording the public connection URL. If you skip these steps, the app will fail to authenticate and sync.

Backend version: the App Service / Sync Gateway must be 4.0 or later, because Couchbase Lite 4.x clients require a 4.x sync backend. Capella App Services' free tier already defaults to 4.x.

Requirements

  • Xcode: 16.4 or later
  • iOS: 18.5 or later
  • Swift: 6.0 (included with Xcode)
  • macOS: Sonoma or later (for running Xcode 16.4)

Dependencies

The project uses Swift Package Manager (SPM) for dependency management. Dependencies are automatically resolved when you open the project:

  • Couchbase Lite Swift: 4.1.0 (Enterprise Edition). 4.1.0 is the release that adds the Bluetooth LE peer-to-peer transport used by this demo

Getting Started

1. Create Info.plist (Required Before Building)

Important

Info.plist is not included in the repository but is required by the Xcode project. You must create it before attempting to build, or the build will fail with:

unable to read input file '.../GroceryApp/Info.plist': Operation not permitted

Create the file at GroceryApp/Info.plist with your Capella App Services credentials:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CBL_BASE_URL</key>
    <string>wss://your-endpoint.apps.cloud.couchbase.com:4984</string>
    <key>CBL_AA_DB</key>
    <string>supermarket-aa</string>
    <key>CBL_NYC_DB</key>
    <string>supermarket-nyc</string>
    <key>CBL_AA_USER</key>
    <string>aa-store-01@supermarket.com</string>
    <key>CBL_NYC_USER</key>
    <string>nyc-store-01@supermarket.com</string>
    <key>CBL_PASSWORD</key>
    <string>P@ssword1</string>
</dict>
</plist>

Where to find CBL_BASE_URL: In your Capella dashboard, go to App Services > select your App Endpoint (e.g. supermarket-nyc) > Connect tab. Copy the Public Connection URL, which looks like wss://<id>.apps.cloud.couchbase.com:4984. Use only the base URL; do not append the database name (that is handled separately by CBL_AA_DB / CBL_NYC_DB).

2. Open the Project

Open the Xcode project:

cd iOS
open GroceryApp.xcodeproj

Xcode will automatically resolve and download the required Swift packages when you first open the project.

3. Configure Capella App Services (Alternative Methods)

If you prefer not to use Info.plist for configuration, you have two other options. The app checks environment variables first, then falls back to Info.plist.

Option A: Environment Variables (Terminal Launch)

Set environment variables in your shell:

export CBL_BASE_URL="wss://your-endpoint.apps.cloud.couchbase.com:4984"
export CBL_AA_DB="supermarket-aa"
export CBL_NYC_DB="supermarket-nyc"
export CBL_AA_USER="aa-store-01@supermarket.com"
export CBL_NYC_USER="nyc-store-01@supermarket.com"
export CBL_PASSWORD="P@ssword1"

Then launch Xcode from the terminal to inherit these variables:

open GroceryApp.xcodeproj

Option B: Xcode Scheme Configuration

  1. In Xcode, select Product > Scheme > Edit Scheme
  2. Go to Run > Arguments tab
  3. Add the environment variables under Environment Variables:
    • CBL_BASE_URL: wss://your-endpoint.apps.cloud.couchbase.com:4984
    • CBL_AA_DB: supermarket-aa
    • CBL_NYC_DB: supermarket-nyc
    • CBL_AA_USER: aa-store-01@supermarket.com
    • CBL_NYC_USER: nyc-store-01@supermarket.com
    • CBL_PASSWORD: P@ssword1

Note

An Info.plist file is still required for the build to succeed, even when using environment variables. You can create a minimal valid plist (containing a root dict) if you prefer to configure credentials via environment variables only.

4. Build and Run

Select a simulator or connected device and click Run (⌘R).

Vector Search Copilot

The Copilot tab is the on-device vector search part of the demo: semantic product search, a visual shelf audit, and retrieval augmented answers. All of it queries the local Couchbase Lite database, so it works with the network off.

The code lives in GroceryApp/Copilot/. Everything it needs is already in the repo:

Model Used for Where
MiniLM-L6-v2 (CoreML) Text embedding, 384 dimensions Copilot/Resources/
CLIP ViT-B/32 (CoreML, int8) Image embedding, 512 dimensions Copilot/Resources/
Apple Foundation Models Answer generation in Ask Supplied by iOS

Two things to know before you judge the results:

  • Answer generation needs a physical iPhone with Apple Intelligence enabled. The Simulator reports the model as available and then fails at inference. Retrieval works fine in the Simulator, so Ask will show you the passages it found without writing an answer.
  • The Copilot needs data the base setup does not create. If Find returns nothing, or the Planogram tab says a shelf has no golden layout, work through Setting up the Copilot data and models.

For what the three steps do, see the Copilot. For the data model, queries and thresholds, see how the vector search works.

Project Structure

iOS/
├── GroceryApp/
│   ├── GroceryAppApp.swift              # Main app entry point (@main)
│   ├── App.swift                        # P2P sync helper (GrocerySyncApp, Network Framework)
│   ├── AppConfig.swift                  # Configuration (database, sync, stores)
│   ├── DatabaseManager.swift            # Couchbase Lite database operations
│   ├── AppServicesSyncManager.swift     # Sync with Capella App Services
│   ├── GroceryMultipeerSyncManager.swift # Peer-to-peer sync
│   ├── AuthenticationManager.swift      # User authentication
│   ├── Views/
│   │   ├── LoginView.swift
│   │   ├── InventoryView.swift
│   │   ├── OrdersView.swift
│   │   └── StoreProfileView.swift
│   └── Models/
│       ├── GroceryItem.swift
│       ├── Order.swift
│       └── StoreProfile.swift
└── GroceryApp.xcodeproj

Configuration Details

Database Settings

  • Database Name: GroceryInventoryDB
  • Scopes: AA-Store, NYC-Store (based on selected store)
  • Collections:
    • inventory - Product inventory items
    • orders - Customer orders
    • profile - Store profile information

Sync Configuration

The app uses continuous replication, which is event-driven (not polling). Changes are pushed and pulled immediately over a persistent WebSocket connection to Capella App Services.

Key settings in AppConfig.swift:

  • syncContinuous: Enables real-time bidirectional sync
  • enableAppServicesSync: Toggle cloud sync on/off
  • enableP2PSync: Toggle peer-to-peer sync on/off

Features

Real-Time Sync with Capella

The app syncs inventory, orders, and store profile data with your Capella cluster through App Services. Changes made in the app are immediately synced to the cloud and to other connected devices.

Peer-to-Peer Sync

Devices can sync directly with each other without going through the cloud, over Wi-Fi (local network) or Bluetooth LE. This is useful for:

  • Demo scenarios with multiple devices
  • Offline collaboration between nearby devices, even with no shared network
  • Reducing cloud bandwidth usage

To enable P2P sync, ensure enableP2PSync is set to true in AppConfig.swift.

Transports: Wi-Fi + Bluetooth LE

GroceryMultipeerSyncManager configures the replicator with both transports:

var transports: Set<MultipeerTransport> = [.wifi, .bluetooth]

The replicator auto-selects and auto-switches between transports based on availability: it meshes over Wi-Fi when both devices share a network, and falls back to Bluetooth LE when they don't. To exercise the Bluetooth path specifically, put both devices in Airplane Mode with Bluetooth left on.

Bluetooth requires its own usage-description string in addition to the local-network one; both are already configured in the Xcode project (Info.plist generation settings):

Capability Info.plist key
Bluetooth LE peer discovery NSBluetoothAlwaysUsageDescription
Wi-Fi / Bonjour peer discovery NSLocalNetworkUsageDescription + NSBonjourServices

On first launch with P2P enabled, iOS prompts for both permissions separately, so accept both, or Bluetooth sync will silently fail to advertise/scan.

Offline-First Architecture

The app works fully offline using Couchbase Lite as the local database. All operations (create, read, update, delete) work without network connectivity. When connectivity is restored, changes automatically sync to the cloud.

Troubleshooting

Build Errors

"Cannot find 'CouchbaseLiteSwift' in scope"

  • Wait for SPM to finish resolving packages (check progress in Xcode's top status bar)
  • Try File > Packages > Reset Package Caches
  • Clean build folder: Product > Clean Build Folder (⇧⌘K)

"Could not resolve package dependencies"

  • Ensure you have an active internet connection
  • Check that the package URLs in Package.resolved are accessible
  • Try removing and re-adding the packages in File > Packages

Sync Issues

Sync not working

  • Verify your CBL_BASE_URL is correct and includes wss:// protocol
  • Check that environment variables are set correctly
  • Verify your App Services endpoint is running in Capella
  • Check Xcode console for sync-related error messages

Authentication failures

  • Ensure the user credentials match those configured in Capella App Services
  • Verify the database name (CBL_AA_DB or CBL_NYC_DB) matches your App Endpoint

Runtime Issues

App crashes on launch

  • Check Xcode console for crash logs
  • Verify all required environment variables are set
  • Ensure the selected iOS simulator/device meets the minimum iOS version (18.5)

Data not appearing

  • Confirm your Capella cluster has data imported into the correct scope/collection
  • Check that scopeName and collection names in AppConfig.swift match your Capella setup
  • Look for database errors in the console output

Additional Notes

Enterprise vs Community Edition

This project uses Couchbase Lite Enterprise Edition, which includes additional features like encrypted sync and delta sync. If you need to use the Community Edition, update the package dependency in Xcode to point to the community repository.

P2P Network Discovery

Peer-to-peer sync uses Bonjour/mDNS for device discovery on the local network. Make sure:

  • Devices are on the same Wi-Fi network
  • Local network permissions are granted to the app
  • Firewall settings allow Bonjour traffic

Related Documentation