Hi jens, your explanation was very helpful and I think I got most of this now.
The reason why I wanted this in a database was because I’ll be adding countries/states to this list in the future. However, I do see the value of uniquely identifying that document and just referencing it directly and not through a query. By well known ID, you mean something like “62023fc0264ac81be77e3f1215873c16” correct? Those doc ID’s are impossible to memorize, lol.
Here’s how I set it all up (for those newly to CBL that have the same questions as mine).
-
Created the view (in AppDelegate after opening the database):
let countryView = database.viewNamed(“countrylist”)
countryView.setMapBlock({ (doc, emit) in
if let type = doc[“type”] as? String, let statelist = doc[“statelist”], let country = doc[“country”], type == “location_array” {
emit(country,[statelist])
}
}, version: “13”) -
Set up a begin and end key:
let beginCountry = "Japan"
let endCountry = “USA” -
invoked the query:
let query = database.viewNamed(“countrylist”).createQuery()
query.limit = 20
query.startKey = beginCountry
query.endKey = endCountrydo { let result = try query.run()
while let row = result.nextRow() {
let resultValue = (row.value as! NSArray) as Array
let countryValue = row.key
let stateValue = resultValue[0]
locationData.append(locationStruc(country: countryValue as! String, statelist: stateValue as! [String]))
}
} catch { return }
I was able to then populate the pickerview with the countries between Japan and USA (inclusive). In all likelihood, I’ll remove the begin and end criteria for this view and it was more for learning purpose. This is really neat stuff and I hope to become more fluent with it.
I did run across a problem trying to run the query in a different view form. If I started with:
let queryx = database.viewNamed("countrylist").createQuery()
queryx.limit = 20
queryx.startKey = "USA"
queryx.endKey = "USA"
It complained that “database” was an unresolved identified. Thinking that since “query” was already set up correctly earlier, I just removed that and tried:
query.limit = 20
query.startKey = "USA"
query.endKey = "USA"
do { let result = try query.run()
while let row = result.nextRow() {
let resultValue = (row.value as! NSArray) as Array
let countryValue = row.key
let stateValue = resultValue[0]
locationData.append(locationStruc(country: countryValue as! String, statelist: stateValue as! [String]))
}
} catch { return }
but it didn’t recognize “query” as a valid identifier.
Does the “database” have to be declared globally in AppDelegate so that other forms can use it? Is “database” considered a variable? Here’s how I opened the database:
func openDatabase(username:String, withKey key:String?,
withNewKey newKey:String?) throws {
// TRAINING: Create a database
let dbname = username
let options = CBLDatabaseOptions()
options.create = true
if kEncryptionEnabled {
if let encryptionKey = key {
options.encryptionKey = encryptionKey
}
}
try database = CBLManager.sharedInstance().openDatabaseNamed(dbname, with: options)
if newKey != nil {
try database.changeEncryptionKey(newKey)
}
Thanks,
David