Announcing Release of Couchbase Lite 2.0 Developer Build 21 (DB 21)

82 views
Skip to first unread message

Priya Rajagopal

unread,
Dec 21, 2017, 9:52:52 AM12/21/17
to Couchbase Mobile
Happy to announce the release of Couchbase Lite 2.0 Developer Build 21 (DB 21) . The DB21 release is available for iOS(Swift, ObjC), .NET (UWP, Xamarin) and Android platforms .
You can download the latest PreRelease Build from our Downloads page : https://www.couchbase.com/downloads


DB021 release introduces some major API updates to the iOS , Android and .Net platforms. The changes include enhancements to Query and Indexing APIs, the default conflict resolver algorithm, database thread safety, live Query API and several bug fixes.

  Be sure to read the platform specific release notes for a full list of platform specific changes.


**Links to platform specific release notes -**


**Sample Apps :**



**Other Links:**


**About Developer Builds:**

Developer Builds give you the opportunity to engage with Couchbase engineers and provide early feedback to influence key aspects of Couchbase Mobile 2.0. It will give us insight into how you use new features in your projects, where you run into issues, and how we can help resolve them.

**About Couchbase Lite 2.0:**

Couchbase Lite 2.0 is a groundbreaking new release for Couchbase Mobile. Key enhancements include a cross-platform common core, simplified Query API with full-text search capabilities, automated conflict resolution that can be customized and a new and improved replication protocol 

Ben Kennedy

unread,
Jan 24, 2018, 5:59:52 PM1/24/18
to Couchbase Mobile
Hello, all.

In our org we have been using CBL 1.x in our iOS app for a couple of years now. Our work on that area has been more or less in a stasis for some time, but we've recently started work on a greenfield project that finally provides the opportunity to begin working with CBL 2.0 betas. I'm quite excited about it. Is this list an appropriate place to be asking general questions in that regard?

My first step is to initialize a local database, which I want to place in a specific directory. I haven't been able to find any documentation on the intended use of DatabaseConfiguration; as far as I've been able to figure out, I have to go like this:

    let config = DatabaseConfiguration.Builder().setDirectory("/foo/bar").build()


This seems like an insanely baroque syntax. Is it the correct way? It seems that it would be more desirable to do something like:

    let config = DatabaseConfiguration(directory: "/foo/bar")


or even

    let config = DatabaseConfiguration()

    config.directory = "/foo/bar"


cheers,

-ben

Jens Alfke

unread,
Jan 24, 2018, 6:54:55 PM1/24/18
to Couchbase Mobile


On Jan 24, 2018, at 2:59 PM, Ben Kennedy <ben.k...@kashoo.com> wrote:

This seems like an insanely baroque syntax. Is it the correct way?

It’s the Builder design pattern. When there are a lot of optional properties for creating an object, it gets awkward to stuff all of them into one constructor/initializer method, so you create an object to hold the properties and then pass that to the constructor.

IMHO we’ve currently got too many layers of this — effectively a builder to create a builder. There’s some debate going on internally about this, so your feedback is helpful.

    let config = DatabaseConfiguration()
    config.directory = "/foo/bar"

Yeah, it was like this recently. But some developers would modify the configuration after creating the Database from it, and then asking why their configuration wasn’t applied. (Reminds me of the old joke about how you can’t idiot-proof anything because people keep finding cleverer ways to be idiots.)

—Jens

Ben Kennedy

unread,
Jan 24, 2018, 7:17:53 PM1/24/18
to mobile-c...@googlegroups.com, Jens Alfke
> On Jan 24, 2018, at 3:54 PM, Jens Alfke <je...@couchbase.com> wrote:
>
> When there are a lot of optional properties for creating an object, it gets awkward to stuff all of them into one constructor/initializer method, so you create an object to hold the properties and then pass that to the constructor.

I agree with the principle, and am on board with the notion of a configuration object. But having to chain together a pile of methods to populate it, rather than simply exposing properties, feels needlessly unwieldy in my opinion.

Perhaps it's is a known issue, but the examples currently shown at https://developer.couchbase.com/documentation/mobile/2.0/couchbase-lite/swift.html don't work. For example, to set up a replicator, it seems I'm forced either to use the method-chaining builder pattern previously discussed, or else use the "CBL-" named counterparts:

