The Basics
Create a Database
There is no limit to how many databases can be created or opened on the device. You can think of a database as a namespace for documents and several databases can be used in the same app (one database per user of the app is a common pattern).
The snippet below creates an empty database for guest user in a directory named guest.
Open the file DatabaseManager.swift.
We will review the func openOrCreateDatabaseForGuest( handler:(_ error:Error?)→Void) method.
func openOrCreateDatabaseForGuest( handler:(_ error:Error?)->Void) {
...
}
We create a folder for the guest user database if one does not exist and specify that as the database directory in the DatabaseConfiguration object.
var options = DatabaseConfiguration()
guard let defaultDBPath = _applicationSupportDirectory else {
fatalError("Could not open Application Support Directory for app!")
return
}
// Create a folder for Guest Account if one does not exist
let guestFolderUrl = defaultDBPath.appendingPathComponent("guest", isDirectory: true)
let guestFolderPath = guestFolderUrl.path
let fileManager = FileManager.default
if !fileManager.fileExists(atPath: guestFolderPath) {
try fileManager.createDirectory(atPath: guestFolderPath,
withIntermediateDirectories: true,
attributes: nil)
}
options.directory = guestFolderPath
The Couchbase Lite Database is created with the specified name and DatabaseConfiguration object
// Gets handle to existing DB at specified path
_db = try Database(name: kGuestDBName, config: options)
Create and Update a Document
Bookmarked hotels are persisted in a separate document with a type of bookmarkedhotels.
The first time a hotel is bookmarked, the bookmarkedhotels document is created with the document ID of that hotel document in the hotels property.
The hotel’s information is persisted in a separate hotels type document.
Subsequently, every time a hotel is bookmarked, the process repeats.
{
"_id": "hotel1",
"name": "San Francisco Hotel",
"address": "123, Park Street, San Francisco"
}
{
"type": "bookmarkedhotels",
"hotels": ["hotel1", "hotel2"]
}
Open the file HotelPresenter.swift.
We will review the func bookmarkHotels(_ hotels: Hotels, handler:@escaping( _ error:Error?)→Void) method.
func bookmarkHotels(_ hotels: Hotels, handler:@escaping( _ error:Error?)->Void) {
...
}
First, you need to get an instance of the database.
guard let db = dbMgr.db else {
handler(TravelSampleError.DatabaseNotInitialized)
return
}
Then fetch documents of type bookmarkedhotels.
Don’t worry too much about how you query for documents of a specific type from the database.
We will examine the Query API in a future lesson.
Create a document of type bookmarkedhotels if one does not exist.
var document = try fetchGuestBookmarkDocumentFromDB(db)?.toMutable()
if document == nil {
// First time bookmark is created for guest account
// Create document of type "bookmarkedhotels"
document = MutableDocument.init(withData: ["type":"bookmarkedhotels","hotels":[String]()])
}
Next, retrieve the Ids of hotels to be bookmarked and add it to the current list of bookmarked hotel Ids from the hotels property of the bookmarkedhotels document.
// Get the Ids of all hotels that need to be bookmarked
let ids:[String] = hotels.map({ (dict) in
if let idVal = dict["id"] as? String {
return idVal
}
return ""
})
// Fetch the current list of bookmarked hotel Ids
var bookmarked = document?.array(forKey: "hotels")
// Add the new hotel ids to the bookmarked hotels array
for newId in ids {
bookmarked = bookmarked?.addString(newId)
}
Update and save the document of type "bookmarkedhotels"
// Update and save the "bookmarkedhotels" document
if let document = document?.toMutable() {
// Update and save the bookmark document
document.setArray(bookmarked, forKey: "hotels")
try db.saveDocument(document)
}
Persist the hotel information as separate documents of type hotels.
First, determine if the document with the specified hotel Id already exists.
If so, update it with the selected hotel details.
If not, create a new hotel document.
// Add the hotel details documents
for hotelDoc in hotels {
if let idVal = hotelDoc["id"] as? String {
if let doc = db.document(withID: idVal)?.toMutable() {
doc.setData(hotelDoc)
try db.saveDocument(doc)
}
else {
try db.saveDocument(MutableDocument.init(withID: idVal, data: hotelDoc))
}
}
}
Delete a Document
A document can be deleted using the delete method.
This operation actually creates a new tombstoned revision in order to propagate the deletion to other clients.
Open the file HotelPresenter.swift.
We will review the func unbookmarkHotels(_ hotels: Hotels, handler:@escaping( _ error:Error?)→Void) method.
func unbookmarkHotels(_ hotels: Hotels, handler:@escaping( _ error:Error?)->Void) {
...
}
When searching for hotels in Guest mode, the app sends a GET request to the Python Web App which performs a Full-Text Search query on Couchbase Server. Then, if a hotel is bookmarked, it gets inserted in the Couchbase Lite database for offline access. So when the user unbookmarks a hotel, the document needs to be removed from the database. That’s what the code below is doing.
// Remove unbookmarked hotel documents
for idOfDocToRemove in idsToRemove {
if let doc = db.document(withID: idOfDocToRemove) {
try db.deleteDocument(doc)
}
}
In addition to deleting the document of type "hotel" as shown above, the unbookmarking process removes the hotel ID from the hotels array in the "bookmarkedhotels" document.
-
Follow the steps in Try it out — Bookmark a Hotel to bookmark a hotel
-
Confirm that you see the bookmarked hotels in the "Bookmarked Hotels" screen. If not, make sure you go through the instructions in Try it out — Bookmark a Hotel
-
Swipe left on a bookmarked hotel cell.
-
You will get an option to “UnBookmark”.
-
Tap "UnBookmark".
-
Verify that the unbookmarked hotel does not show up in the list — see: Figure 2