Manager

A Manager is the top-level object that manages a collection of Couchbase Lite Database instances. You need to create a Manager instance before you can work with Couchbase Lite objects in your Application.

Creating a manager


You create a Manager object by calling a constructor or initializer on the Manager class. In Objective-C you can also call [CBLManager sharedInstance] which returns a global instance; this instance should only be used on the main thread, however.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    /*
     * In Objective-C the <code>Manager</code> shared instance and all the objects descending
     * from it may only be used on the main thread.
     */                      
    CBLManager *manager = [CBLManager sharedInstance];
    if (!manager) {
        NSLog(@"Cannot create Manager instance");
        exit(-1);
    }
    return YES;
}
public class Application extends android.app.Application {
    private Manager manager;
    private static Context mContext;
    
    ...
    
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        try {
            /*
             * In Java the Manager instance and all the objects descending
             * from it may be used on any thread.
             */
            manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);
        } catch (IOException e) {
            Log.e(TAG, "Cannot create Manager instance", e);
            return;
        }
    }
}
public class Application extends android.app.Application {
    private Manager manager;
    private static Context mContext;
    
    ...
    
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        try {
            /*
             * In Java the Manager instance and all the objects descending
             * from it may be used on any thread.
             */
            manager = new Manager(new AndroidContext(mContext), Manager.DEFAULT_OPTIONS);
        } catch (IOException e) {
            Log.e(TAG, "Cannot create Manager instance", e);
            return;
        }
    }
}
No code example is currently available.

Dude, where's my database file?

The Manager creates a directory in the filesystem and stores databases inside it. Normally, you don't need to care where that is -- your application shouldn't be directly accessing those files. But sometimes it does matter.

Caution:One notable case where the location can be important is on iOS: Apple's app review process tries to make sure that the only application data that will be backed up to iCloud is data created by the user. So it's a red flag when, on first launch, an app creates data in backed-up locations (including the Documents and Application Support directories) without user action. Unfortunately, that will happen if your app starts a pull replication on launch, or installs a pre-populated database. Some apps using Couchbase Lite have had their App Store approval held up for this reason!

On iOS or Mac OS you can change the location of the databases by instantiating the Manager via a constructor/initializer that takes a path as a parameter. This directory will be created if it doesn't already exist. (Of course you should be consistent about what path to use, since if you change the path the application won't be able to find any already-existing databases.)

On Android, you can subclass com.couchbase.lite.Context and override its getFilesDir method to return the desired directory.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSString* dir = WhereIWantCBLStuffToGo();
    NSError* error;
    self.manager = [[CBLManager alloc] initWithDirectory: dir
                                                 options: NULL
                                                   error: &error];
    if (!manager) {
        NSLog(@"Cannot create Manager instance: %@", error);
        exit(-1);
    }
    return YES;
}
No code example is currently available.
No code example is currently available.
No code example is currently available.

Manager options


By default a Manager will open a Database with read/write access. If you want to ensure that data can not be modified you can restrict Database access to read only by passing a ManagerOptions object to the Manager constructor or initilaizer.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSError* error;
    CBLManagerOptions options;
    options.readOnly = YES;
    CBLManager *manager = [[CBLManager alloc] initWithDirectory: CBLManager.defaultDirectory options: &options error: &error ];
    if (error) {
        NSLog(@"Cannot create Manager instance with custom options");
        exit(-1);
    }
    return YES;
}
public class Application extends android.app.Application {
    private Manager manager;
    private static Context mContext;
    
    ...
    
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        try {
            ManagerOptions customOptions = new ManagerOptions();
            customOptions.setReadOnly(true);
            manager = new Manager(new AndroidContext(mContext), customOptions);
        } catch (IOException e) {
            Log.e(TAG, "Cannot create Manager instance with custom options", e);
            return;
        }
    }
}
public class Application extends android.app.Application {
    private Manager manager;
    private static Context mContext;
    
    ...
    
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        try {
            ManagerOptions customOptions = new ManagerOptions();
            customOptions.setReadOnly(true);
            manager = new Manager(new AndroidContext(mContext), customOptions);
        } catch (IOException e) {
            Log.e(TAG, "Cannot create Manager instance with custom options", e);
            return;
        }
    }
}
No code example is currently available.

Global logging settings


You can customize the global logging settings for Couchbase Lite via the Mananger class.

