Simple Sync is a demonstration of how to read, write, search, and sync data using Couchbase Lite. This repository provides a comprehensive guide to handling different types of data and demonstrates how to synchronize this data across devices, with and without the Internet.
The Simple Sync app is available for download from the App Store. You can download and run the app on your device without any additional setup to see these features in action.
The code is divided into four major areas, each demonstrating different aspects of data handling and synchronization:
The ColorViewController
class manages the color sync feature. It demonstrates how to read, write, and sync simple scalar data, and listen for database changes.
// Get the profile document from the database collection.
let profile = collection["profile1"].document
// Get the color from the profile.
let color = profile["color"].string
// Update the color.
profile["color"].string = "green"
// Save the document.
try collection.save(document: profile)
// Listen for changes to the profile document.
collection.addDocumentChangeListener(id: "profile1") { change in
// React to the change.
}
The PhotoViewController
class manages the photo sync feature. It demonstrates how to read, write, and sync binary data.
// Get the profile document from the database collection.
let profile = collection["profile1"].document
// Get the photo from the profile.
let photo = profile["photo"].blob
// Update the photo.
let newPhoto = UIImage(named: "newPhoto")
if let pngData = newPhoto.pngData() {
profile["photo"].blob = Blob(contentType: "image/png", data: pngData)
}
// Save the document.
try collection.save(document: profile)
The CountViewController
class manages the count sync feature. It demonstrates how to read, write, and sync complex data using a CRDT PN-Counter (Positive-Negative Counter).
// Get the item document from the database collection.
let item = collection["item1"].document
// Get the counter from the item.
var count = item.counter(forKey: "count")
// Increment the count.
count.increment(by: 1)
// Decrement the count.
count.decrement(by: 1)
// Save the document with concurrency control.
try collection.save(document: item, concurrencyControl: .failOnConflict)
The SearchViewController
class manages the search feature. It demonstrates how to use Couchbase Lite’s SQL, full-text search, vector search, and indexing capabilities.
SELECT name, image
FROM products
WHERE category = $category
AND VECTOR_MATCH(ImageVectorIndex, $embedding, 10)
AND VECTOR_DISTANCE(ImageVectorIndex) < 0.35
AND MATCH(NameColorAndCategoryIndex, $search)
ORDER BY VECTOR_DISTANCE(ImageVectorIndex), RANK(NameColorAndCategoryIndex), name
// Create the query.
let query = try database.createQuery(sql)
// Set the query parameters.
query.parameters = Parameters()
.setString(category, forName: "category")
.setString(embedding, forName: "embedding")
.setString(search, forName: "search")
// Execute the query.
let results = try query.execute()
// For fast sorting, create an index on the "name" field.
let nameIndex = ValueIndexConfiguration(["name"])
try collection.createIndex(withName: "NameIndex", config: nameIndex)
// For fast predicates, create an index on the "category" field.
let categoryIndex = ValueIndexConfiguration(["category"])
try collection.createIndex(withName: "CategoryIndex", config: categoryIndex)
// Initialize the vector index on the "embedding" field for image search.
var vectorIndex = VectorIndexConfiguration(expression: "embedding", dimensions: 768, centroids: 1000)
try collection.createIndex(withName: "ImageVectorIndex", config: vectorIndex)
// For fast searches, create a full-text search index on the "name", "color", and "category" fields.
let ftsIndex = FullTextIndexConfiguration(["name", "color", "category"])
try collection.createIndex(withName: "NameColorAndCategoryIndex", config: ftsIndex)
The App
class manages the overall synchronization of the application using Couchbase Lite's sync capabilities. It demonstrates how to sync peer-to-peer and with an endpoint over the internet. The class handles network management, monitoring, and trust verification.
// Create the app passing the database to sync, the sync endpoint, and the identity
// and certificate authority for peer-to-peer trust verification.
let app = App(
database: database,
endpoint: endpoint,
identity: identity,
ca: ca
)
// Start syncing.
app.start()
NOTE: The included gen-credentials.sh
script was used to generate the credentials included with the project. If you want to generate new credentials, run that script again and replace the files in the project's credentials folder with the newly generated files.
An endpoint can be hosted using Couchbase Capella or Couchbase Sync Gateway, and connected in the Simple Sync app settings.
Start with an existing App Service or create a new one. In the App Service, create and configure the following endpoints:
- Create an App Endpoint named “color”
- In the App Endpoint, create a user with the Admin Channel “color”
- Define the Access Control and Data Validation function as:
function(doc, oldDoc, meta) {
if (doc._id !== "profile") {
throw new Error();
}
channel("color");
}
- Create an App Endpoint named “photo”
- In the App Endpoint, create a user with the Admin Channel “photo”. The user should have the same username/password as the user created for the "color" App Endpoint.
- Define the Access Control and Data Validation function as:
function(doc, oldDoc, meta) {
if (doc._id !== "profile") {
throw new Error();
}
channel("photo");
}
- Create an App Endpoint named “count”
- In the App Endpoint, create a user with the Admin Channel “count”. The user should have the same username/password as the user created for the "color" App Endpoint.
- Define the Access Control and Data Validation function as:
function(doc, oldDoc, meta) {
if (doc._id !== "item") {
throw new Error();
}
channel("count");
}
- Clone or download this repository
- Download the latest
CouchbaseLiteSwift.xcframework
andCouchbaseLiteVectorSearch.xcframework
, and copy them to the project'sFrameworks
directory. - Open the project in Xcode.
- Run the app on two or more simulators, phones, or tablets.
- Tap on the
Color
view, then tap the screen. The color will change and sync with other devices. - Tap on the
Photo
view, then tap the screen. The photo will change and sync with other devices. - Tap on the
Count
view, then tap the buttons. The count will change and sync with other devices. - Tap on the
Search
view, then search using name, color, category, image, and more.
- Tap on the
To explore the code, start with the following source files:
ColorViewController.swift
: Manages the color sync feature.PhotoViewController.swift
: Manages the photo sync feature.CountViewController.swift
: Manages the count sync feature.SearchViewController.swift
: Manages the search feature.Counter.swift
: Contains theCounter
andMutableCounter
classes for managing the CRDT pn-counter, and theCRDTConflictResolver
class for resolving conflicts.App.swift
: Manages the peer-to-peer and internet endpoint sync features, and handles network monitoring and trust verification.