Observables in a remote interface are reactive streams of Event
instances in
Kotlin that, when connected to a Web Frame, can push data to the web
layer. They are implemented with
Asynchronous Flows,
a powerful coroutine-based reactive programming library built by the Kotlin team
, which means they are instances of
Flows.
Examples
Observables can be declared any number of ways. The following examples are for a remote observable that sends events every time the network connection changes.
Declared as a class property
class Network {
val visible = MutableSharedFlow<Event>()
}
Declared as a variable
val networkConnection = MutableSharedFlow<Event>()
Web Frame Configuration
For the following example, we’ll be using an observable declared like the following:
val networkConnection = MutableSharedFlow<Event>()
The observable reference can be passed directly to the Web Frame configuration.
Although you can add an instance of MutableSharedFlow
directly to the Web
Frame configuration, it is a good idea to convert it to an immutable flow first
by using
.asSharedFlow()
.
val configuration = WebFrame.Configuration(
baseUrl = ...
functions = ...
observables = mapOf(
"networkConnection$": networkConnection.asSharedFlow()
),
)
Observables must end in a dollar sign ($
) to denote a reactive property, as
popularized by Cycle.js. This isn’t merely
convention—the dollar sign is how ProxyClient knows it’s an observable, not a
function.
Kotlin API
Event
Remote observables must emit Event
objects, which represent a single value
sent to the web layer.
Constructors
Event(val data: JsonElement)
Create an Event
object with arbitrary data.
Data must be JSON content on Android. One delightful way of creating arbitrary
JSON content is by using the
buildJsonObject
helper from the KotlinX Serialization library:
val event = Event(buildJsonObject {
put("type", "wifi")
})
inline fun <reified T> Event(json: T)
Technically not a constructor, this function can be used to instantiate Event objects with any serializable object.
The easiest way to make a class serializable is by annotating it with
@Serializable
from the KotlinX Serialization library:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class Connection(val type: String)
Then, objects can be passed to this constructor directly:
val event = Event(Connection("wifi"))
This constructor will throw an error if encoding fails (highly unlikely).
This function uses
Json.encodeToJsonElement
under the hood to serialize almost any data type: strings, booleans, ints,
doubles, as well as any instances of classes annotated with @Serializable
. For
more information, see the docs for
KotlinX Serialization.