let config = ReplicatorConfiguration(database: cblDatabase, target: URLEndpoint(url: url)) // fails; no initializer available for ReplicatorConfiguration

let config = CBLReplicatorConfiguration(database: cblDatabase, target: CBLURLEndpoint(url: url)) // works

I'm a little confused as to why the CBL-named classes and the non-CBL (Swift-named) classes are even available. (It's a Swift-only project so far, and I've imported CouchbaseLiteSwift via CocoaPods. I would have though that bridging would have removed a layer of the redundancy, but admittedly I'm not too expert in ObjC/Swift bridging.)

> Yeah, it was like this recently. But some developers would modify the configuration after creating the Database from it, and then asking why their configuration wasn’t applied.

But DatabaseConfiguration is a struct, and in Swift, structs have "value" semantics. Therefore it is incorrect to expect that modifying a struct -- a copy of which was previously handed to another object -- should have any future effect. Accordingly, it seems unreasonable to penalize the programmer at init time in order to protect against such a mistake.

-ben

Jim Borden

unread,
Jan 24, 2018, 8:35:50 PM1/24/18
to Couchbase Mobile
> Therefore it is incorrect to expect that modifying a struct -- a copy of which was previously handed to another object -- should have any future effect.

That doesn't stop people from expecting it...and wasting time with questions about it 

Pasin Suriyentrakorn

unread,
Jan 24, 2018, 8:36:27 PM1/24/18
to mobile-c...@googlegroups.com, Jens Alfke
On Jan 24, 2018, at 4:17 PM, Ben Kennedy <ben.k...@kashoo.com> wrote:

On Jan 24, 2018, at 3:54 PM, Jens Alfke <je...@couchbase.com> wrote:

When there are a lot of optional properties for creating an object, it gets awkward to stuff all of them into one constructor/initializer method, so you create an object to hold the properties and then pass that to the constructor.

I agree with the principle, and am on board with the notion of a configuration object. But having to chain together a pile of methods to populate it, rather than simply exposing properties, feels needlessly unwieldy in my opinion.

Perhaps it's is a known issue, but the examples currently shown at https://url.emailprotection.link/?at5deUC_Tu3W-ZIIVdGCs1A9ZdNafh6GrLbBKCNkHC1UWV3cfBQQuBy5ij3LUHc8FHg9yCo7duB-SdiX7LE3Bw13CZ3bLtk5fKuoK72Kq2hc5sfLXWlme5hQmRQq8NcGb don't work. For example, to set up a replicator, it seems I'm forced either to use the method-chaining builder pattern previously discussed, or else use the "CBL-" named counterparts:


let config = ReplicatorConfiguration(database: cblDatabase, target: URLEndpoint(url: url)) // fails; no initializer available for ReplicatorConfiguration

let config = CBLReplicatorConfiguration(database: cblDatabase, target: CBLURLEndpoint(url: url)) // works

I'm a little confused as to why the CBL-named classes and the non-CBL (Swift-named) classes are even available. (It's a Swift-only project so far, and I've imported CouchbaseLiteSwift via CocoaPods. I would have though that bridging would have removed a layer of the redundancy, but admittedly I'm not too expert in ObjC/Swift bridging.)

Currently when using the Swift API, please do use the CBL-named classes as those are the objective-c API. This is a known issue that the Objective-C headers are also visible when using Swift API. We have written the Swift API on top of the Objective-C API and to make the Objective-C API visible to Swift, we need to make them public as well. It is something that we need to solve before the final 2.0 release.


Yeah, it was like this recently. But some developers would modify the configuration after creating the Database from it, and then asking why their configuration wasn’t applied.

But DatabaseConfiguration is a struct, and in Swift, structs have "value" semantics. Therefore it is incorrect to expect that modifying a struct -- a copy of which was previously handed to another object -- should have any future effect. Accordingly, it seems unreasonable to penalize the programmer at init time in order to protect against such a mistake.

-ben

