Populate iOS picker view (Swift 3) from Couchbase server


#1

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


#2

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


#3

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


#4

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


#5

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


#6

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 ?


#7

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


#8

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:


#9

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


#10

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

-Priya