been doing android development for the past 4 years • currently working at Homestars Inc. but moving on to Hootsuite Inc. soon • love working with Kotlin
due to code sharing. • Avoid developer frustration when it comes to IDEs, SDKs, and platform specific requirements. • Third party integration would be ‘lighter’. • Bug tracking is easier as codebase is shared. • Hybrid apps get build faster. • Faster initial speed to market. • Fast deploy of updates. • Less secure compared to native. • Distribution platforms allow more visibility to native apps. • Total dependence on the framework forces you to develop features to cater the framework’s needs.
development provided by JetBrains. It uses the multiplatform capabilities of Kotlin and includes various tools and features designed to make the end-to-end experience of building mobile cross-platform applications as enjoyable and efficient as possible.”
shared among all the platforms shared module will hold the shared business logic. This logic can be further dissected into platform specific directories androidMain & iosMain directories will hold the business logic that will be shared among the respective platform’s feature module
• If iOS specific-code needs to be written, then Xcode version 11.3 or higher • Compatible Kotlin compiler plugin • Kotlin Multiplatform Mobile plugin • JDK
shared among all the platforms shared module will hold the shared business logic. This logic can be further dissected into platform specific directories androidMain & iosMain directories will hold the business logic that will be shared among the respective platform’s feature module
val missionName: String, @SerialName("launch_year") val launchYear: Int, @SerialName("launch_date_utc") val launchDateUTC: String, @SerialName("rocket") val rocket: Rocket, @SerialName("details") val details: String?, @SerialName("launch_success") val launchSuccess: Boolean?, @SerialName("links") val links: Links ) @Serializable data class Rocket( @SerialName("rocket_id") val id: String, @SerialName("rocket_name") val name: String, @SerialName("rocket_type") val type: String ) @Serializable data class Links( @SerialName("mission_patch") val missionPatchUrl: String?, @SerialName("article_link") val articleUrl: String? )
missionName: String, @SerialName("launch_year") val launchYear: Int, @SerialName("launch_date_utc") val launchDateUTC: String, @SerialName("rocket") val rocket: Rocket, @SerialName("details") val details: String?, @SerialName("launch_success") val launchSuccess: Boolean?, @SerialName("links") val links: Links ) @Serializable data class Rocket( @SerialName("rocket_id") val id: String, @SerialName("rocket_name") val name: String, @SerialName("rocket_type") val type: String ) @Serializable data class Links( @SerialName("mission_patch") val missionPatchUrl: String?, @SerialName("article_link") val articleUrl: String? ) Entity.kt(com.kdhillon.spacex.shared.entity)
... } sqldelight { database("AppDatabase") { // The packageName parameter specifies the package name for the generated Kotlin sources. packageName = "com.kdhillon.spacex.shared.cache" } }
sqldelight { database("AppDatabase") { // The packageName parameter specifies the package name for the generated Kotlin sources. packageName = "com.kdhillon.spacex.shared.cache" } } Build.gradle.kts (shared)
TEXT NOT NULL, launchYear INTEGER AS Int NOT NULL DEFAULT 0, rocketId TEXT NOT NULL, details TEXT, launchSuccess INTEGER AS Boolean DEFAULT NULL, launchDateUTC TEXT NOT NULL, missionPatchUrl TEXT, articleUrl TEXT ); CREATE TABLE Rocket ( id TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL );
NOT NULL, launchYear INTEGER AS Int NOT NULL DEFAULT 0, rocketId TEXT NOT NULL, details TEXT, launchSuccess INTEGER AS Boolean DEFAULT NULL, launchDateUTC TEXT NOT NULL, missionPatchUrl TEXT, articleUrl TEXT ); CREATE TABLE Rocket ( id TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL ); AppDatabase.sq
TEXT NOT NULL, launchYear INTEGER AS Int NOT NULL DEFAULT 0, rocketId TEXT NOT NULL, details TEXT, launchSuccess INTEGER AS Boolean DEFAULT NULL, launchDateUTC TEXT NOT NULL, missionPatchUrl TEXT, articleUrl TEXT ); CREATE TABLE Rocket ( id TEXT NOT NULL PRIMARY KEY, name TEXT NOT NULL, type TEXT NOT NULL );
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) expect class DatabaseDriverFactory { fun createDriver(): SqlDriver }
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) actual class DatabaseDriverFactory(private val context: Context) { actual fun createDriver(): SqlDriver { return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db") } }
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) actual class DatabaseDriverFactory(private val context: Context) { actual fun createDriver(): SqlDriver { return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db") } }
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) actual class DatabaseDriverFactory(private val context: Context) { actual fun createDriver(): SqlDriver { return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db") } } actual class DatabaseDriverFactory { actual fun createDriver(): SqlDriver { return NativeSqliteDriver(AppDatabase.Schema, "test.db") } }
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) actual class DatabaseDriverFactory(private val context: Context) { actual fun createDriver(): SqlDriver { return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db") } } actual class DatabaseDriverFactory { actual fun createDriver(): SqlDriver { return NativeSqliteDriver(AppDatabase.Schema, "test.db") } }
private val dbQuery = database.appDatabaseQueries } Database.kt(com.kdhillon.spacex.shared.cache) actual class DatabaseDriverFactory(private val context: Context) { actual fun createDriver(): SqlDriver { return AndroidSqliteDriver(AppDatabase.Schema, context, "test.db") } } actual class DatabaseDriverFactory { actual fun createDriver(): SqlDriver { return NativeSqliteDriver(AppDatabase.Schema, "test.db") } }
and the public API’s are expected to be changed frequently given its scale. • Deploying a KMM project in production therefore should be prohibited. • A lot of edge-cases might be encountered when working in KMM, such as how to manage sensitive information.