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)

Try it out

  • Build and Run the Travel Sample Mobile App

  • On the Login screen select “Proceed as Guest” option.

  • This will log you into the app in Guest Mode. Signing in as Guest will create a new empty database for “guest” account if one does not exist

  • Confirm that you see the "Bookmarked Hotels" page. It will be empty the very first time.

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))

      }
  }
}

Try it out

  • As Guest User, tap on the "hotels" button.

  • In the "location" text field , enter "London".

  • You will see a list of hotels.

  • The list of hotels is pulled from the Couchbase Server via the Travel Sample Web Services API. The list of hotels is not displayed unless there is an open connection the python web app so make sure you have your Travel Sample Web app running.

  • Swipe left on the first hotel cell

  • You will get option to “Bookmark”

  • Tap “bookmark”

  • This should display a "bookmark" icon on the hotel cell

  • Tap "Cancel" button

  • Verify that you see the bookmarked hotel in the “Bookmarked Hotels” screen. A motivation for having separate docs for each bookmarked hotel is if they become sharable between users via the sync function.

    basics add document

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.

Try it out

  • Follow the steps in Update a Document section 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 Update a Document section

  • 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.

    basics delete document