Blog

Kotlin Multiplatform + Kotlin/Native: alternatywa dla Xamarin?

Czy Kotlin Multiplatform i Kotlin/Native mogą zastąpić Xamarin? Architektura demo dla Androida i iOS, konfiguracja Gradle, moduły common, expect/actual, warstwa danych oraz plusy i ograniczenia podejścia.

Mateusz Kopta

Wprowadzenie

Kotlin 1.2 przyniósł eksperymentalne Kotlin Multiplatform Projects, które pozwalają współdzielić kod między platformami JVM (Android, desktop, web). Równolegle Kotlin/Native kompiluje Kotlin bez VM do natywnych binariów na iOS, macOS czy systemy wbudowane.

Połączmy te technologie i zbudujmy prostą, mobilną aplikację na Android i iOS: przeglądarkę zdjęć z NASA Astronomy Picture of the Day.

Build system i IDE

Multiplatform opiera się wyłącznie na Gradle.

Dostępne są template w IntelliJ 2017.3 oraz wtyczka Kotlin/Native do AppCode 2018.1.1. W praktyce wygodnie jest użyć Android Studio do modułów Android i common oraz Xcode do części iOS.

Struktura projektu

- Android: klasyczna aplikacja zależna od modułu platform-android.

- iOS: projekt Xcode, który dołącza platform-ios jako ogólny framework obj-c.

- Common: współdzielony moduł z czystym Kotlinem, bez zależności platformowych. Deklaruje API wymagające platformowych implementacji za pomocą słowa kluczowego expect. Moduły platform-android i platform-ios dostarczają actual implementacje.

- Platform-android i platform-ios: implementacje zależne od platformy oraz dodatkowy kod natywny. Każdy moduł platformowy implementuje pojedynczy moduł common.

W module common dostępna jest jedynie wersja common standardowej biblioteki, kotlin-stdlib-common, co ogranicza dostępne API.

Tworzenie i konfiguracja

- Common: zależność wyłącznie od kotlin-stdlib-common. Opcjonalnie włączone coroutines jako funkcja eksperymentalna.

- Platform-android: moduł biblioteczny Android (com.android.library) z mechanizmem actual i zależnością expectedBy na common.

- Platform-iOS: użycie wtyczki Kotlin/Native (Konan) w Gradle do budowy frameworka dla iphone oraz iphone_sim, z włączonymi optymalizacjami i debugiem. Również expectedBy na common.

- Aplikacja Android: zależność od platform-android.

- Aplikacja iOS: budowana w Xcode, osadza wygenerowany AstronomyPictureOfTheDay.framework.

Asynchroniczność i coroutines

W momencie tworzenia projektu Kotlin/Native nie wspierał jeszcze coroutines. Aby zachować styl programowania zbliżony do async/await, zdefiniowano wspólny interfejs w common i dostarczono platformowe implementacje przez expect/actual. To umożliwia spójne API asynchroniczne przy jednoczesnym wykorzystaniu natywnych prymitywów na każdej platformie.

Warstwa dostępu do danych

- Endpoint: https://api.nasa.gov/planetary/apod?date=[date]&hd=true&api_key=[api_key]

- Odpowiedź zawiera m.in. date, explanation, hdurl, media_type, service_version, title, url.

- Wspólny model danych znajduje się w module common.

- Zapytania i parsowanie są realizowane natywnie na platformach: na Androidzie Retrofit + Gson, na iOS Alamofire + SwiftyJSON.

Takie podejście trzyma sieć i parsowanie blisko platformy, a jednocześnie pozwala współdzielić modele i logikę sterującą.

Reprezentacja daty w common

Użycie String do daty jest niewygodne przy nawigacji dzień wstecz/naprzód. Z powodu ograniczeń kotlin-stdlib-common przygotowano własną abstrakcję daty w module common z implementacjami actual:

- Android: JodaTime

- iOS: NSDate (Foundation)

Dzięki interoperacyjności Kotlin/Native z Objective-C/Swift można bezpośrednio wywoływać API Foundation czy UIKit z kodu w Kotlinie, mimo że cały moduł jest pisany w Kotlin.

MVP: Presenter i View

W module common zdefiniowano prosty zestaw interfejsów Presenter i View (MVP). Platformowe ekrany implementują View, a Presenter i logika nawigacji pozostają współdzielone.

Integracja w aplikacjach

Android i iOS dołączają moduł common, wstrzykują platformowe implementacje repozytoriów, narzędzi czasu i asynchroniczności, a następnie wiążą Presenter z natywnym UI. Dzięki temu duża część logiki pozostaje identyczna na obu platformach.

Podsumowanie

Kotlin Multiplatform + Kotlin/Native już dziś pozwalają współdzielić kluczową logikę między Androidem i iOS, przy zachowaniu natywnych interfejsów i bibliotek.

Plusy:

- Wspólny język i modele danych

- Natywny dostęp do API (Retrofit, UIKit, Foundation)

- Brak VM po stronie iOS, czyste binaria

Ograniczenia:

- Status eksperymentalny i uboższe kotlin-stdlib-common

- Rozdzielone narzędzia (Gradle + Xcode)

- W ówczesnym stanie brak pełnego wsparcia coroutines w Kotlin/Native, konieczne mostkowanie expect/actual

Dla zespołów pracujących w Kotlinie to realna alternatywa dla Xamarin, zwłaszcza gdy cele obejmują natywne UI i współdzielenie logiki. Warto śledzić rozwój — kolejne wydania upraszczają konfigurację i poszerzają wsparcie bibliotek.

Potrzebujesz wsparcia technologicznego?

Porozmawiajmy o Twoim projekcie — od discovery po wdrożenie.

Umów konsultację

Chcesz wiedzieć więcej?

Sprawdź inne artykuły lub porozmawiajmy o Twoim projekcie

Wszystkie artykuły Zaprojektujmy Twoją aplikację AI
An unhandled error has occurred. Reload 🗙