--
You received this message because you are subscribed to the Google Groups "Couchbase Mobile" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mobile-couchba...@googlegroups.com.
To view this discussion on the web visit https://url.emailprotection.link/?acI2QHOlLUu5r3fIWsg0FuhkF2e47DmK1vgOYPYmLg0Klkq3k-e350TEq7W8IuGwl2Uo3eLQjo_Bu_eHXSFq5WAqW_ZZY2NVnZnHzf9gzBrXoE5TNDGd2D4Nbt75Gs8T956kZ8E4OVauY4jPiTaR3yfnfa4WMcd1y-bqqb_mL7J0~.
For more options, visit https://url.emailprotection.link/?acI2QHOlLUu5r3fIWsg0FukefuYIqVJU2gt8_envaf_7bRGVAePvclKgGlI5iD7VjZEtCv8mJsYVLH4A0CyroQQ~~.

Ben Kennedy

unread,
Jan 24, 2018, 9:47:03 PM1/24/18
to mobile-c...@googlegroups.com, Pasin Suriyentrakorn, Jens Alfke
> On Jan 24, 2018, at 5:36 PM, Pasin Suriyentrakorn <pa...@couchbase.com> wrote:
>
> Currently when using the Swift API, please do use the CBL-named classes as those are the objective-c API.

Thanks. I infer that you mean to say "do NOT use" the CBL-named classes in Swift?

And thus, to clarify, there is no alternative to the builder-method-chaining approach for initialization in Swift?

(It seems a bit cruel that the Obj C interface provides a more pleasant API. Ah well...)

cheers,

-ben

Jim Borden

unread,
Jan 24, 2018, 10:13:42 PM1/24/18
to Couchbase Mobile

Yes, the builder is the only current way to do it, but debate has arisen again internally as pointed out above.  However, we have very little room left to make more changes to the API and so there will be at maximum one more round of only minor changes.  We'll take into account this feedback.

Priya Rajagopal

unread,
Jan 24, 2018, 10:36:38 PM1/24/18
to Couchbase Mobile
Hey Ben
Quick note regarding :-

Perhaps it's is a known issue, but the examples currently shown at https://developer.couchbase.com/documentation/mobile/2.0/couchbase-lite/swift.html don't work. 

