Saving data on background thread

192 views
Skip to first unread message

Ragu Vijaykumar

unread,
May 17, 2014, 6:52:01 PM5/17/14
to mobile-c...@googlegroups.com
When using CoreData, I was able to accomplish background saving with a parent NSManagedObjectContext in the background, and a child NSManagedObjectContext on the main thread. Any saves on the main UI thread to NSManagedObjects would then save in the background without disrupting the UI. I've been trying to figure out how to accomplish the same sort of behavior with CBL - Is there any way to accomplish this with CBL?

Cheers,
Ragu

Pascal

unread,
May 17, 2014, 9:05:03 PM5/17/14
to mobile-c...@googlegroups.com

Ragu Vijaykumar

unread,
May 18, 2014, 9:33:54 AM5/18/14
to mobile-c...@googlegroups.com
So, this is safe to call even if all my models were created / accessed on the main thread?

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

        NSError* error;

        CBLDatabase* database = [[[CBLManager sharedInstance] copy] existingDatabaseNamed:@"mydatabase" error:&error];

        [database saveAllModels:&error];

    });

Pascal

unread,
May 18, 2014, 11:43:46 AM5/18/14
to mobile-c...@googlegroups.com
No, this is not good. The documentation I linked you to, more specifically http://docs.couchbase.com/couchbase-lite/cbl-ios/#create-a-background-cblmanager , mentions that you should NOT call `sharedInstance` on a background thread. Use the example provided and see if that works for you.

Ragu Vijaykumar

unread,
May 19, 2014, 8:51:25 AM5/19/14
to mobile-c...@googlegroups.com
Yeah, but even if I make the copied CBLManager on the main thread, the models I have on the main thread won't be accessible through that background CBLManager. I'm wondering if there is a way to resolve that?

Pascal

unread,
May 20, 2014, 9:54:11 PM5/20/14
to mobile-c...@googlegroups.com
You will have to instantiate the models again on the background thread. This is what I do, it's very simple anyway with [MYModel modelForDocument:row.document] (or the factory class). Just pass in document ids, I do that on an export task that runs in a background queue and base64 encodes image attachments, so this may run a while but doesn't block the UI.

Jens Alfke

unread,
May 22, 2014, 12:59:19 PM5/22/14
to mobile-c...@googlegroups.com

On May 18, 2014, at 6:33 AM, Ragu Vijaykumar <ra...@scrxpt.com> wrote:

> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
> NSError* error;
> CBLDatabase* database = [[[CBLManager sharedInstance] copy] existingDatabaseNamed:@"mydatabase" error:&error];
> [database saveAllModels:&error];
> });

There are a couple of things wrong here —

1. The shared instance of CBLManager should only be used on a single thread (usually the main thread.)
2. There’s an existing method -[CBLManager backgroundTellDatabaseNamed:to:] to run code on a background thread, so you don’t need to go through the work.
3. Even if you do that, this code won’t do anything because the background thread’s database instance doesn’t have any CBLModels.

Unfortunately there isn’t really a clean way to do what you’re asking, yet. An implementation of this would need to collect the -propertiesToSave from each modified CBLModel, send that data to the background thread and save the properties to the corresponding CBLDocuments, and then back on the main thread mark the models as unmodified as soon as the change notification arrives. The last step in particular is tricky and I don’t think it can be done with the public API.

Are you having performance problems saving? If so I’d love to see some profile data from Instruments.

—Jens
Reply all
Reply to author
Forward
0 new messages