Copenhagen Denmark
SHIPPING MULTIPLATFORM ON IOS & ANDROID BEN ASHER ALEC STRONG
@benasher44 @strongolopolis
SHIPPING MULTIPLATFORM ON IOS & ANDROID BEN ASHER ALEC STRONG - - PowerPoint PPT Presentation
SHIPPING MULTIPLATFORM ON IOS & ANDROID BEN ASHER ALEC STRONG @benasher44 @strongolopolis Copenhagen Denmark SHIPPING MULTIPLATFORM ON IOS & ANDROID BEN ASHER ALEC STRONG @benasher44 @strongolopolis Copenhagen Denmark Markups
Copenhagen Denmark
@benasher44 @strongolopolis
Copenhagen Denmark
@benasher44 @strongolopolis
Link to another sheet Markups
History
Live Info
Championed on iOS ~15 across Android and iOS Construction Championed on Android ~30 across Android and iOS Financial Services
Offline Sync System Search Business Logic
Business Logic Models
MPP
Business Logic Models
MPP
Business Logic Models
MPP
MPP Kotlin/Native
New tools New language Uneven ecosystem
No JNI
Obj-C Interop Not New For Android Community Jetbrains
Kotlin/Native relies on Obj-C? What about Swift?
Obj-C header is well-annotated for Swift This is the status quo for Apple’s own frameworks
What about performance?
Same performance expectations on Android Can drop into C if needed on iOS
What about value types?
There’s a garbage collector? But there’s no JVM, right? Bacon’s Algorithm for GC
What libraries can we use for mpp?
JVM Distributions are incomplete Special multiplatform distributions K/N ABI instability (klib)
What is “common” code?
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets Code expect class Lock actual class Lock actual class Lock
expect class Lock actual class Lock actual class Lock
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets
commonMain iosMain androidMain iOS - .framework Android - .aar
Library Outputs Library Source Sets
windowsMain Windows - .dll
Is it platform agnostic? commonMain
Yes No
Will other common code use it?
Yes No
Platform
Is it platform agnostic? commonMain
Yes No
Will other common code use it?
Yes No
Platform
Is it platform agnostic?
No
Will other common code use it? commonMain
Yes
expect class DatabaseFactory { internal fun createSqliteDriver(): SqlDriver }
Is it platform agnostic?
No
Will other common code use it?
No
Platform
sourceSets {A commonMain {B}C androidLibMain {D}E iosLibMain {F}G }H
sourceSets {A commonMain {B}C androidLibMain {D dependencies {I api project(‘:protos') }J }E iosLibMain {F}G }H
fun SearchQueries.insert(entity: SyncEntity) entity: SyncEntity
sourceSets {A commonMain {B}C androidLibMain {D}E iosLibMain {F}G }H
sourceSets {A commonMain {B}C androidLibMain {D}E }H
Is it platform agnostic? commonMain
Yes
fun search(terms: String): List<Search>?
commonMain iosMain androidMain
Library Source Sets
Host Application
Host Application
Talks to backend API Talks to existing application state
Host Application commonMain
Library Initialization
Library defines interface App provides implementation
Highly platform-specific Backend API Hosts Current user’s credential
Make an API request Receive an async response Interface can be re-implemented later
interface Network { /** * Makes an API request */ fun makeRequest( host: APIHost, request: Request, completion: (Request.Response) -> Unit ): NetworkDisposable }
interface Network { /** * Makes an API request */ fun makeRequest( host: APIHost, request: Request, completion: (Request.Response) -> Unit ): NetworkDisposable } host: APIHost Plain enum of names of the hosts– no URL handling required
interface Network { /** * Makes an API request */ fun makeRequest( host: APIHost, request: Request, completion: (Request.Response) -> Unit ): NetworkDisposable } request: Request data class:
interface Network { /** * Makes an API request */ fun makeRequest( host: APIHost, request: Request, completion: (Request.Response) -> Unit ): NetworkDisposable } completion: (Request.Response) -> Unit sealed class w/ different response types:
interface Network { /** * Makes an API request */ fun makeRequest( host: APIHost, request: Request, completion: (Request.Response) -> Unit ): NetworkDisposable } NetworkDisposable Interface with a cancel() method
suspend fun Network.makeRequest( host: APIHost, request: Request ): Request.Response
commonMain iosMain androidMain
expect fun <T> T.freeze(): T actual fun <T> T.freeze(): T = this actual fun <T> T.freeze(): T = freeze()
commonMain iosMain androidMain Host Application
commonMain iosMain androidMain Host Application Host Application
commonMain iosMain androidMain Host Application Host Application
Minimal change for android Seamless local development Single source of truth Host dependencies Two build environments for iOS CI Nightmare
commonMain iosMain androidMain Host Application Host Application
commonMain iosMain androidMain Host Application Host Application
commonMain commonMain iosMain androidMain Host Application Host Application
commonMain iosMain androidMain Host Application Host Application commonMain
Minimal change for android Seamless local development Host dependencies Two build environments for iOS CI Nightmare for iOS Out of sync code
commonMain iosMain androidMain Host Application Host Application
commonMain iosMain androidMain Host Application Host Application
CI is fast Encourages unit test coverage Single source of truth Breaking changes are painful Need good CD setup Debugging decoupled repos
commonMain iosMain androidMain Host Application Host Application
commonMain iosMain Host Application Host Application androidMain
commonMain androidMain Host Application Host Application
fun crash() { (null as String?)!! }
setUnhandledExceptionHook()
Define your project’s goals Be thoughtful growing your codebase Avoid solving general muliplatform problems Get your CI and dev setup working early Join us in Kotlin slack
#KotlinConf
Ben Asher @benasher44 Alec Strong @Strongolopolis