The examples in the documents correspond to Developer Build 21 (DB21) which is the latest officially released version available from our Downloads page (https://www.couchbase.com/downloads) .  You have been trying out the latest build which has not yet made it to our official downloads page and hence the docs don't reflect the changes.

Ben Kennedy

unread,
Jan 26, 2018, 7:37:38 PM1/26/18
to mobile-c...@googlegroups.com, Priya Rajagopal
> On Jan 24, 2018, at 7:36 PM, Priya Rajagopal <priya.r...@couchbase.com> wrote:
>
> The examples in the documents correspond to Developer Build 21 (DB21) which is the latest officially released version available from our Downloads page (https://www.couchbase.com/downloads) . You have been trying out the latest build which has not yet made it to our official downloads page and hence the docs don't
> reflect the changes.

A ha -- of course you're right; I've indeed checked out `feature/2.0`. I should have considered that possibility. Thanks.

Speaking of changes, I noticed that the `expires` param has recently been removed from CBLSessionAuthenticator. I suppose that makes sense, because looking at the diffs I see its value used to be simply ignored.

Clearly the onus is on me to track the cookie's lifetime locally, then, but what is the correct recourse once it expires? Should I just shut down and re-instantiate a new replicator? (Given that its configuration is immutable, I don't see a way to provide a fresh session cookie.)

thanks,

-ben

Jim Borden

unread,
Jan 26, 2018, 9:49:09 PM1/26/18
to Couchbase Mobile
The spirit of what you described is what you should do, but your replicator will shut down automatically once the session cookie expires because it will start getting unauthorized errors (I'm not sure why it was in the client API and so when it was reviewed it was removed, but as far as creating the session with Sync Gateway you can pass an expires value there and it will be honored).  This will be passed to the status callback.  At that time you can renew your session and start a new replicator.

Ben Kennedy

unread,
Jan 30, 2018, 3:45:18 PM1/30/18
to mobile-c...@googlegroups.com, Jim Borden
> On Jan 26, 2018, at 6:49 PM, Jim Borden <borr...@gmail.com> wrote:
>
> The spirit of what you described is what you should do, but your replicator will shut down automatically once the session cookie expires because it will start getting unauthorized errors (I'm not sure why it was in the client API and so when it was reviewed it was removed, but as far as creating the session with Sync Gateway you can pass an expires value there and it will be honored). This will be passed to the status callback. At that time you can renew your session and start a new replicator.

Thanks Jim. That sounds like the better approach over maintaining a local timer.

Now that I have a replication running against SG 1.5 (having moved back to 2.0DB021 after realizing that feature/2.0 is a bit too cutting-edge), I'm trying to get familiar with the new API using existing data.

We have documents with attachments created in 1.x using API like this:

[model setAttachmentNamed:attachmentName withContentType:@"image/png" content:UIImagePNGRepresentation(image)];
[model setValue:attachmentName ofProperty:kPropertyName];

which we would retrieve using those methods' reciprocal counterparts.

When retrieved in 2.0, I see the "_attachments" property on the document. However, I can't figure out how to acquire the blob using the new API. Neither using the attachment name nor property name as the argument for document.blob(forKey:) works; both return nil.

Have I missed some documentation on how this now works?

(Incidentally, speaking of documentation, there appear to be a couple of notable errors in the setup guide for SG 1.5 relating to support for CBL 2.0 replication. I submitted feedback via the page; see https://issues.couchbase.com/browse/DOC-3194.)

thanks,

-ben

James Nocentini

unread,
Feb 2, 2018, 12:58:43 PM2/2/18
to Couchbase Mobile
(Incidentally, speaking of documentation, there appear to be a couple of notable errors in the setup guide for SG 1.5 relating to support for CBL 2.0 replication. I submitted feedback via the page; see https://issues.couchbase.com/browse/DOC-3194.) 

Ben Kennedy

unread,
Feb 2, 2018, 1:14:33 PM2/2/18
to mobile-c...@googlegroups.com, James Nocentini
> On Feb 2, 2018, at 9:58 AM, James Nocentini <james.n...@gmail.com> wrote:
>
> (Incidentally, speaking of documentation, there appear to be a couple of notable errors in the setup guide for SG 1.5 relating to support for CBL 2.0 replication. I submitted feedback via the page; see https://issues.couchbase.com/browse/DOC-3194.)
>
> @Ben Thanks for letting us know! That should be fixed now https://developer.couchbase.com/documentation/mobile/1.5/guides/sync-gateway/config-properties/index.html#1.5/databases-foo_db-unsupported.

Hi James,

Part of it is fixed -- the default now reads 'false' rather than 'true'. However, the interoperability statement is still apparently wrong.

It reads:

> Note that if this property is set to true, Sync Gateway will no longer accept incoming requests from clients running the 1.x implementation. This includes Couchbase Lite 1.x and CouchDB-based databases (such as PouchDB and Cloudant).

We turned on the `unsupported.replicator_2` setting, and SG appears to be working just fine with Couchbase Lite 1.x clients.

The passage I quoted above is directly at odds with this statement in the CBL 2.0 setup guide at https://developer.couchbase.com/documentation/mobile/2.0/couchbase-lite/swift.html#story-h2-7 :

> Sync Gateway 1.5 will automatically use the 1.x replication protocol when a Couchbase Lite 1.x client connects through "http://localhost:4984/db" and the 2.0 replication protocol when a Couchbase Lite 2.0 client connects through "ws://localhost:4984/db".

Is or is not SG 1.5 intended to support both 1.x and 2.0 clients? Or have I misunderstood what the doc is trying to say?

cheers,

-ben

James Nocentini

unread,
Feb 2, 2018, 1:32:16 PM2/2/18
to Couchbase Mobile
Indeed, that isn't right. Updated that too to match with the statement in the Couchbase Lite API guide. Thanks!

Priya Rajagopal

unread,
Feb 2, 2018, 6:41:40 PM2/2/18
to paul....@sadasystems.com, Couchbase Mobile

Hey Paul

We are planning on going GA in the next month or so (exact timeline TBD). So 2.0 is pretty much feature complete and the focus right now is code hardening.

Since you are just starting off , worthwhile noting that there have some important bug fixes and API enhancements since DB021. So your options are (a) start with DB021 to get a good feel for the API  (b)  wait for our next release (should be out reasonably soon) or (c) pull and build from source directly to get the latest and greatest.

 

We would love to get your feedback on 2.0 and whether it handles your thread safety issues…

 

Regards

-Priya

 

From: <paul....@sadasystems.com>
Date: Friday, February 2, 2018 at 6:16 PM
To: Couchbase Mobile <mobile-c...@googlegroups.com>
Subject: Re: Announcing Release of Couchbase Lite 2.0 Developer Build 21 (DB 21)

 

Congratulations (and hi), I'm excited to start working with Couchbase 2 if the time is right, as the threading issues with Couchbase 1.4 have been.. challenging. I know this is a very subjective question but, roughly how stable is this code now? Would you use it in a production environment? Or if not, does it feel close? I'm growing tired of crashes related to multiple threads accessing the database at the same time and I can either go through and put everything in queues (not sure yet if NSOperation or dispatch), or try switching to 2.0 which I expect I'd end up doing in time anyway.

Thanks in advance for any opinions or info anyone with relevant experience would like to share.


On Thursday, December 21, 2017 at 6:52:52 AM UTC-8, Priya Rajagopal wrote:

paul....@sadasystems.com

unread,
Feb 2, 2018, 7:54:36 PM2/2/18
to Couchbase Mobile
Congratulations (and hi), I'm excited to start working with Couchbase 2 if the time is right, as the threading issues with Couchbase 1.4 have been.. challenging. I know this is a very subjective question but, roughly how stable is this code now? Would you use it in a production environment? Or if not, does it feel close? I'm growing tired of crashes related to multiple threads accessing the database at the same time and I can either go through and put everything in queues (not sure yet if NSOperation or dispatch), or try switching to 2.0 which I expect I'd end up doing in time anyway.
Thanks in advance for any opinions or info anyone with relevant experience would like to share.

On Thursday, December 21, 2017 at 6:52:52 AM UTC-8, Priya Rajagopal wrote:

Paul Jacobs

unread,
Feb 2, 2018, 7:54:36 PM2/2/18
to Priya Rajagopal, Couchbase Mobile
Very interesting to hear that.. thank you for laying out the options so clearly. I'm not sure what I'll do yet, I'll think things through, look through the APIs, try it out, etc. I will let you know if I have feedback, it may be a while before I can try integrating enough to answer whether it fixes the issues. 

Best Wishes,
Paul
--

Paul Jacobs

Senior iOS Developer | Geo - ATOM

SADA Systems

Direct: 805-358-7634 | SADASystems.com  

Cloud Computing | Consulting | Managed Services | App Development

Google Partner of the Year: 2013 | 2014 | 2015 2016

Jens Alfke

unread,
Feb 2, 2018, 7:59:25 PM2/2/18
to Couchbase Mobile, Jim Borden


On Jan 30, 2018, at 12:45 PM, Ben Kennedy <ben.k...@kashoo.com> wrote:

When retrieved in 2.0, I see the "_attachments" property on the document. However, I can't figure out how to acquire the blob using the new API. Neither using the attachment name nor property name as the argument for document.blob(forKey:) works; both return nil.

This is a bug in CBL-iOS: it didn’t recognize the objects in the _attachments dictionary as being blobs. It’s been fixed, but I think the fix won’t appear until after beta/DB22.

—Jens

Jens Alfke — Mobile Architect — Couchbase, Inc.

Jens Alfke

unread,
Feb 2, 2018, 8:04:54 PM2/2/18
to Couchbase Mobile


On Feb 2, 2018, at 3:16 PM, paul....@sadasystems.com wrote:

I'm growing tired of crashes related to multiple threads accessing the database at the same time and I can either go through and put everything in queues (not sure yet if NSOperation or dispatch), or try switching to 2.0 which I expect I'd end up doing in time anyway.

2.0 will provide more thread-safety, but you can still get yourself in trouble. For example, modifying the same document on two threads at once will create a conflict, and it gets worse if you’re using the same CBLDocument object on multiple threads, since the value of a property will depend on which thread wrote to it last.

If you’re having trouble keeping track of which threads/queues your code is running on, that’s a “code smell” that can indicate trouble with your design. (Not saying this to insult you; I’ve definitely been there myself!)

Jim Borden

unread,
Feb 9, 2018, 11:50:18 PM2/9/18
to Couchbase Mobile
Hey, just wanted to chime in and let you know that the discussion about the builder API ended with the "remove it" side winning.  We are back to regular configuration objects with DB022, except that once they are used inside of their various objects they become "frozen" and further attempts to edit them will result in errors.
Reply all
Reply to author
Forward
0 new messages