Kotlin

    Description — Couchbase Lite for Android — Kotlin support
    Related Content — Databases | Documents | Indexing |

    Introduction

    Couchbase Lite Android 4.0.3 introduces full idiomatic support for Kotlin apps, out-of-the-box.

    Kotlin developers can now build apps using common Kotlin Patterns, that integrate seamlessly with Couchbase Lite for Android and have full feature parity with the Java API; including some convenient Kotlin Extensions to get you started.

    Key features include:

    • Nullability annotations

    • Named parameters

    • Kotlin Flows, for asynchronous event notifications

    Java support and functionality continues for Android.

    Kotlin Extensions

    In addition to having full co-compatible access to the existing Java API, Kotlin developers can also access a number of Kotlin Extensions.

    The Kotlin Extensions package includes:

    • Configuration Factories for the configuration of important Couchbase Lite objects such as Databases, Replicators and Listeners.

    • Change Flows that monitor key Couchbase Lite objects fpr change using Kotlin features such as, Co-routines and Flows.

    See: Kotlin Extensions for extension API docs

    Configuration Factories

    Couchbase Lite provides a set of ConfigurationFactories and CommonConfigurationFactories, these allow use of named parameters to specify property settings.

    This makes it simple to create variant configurations, by simply overriding named parameters:

    Example of overriding configuration
    val listener8080 = URLEndpointListenerConfigurationFactory.newConfig(
        networkInterface = "en0",
        port = 8080
    )
    val listener8081 = listener8080.newConfig(port = 8081)

    Database

    Use DatabaseConfigurationFactory to create a DatabaseConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    database = Database("getting-started")
    val DatabaseConfigurationFactory: DatabaseConfiguration? = null
    
    fun DatabaseConfiguration?.newConfig(
        databasePath: String? = null,
        encryptionKey: EncryptionKey? = null,
        fullSync: Boolean? = null,
    )

    Replication

    Use ReplicatorConfigurationFactory to create a ReplicatorConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    val replicator =
        Replicator(
            ReplicatorConfigurationFactory.newConfig(
                collections = CollectionConfiguration.fromCollections(db.collections),
                target = URLEndpoint(URI("ws://localhost:4984/getting-started-db")),
                type = ReplicatorType.PUSH_AND_PULL,
                authenticator = BasicAuthenticator("sync-gateway", "password".toCharArray())
            )
        )
    val ReplicatorConfigurationFactory: ReplicatorConfiguration? = null
    
    fun ReplicatorConfiguration.newConfig(
        collections: Set<CollectionConfiguration>,
        target: Endpoint,
        type: ReplicatorType? = null,
        continuous: Boolean? = null,
        authenticator: Authenticator? = null,
        headers: Map<String, String>? = null,
        pinnedServerCertificate: X509Certificate? = null,
        maxAttempts: Int? = null,
        maxAttemptWaitTime: Int? = null,
        heartbeat: Int? = null,
        enableAutoPurge: Boolean? = null,
        acceptOnlySelfSignedServerCertificate: Boolean? = null,
        acceptParentDomainCookies: Boolean? = null
    )
    
    val MessageEndpointListenerConfigurationFactory: MessageEndpointListenerConfiguration? = null
    
    fun MessageEndpointListenerConfiguration?.create(
        database: Database? = null,
        protocolType: ProtocolType? = null
    )

    Use FullTextIndexConfigurationFactory to create a FullTextIndexConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    collection.createIndex(
        "overviewFTSIndex",
        FullTextIndexConfigurationFactory.newConfig("overview")
    )
    val FullTextIndexConfigurationFactory: FullTextIndexConfiguration? = null
    
    fun FullTextIndexConfiguration?.create(expression: String? = null)

    Indexing

    Use ValueIndexConfigurationFactory to create a ValueIndexConfiguration object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    collection.createIndex(
        "TypeNameIndex",
        ValueIndexConfigurationFactory.newConfig("type", "name")
    )
    val ValueIndexConfigurationFactory: ValueIndexConfiguration? = null
    
    fun ValueIndexConfiguration?.create(vararg expressions: String = emptyArray())

    Logs

    Use FileLogSinkFactory to create a FileLogSink object, overriding the receiver’s values with the passed parameters.

    • In Use

    • Definition

    FileLogSinkFactory.install(
        directory = context.cacheDir.absolutePath, (1)
        level = LogLevel.INFO, (2)
        maxFileSize = 10240L, (3)
        maxKeptFiles = 5, (4)
        isPlainText = false (5)
    )
    val FileLogSinkFactory: FileLogSink? = null
    
    fun FileLogSinkFactory?.install(
        directory: String? = null,
        level: LogLevel? = null,
        maxFileSize: Long? = null,
        maxKeptFiles: Int? = null,
        isPlainText: Boolean? = null
    )

    Flows

    These wrappers use Flowables to monitor for changes.

    Replicator Change Flow

    Use replicatorChangeFlow(Replicator,Executor) to monitor replicator changes.

    • In Use

    • Definition

    val replState = repl.replicatorChangesFlow()
        .map { it.status.activityLevel }
        .asLiveData()
    @ExperimentalCoroutinesApi
    fun Replicator.replicatorChangesFlow(executor: Executor? = null)

    Document Replicator Change Flow

    Use documentReplicationFlow(Replicator,Executor) to monitor document changes during replication.

    • In Use

    • Definition

    val replicatedDocs = repl.documentReplicationFlow(testSerialExecutor)
        .map { update -> update.documents }
        .onEach { listView.setUpdated(it) }
        .collect()
    @ExperimentalCoroutinesApi
    fun Replicator.documentReplicationFlow(executor: Executor? = null)

    Query Change Flow

    Use queryChangeFlow(Query,Executor) to monitor document changes during replication.

    • In Use

    • Definition

    fun watchQuery(query: Query): LiveData<List<Result>> {
        return query.queryChangeFlow()
            .mapNotNull { change ->
                val err = change.error
                if (err != null) {
                    throw err
                }
                change.results?.allResults()
            }
            .asLiveData()
    }
    @ExperimentalCoroutinesApi
    fun Query.queryChangeFlow(executor: Executor? = null)