Log messages are tagged, allowing them to be logically grouped by activity. You can control whether individual tag groups are logged, in Java it is also possible to set log levels for each tag group.

In Objective-C tag groups is disabled by default, in Java tag groups are enabled at level WARN by default. The available tags are:

BLIP
BLIPVerbose
CBLDatabase
CBLJSONMatcher
CBLListener
CBLListenerVerbose
CBLModel
CBL_Router
CBL_Server
CBL_URLProtocol
CBLValidation
CBLRemoteRequest
CBLMultiStreamWriter
ChangeTracker
ChangeTrackerVerbose
JSONSchema
MYDynamicObject
Query
RemoteRequest
Sync
SyncVerbose
View
ViewVerbose
WS
BlobStore
CBLite // default "catch-all" tag
ChangeTracker
Database
Listener
MultistreamWriter
Query
RemoteRequest
Router
Sync
View
   
BlobStore
CBLite // default "catch-all" tag
ChangeTracker
Database
Listener
MultistreamWriter
Query
RemoteRequest
Router
Sync
View
   
No code example is currently available.

You would enable the "Sync" tag group by calling the enableLogging method on the Managerclass. In Java you may also set the logging level.

- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
CBLManager enableLogging: @"Sync"];
eturn YES;
public class Application extends android.app.Application {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        Manager.enableLogging("Sync", Log.VERBOSE);
        ...
    }
}
 
public class Application extends android.app.Application {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        ...
        Manager.enableLogging("Sync", Log.VERBOSE);
        ...
    }
}
 
No code example is currently available.

In Java the Log class provides static constants for the default tag groups:

and static constants for the supported logging levels:

Concurrency Support


Note:In Java all Couchbase Lite objects may be shared freely between threads. The rest of this section is irrelevant for Java programs, and applies only to Objective-C.

In Objective-C, a Manager instance and the object graph associated with it may only be accessed from the thread or dispatch queue that created the Manager instance. Concurrency is supported through explicit method calls.

Running individual blocks in the background

You can use the CBLManager method backgroundTellDatabaseNamed:to: to perform any operation in the background. Be careful with this, though! Couchbase Lite objects are per-thread, and your block runs on a background thread, so:

In general, it’s best to do only very limited things using this API, otherwise it becomes too easy to accidentally use main-thread Couchbase Lite objects in the block, or store background-thread Couchbase Lite objects in places where they’ll be called on the main thread.

Here’s an example that deletes a number of documents given an array of IDs:

// "myDB" is the CBLDatabase object in use on the main thread.
CBLManager* mgr = myDB.manager;
NSString* name = myDB.name;
[mgr backgroundTellDatabaseNamed: name to: ^(CBLDatabase *bgdb) {
    // Inside this block we can't use myDB; instead use the instance given (bgdb)
    for (NSString* docID in docIDs) {
        [[bgdb documentWithID: docID] deleteDocument: nil];
}];

Running Couchbase Lite on a background thread

If you want to do lots of Couchbase Lite processing in the background in Objective-C, the best way to do it is to start your own background thread and use a new Manager instance on it.

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CBLManager *manager = [CBLManager sharedInstance];
    NSError* error;
    self.database = [manager databaseNamed: @"db" error: &error];
    
    // We also want to run some Couchbase Lite operations on a background thread.
    // Since we can't use the regular CBLManager instance there, we copy it
    // and pass the copy to the background thread to use:
    CBLManager* bgMgr = [manager copy];
    [NSThread detachNewThreadSelector: @selector(runBackground:)
                             toTarget: self 
                           withObject: bgMgr];
    return YES;
}
- (void) runBackground: (CBLManager*)bgMgr {
    NSError* error;
    CBLDatabase* bgDB = [bgMgr databaseNamed: @"db" error: &error];
    // ... now use bgDB
}

If you don't plan to use Couchbase Lite on the main thread at all, the setup is even easier. Just have the background thread create a new instance of CBLManager from scratch and use that:

- (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // We're not going to use Couchbase Lite at all on the main thread;
    // instead we start a background thread to run it on:
    [NSThread detachNewThreadSelector: @selector(runBackground)
                             toTarget: self 
                           withObject: nil];
    return YES;
}
- (void) runBackground {
    // Create a CBLManager instance to use on this background thread:
    CBLManager* manager = [[CBLManager alloc] init];
    NSError* error;
    CBLDatabase* db = [manager databaseNamed: @"db" error: &error];
    // ... now use the database
}