Populate iOS picker view (Swift 3) from Couchbase server

Hi all,

I’m looking to populate a picker view in Swift 3 with document data stored on a Couchbase server and trying to see if anyone has done that and perhaps have sample code in Github or something that can be shared here.

I am relatively new to both Couchbase and Swift and am trying to learn both but struggling a little bit and I think an example would really help, just like how the to-do lite project taught me some sync basics.

Appreciate any time in advance,
David

Hi David,
You will have to first fetch/pull data from the Couchbase Server . Once you have the data local in your app, you can implement the UIPickerViewDelegate and UIPickerViewDataSource protocols as you would normally do in order to populate the picker view.

-Priya

Hi Priya, thanks for the response. I’ve gone through a number of tutorials and all I see out there is the pickerview being populated by an array. Do I have to populate an array from fetched data in the Couchbase Lite db instance and then link that array to the pickerdatasource?

Thanks,
David

Hi David
You don’t have to copy it over to a separate Array if you don’t want to. You can return the CBLQueryEnumerator’s count in the UIPickerViewDelegate’s numberOfRowsInComponent function and CBLQueryEnumerator’s rowAtIndex function to get the details of a row which you can then query to return in titleForRow delegate function

Roughly …

   func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return Int(self.docsEnumerator?.count ?? 0)

    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        
        let queryRow = self.docsEnumerator?.row(at: UInt(row))
        let userProps = queryRow?.document?.userProperties 
        let title = userProps?["name"] as? String // Depends on your document structure
        return title
        
    }

regards
-Priya

Hello Priya, thanks for providing this snippet, which I am studying. I do have a related question that I’m hoping you can answer, or at least provide some insight. I want to create an iOS app that pulls down data (like you outlined above) but also pushes up data to the Couchbase server. However, I do not want the data being pushed up to sync at all. In the simplest description, let’s say I load a pickerview with data from Couchbase and then when a user selects an item in the pickerview, the app captures what item is selected and stores that in Couchbase. I looked around for documentation on something like that but I can’t seem to find it. Is something like that handled via channels? Would it be easier to populate the pickerview source with a refresh pull each time the app is opened, or should I sync the source for pickerview with the backend server? I guess that might be more of a programmatic preference.

Thanks,
David

Hi David
Can you elaborate what you mean by “I do not want the data being pushed up to sync at all”.
Once you “push” a document to the Sync Gateway, it will be synchronized.
So are you looking to store the selected picker value in a local document that does not get synched or pushed up to SG ?

Hi Priya, perhaps a better example will help. Let’s say I want to create a utility and I want to track usage of the utility. Perhaps I want to know how often a particular function of the utility is being used. I’d like certain actions to be logged into the mobile Couchbase db and then transferred to the Couchbase server via sync. However, I don’t want those logs to get sync’d to every other user who uses the application. So basically I’m looking at mixing both a one-way data transfer up (logs of user actions) and a one-way transfer down (populating a pickerview with something that I want to manage on the backend).

Does that make a little more sense?

Thanks,
David

Hi David
In your particular example, if you don’t want the logs to be synched to every other user, then I would put the log documents in a “private” channel that is only accessible to the user.
The assignment of documents to channels is handled by the sync function that runs on the Sync Gateway. So you could include a “type” user property to distinguish between the doc types. The Sync Gateway could use document type to assign those to a private channel that only the owner of the logs can access.
You can learn more about channels and data routing here : https://developer.couchbase.com/documentation/mobile/current/guides/sync-gateway/channels/index.html

You can also refer to this blog post that demonstrates how you can assign documents to private and public channels , very similar to what you are looking for :-
https://blog.couchbase.com/data-sync-on-ios-couchbase-mobile/

Sample App:

Hi Priya,

Thanks for the links and I’m studying them right now. For the starterapp, I’m trying to run it but am encountering an “Apple Mach-O Linker Error” which might be due to some missing files. Have you run into this before? I downloaded and unzipped the startapp.zip file to my desktop and I did make sure to change the bundle identifier and signing team.

David

Hi David
Make sure you open the .xcworkspace (not the project file) ?

-Priya