آموزش کاتلین مولتی پلتفرم (KMP) در اندروید و iOS: راهنمای جامع

برنامه نویسی اندروید
آموزش کاتلین مولتی پلتفرم (KMP) در اندروید و iOS: راهنمای جامع
راهنمای سطح پیشرفته (Production-Grade): این مقاله به صورت اختصاصی برای مهندسان نرم افزار و توسعه دهندگان اندروید طراحی شده است تا منطق تجاری پروژه های خود را با استفاده از کاتلین مولتی پلتفرم (Kotlin Multiplatform) میان اندروید و iOS به اشتراک بگذارند.

کاتلین مولتی پلتفرم چیست و چرا آینده توسعه موبایل است؟

کاتلین مولتی پلتفرم یا KMP یک فناوری مدرن و متن باز از شرکت JetBrains برای اشتراک گذاری منطق برنامه است. این بستر به برنامه نویسان اجازه می دهد لایه های داده، شبکه، دیتابیس و الگوریتم ها را به زبان کاتلین بنویسند و آن را میان اندروید و iOS مشترک سازند.

بر خلاف فریم ورک های کراس پلتفرم سنتی، در این ساختار هیچ رابط کاربری شبیه سازی نمی شود. کدهای کاتلین در سیستم عامل اندروید مستقیما به بایت کد JVM تبدیل شده و در سیستم عامل iOS توسط کامپایلر LLVM به باینری بومی و کد ماشین کامپایل می گردند.

همین فرآیند کامپایل مستقیم باعث شده است تا هیچ گونه افت فریم یا سربار اجرایی به وجود نیاید. اپلیکیشن های ساخته شده با این متدولوژی سرعتی برابر با کدهای صد در صد نیتیو سوئیفت ارائه می دهند و رضایت حداکثری کاربران را به دست می آورند.

انعطاف پذیری استثنایی در میزان اشتراک گذاری سورس کد، ویژگی بنیادین این فریم ورک محسوب می شود. تیم های مهندسی الزامی ندارند که کل ساختار برنامه را از ابتدا مشترک نمایند، بلکه می توانند تنها یک ماژول شبکه یا الگوریتم های محاسباتی پیچیده را به اشتراک بگذارند.

شما می توانید رابط کاربری اندروید را با راهنمای جامع نقشه راه برنامه نویسی اندروید به کمک جت پک کامپوز توسعه دهید و در پلتفرم اپل از فریم ورک مدرن SwiftUI بهره مند شوید.

شرکت های بزرگی نظیر نتفلیکس، گوگل، مک دونالد و فوربز با مهاجرت به این ساختار به نتایج تجاری چشمگیری دست یافته اند. بر اساس گزارش های رسمی، پیاده سازی منطق مشترک توانسته است زمان توسعه فیچرها را تا ۵۰ درصد کاهش داده و هزینه نگه داری را به نصف برساند.

تاییدیه رسمی گوگل: گوگل رسما اعلام کرد که از کاتلین مولتی پلتفرم به عنوان استاندارد اصلی اشتراک گذاری منطق در سیستم عامل های موبایل پشتیبانی می کند. کتابخانه های مطرح اندروید جت پک نظیر Collections، DataStore، Room و Paging اکنون کاملا با این پلتفرم هماهنگ هستند.

معماری پروژه در کاتلین مولتی پلتفرم و ساختار Source Sets

معماری سورس کد در پروژه های کاتلین مولتی پلتفرم بر پایه ساختاری سازمان یافته به نام Source Sets هدایت می شود. در این الگوی ماژولار، کدها به بخش های کاملا مستقل و بخش های متصل به سیستم عامل تفکیک می شوند تا نگه داری آن ها در مقیاس سازمانی آسان گردد.

سورس ست ریشه که با نام commonMain شناخته می شود، میزبان اصلی مدل های داده و منطق تجاری برنامه است. این بخش هیچ شناختی از کلاس های اختصاصی اندروید مانند اکتیویتی یا کلاس های اپل ندارد و صرفا با ویژگی های استاندارد زبان کاتلین تعامل می کند.

در سطوح بعدی، سورس ست های androidMain و iosMain قرار دارند که به فریم ورک های بومی هر سیستم دسترسی دارند. برای نمونه در سورس ست اندروید به سادگی می توان از کانتکست استفاده کرد و در سورس ست iOS به کتابخانه های فاندیشن اپل دسترسی یافت.

معماری اشتراک کد و مکانیزم expect و actual در کاتلین مولتی پلتفرم
تصویر ۱: سلسله مراتب Source Sets و جریان انتقال کد از commonMain به پلتفرم های بومی اندروید و iOS

برای مدیریت تارگت های اپل، کامپایلر از سورس ست های میانی پشتیبانی می کند. ساختارهایی نظیر iosArm64 برای دستگاه های واقعی آیفون و iosSimulatorArm64 برای شبیه ساز مک در یک زیرمجموعه واحد به نام iosMain یکپارچه می شوند.

فایل پیکربندی گریدل (build.gradle.kts) در ماژول مشترک پروژه هسته اصلی این ارتباطات را تنظیم می کند. توصیه می شود برای کاهش زمان بیلد از نکات بررسی شده در مقاله افزایش سرعت بیلد گریدل در اندروید استودیو استفاده نمایید:

plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidLibrary)
    alias(libs.plugins.kotlinxSerialization)
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions.jvmTarget = "17"
        }
    }
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "SharedKit"
            isStatic = true
        }
    }
}

پس از معرفی پلتفرم های مقصد، نوبت به تعیین کتابخانه ها و پکیج های وابسته برای هر لایه فرا می رسد. قطعه کد زیر نشان می دهد چگونه وابستگی های شبکه و همزمانی در سورس ست های تفکیک شده تزریق می شوند:

sourceSets {
    commonMain.dependencies {
        implementation(libs.kotlinx.coroutines.core)
        implementation(libs.kotlinx.serialization.json)
        implementation(libs.ktor.client.core)
        implementation(libs.ktor.client.content.negotiation)
    }
    androidMain.dependencies {
        implementation(libs.ktor.client.okhttp)
    }
    iosMain.dependencies {
        implementation(libs.ktor.client.darwin)
    }
}

مدیریت حافظه در بخش Kotlin/Native با نسخه جدید مموری منیجر کاملا بازنویسی شده است. دیگر نیازی به فریز کردن اشیا میان تردها نیست و گاربیج کالکتور نسل جدید کاتلین شیوه ای مشابه با ران تایم های مدرن را پیاده سازی می کند.

مکانیزم expect و actual: پل ارتباطی با قابلیت های بومی سیستم عامل

مکانیزم کلمات کلیدی expect و actual در کاتلین مولتی پلتفرم راهکار مستقیم کامپایلر برای دسترسی به ویژگی های بومی سیستم عامل است. این متدولوژی هوشمندانه نیاز به ایجاد پل های نرم افزاری ناامن یا لایه های واسط سنتی را از بین می برد.

کلمه کلیدی expect در سورس ست مشترک نقشی شبیه به یک اینترفیس اعلانی ایفا می کند. این اعلان به کامپایلر اطمینان می دهد که بدنه اجرایی کلاس یا تابع مورد نظر توسط سورس ست های اختصاصی همان سیستم عامل تکمیل خواهد شد.

در نقطه مقابل، کلمه کلیدی actual در سورس ست های androidMain و iosMain پیاده سازی دقیق متد را بر پایه کتابخانه های سیستمی همان محیط مهیا می سازد و امکان استفاده از API های بومی را فراهم می کند.

فرض کنید قصد داریم اطلاعات سخت افزاری دستگاه و یک شناسه تصادفی یکتا تولید کنیم. ابتدا در سورس ست مشترک قرارداد مورد نیاز را پیاده سازی می کنیم:

// commonMain/kotlin/ir/vahidhoseini/platform/PlatformInfo.kt
package ir.vahidhoseini.platform

expect class PlatformInfo() {{
    val platformName: String
    val osVersion: String
    fun getDeviceModel(): String
}}

expect fun generatePlatformUUID(): String

سپس در سورس ست اندروید، پیاده سازی واقعی به کمک کلاس های android.os.Build و کتابخانه های استاندارد جاوا به این شکل نوشته می شود:

// androidMain/kotlin/ir/vahidhoseini/platform/PlatformInfo.android.kt
package ir.vahidhoseini.platform

import android.os.Build
import java.util.UUID

actual class PlatformInfo {{
    actual val platformName: String = "Android"
    actual val osVersion: String = Build.VERSION.RELEASE ?: "Unknown"
    actual fun getDeviceModel(): String = "${{Build.MANUFACTURER}} ${{Build.MODEL}}"
}}

actual fun generatePlatformUUID(): String = UUID.randomUUID().toString()

در نهایت در سورس ست iOS، همان امضا با بهره گیری مستقیم از فریم ورک های بومی UIKit و سیستم امنیتی اپل پیاده سازی می گردد:

// iosMain/kotlin/ir/vahidhoseini/platform/PlatformInfo.ios.kt
package ir.vahidhoseini.platform

import platform.UIKit.UIDevice
import platform.Foundation.NSUUID

actual class PlatformInfo {{
    actual val platformName: String = "iOS"
    actual val osVersion: String = UIDevice.currentDevice.systemVersion
    actual fun getDeviceModel(): String = UIDevice.currentDevice.model
}}

actual fun generatePlatformUUID(): String = NSUUID().UUIDString()
توصیه مهم معماری نرم افزار: مکانیزم expect و actual باید صرفا برای لایه های زیرساختی نظیر اینیشیالایز کردن دیتابیس یا ابزار های لاگ به کار رود. برای بخش های اصلی منطق برنامه همواره مطابق با اصول آموزش معماری تمیز در اندروید از اینترفیس های تجریدشده استفاده کنید.

اکوسیستم کتابخانه های مدرن در کاتلین مولتی پلتفرم (KMP)

بلوغ اکوسیستم نرم افزاری کاتلین چند سکویی در سال های گذشته شتاب خارق العاده ای تجربه کرده است. امروزه به برکت همراهی مستمر گوگل و جت برینز، مجموعه ای از قابل اعتمادترین کتابخانه های پایدار برای تمامی نیازهای مهندسی در اختیار برنامه نویسان قرار دارد.

این کتابخانه ها به صورت چند سکویی کامپایل می شوند و عملکرد یکسانی را در سراسر سیستم عامل ها به نمایش می گذارند. بر اساس تحلیل های صورت گرفته در مقاله مقایسه کاتلین و جاوا این ابزار ها با بهره گیری بهینه از رم، کارایی سیستم را تضمین می کنند.

اکوسیستم کتابخانه های مدرن در کاتلین مولتی پلتفرم KMP
تصویر ۲: لایه های مختلف استک فنی مدرن KMP از شبکه و دیتابیس تا تزریق وابستگی و سریال سازی
نام کتابخانه توسعه دهنده حیطه کاربرد در KMP موتور اجرایی در اندروید / iOS
Ktor Client JetBrains ارتباطات شبکه ای و مدیریت REST API موتور OkHttp در اندروید / موتور Darwin در iOS
Room KMP Google (Jetpack) پایگاه داده رابطه ای محلی و کش آفلاین Android SQLite Driver / iOS Native SQLite Driver
Kotlinx Coroutines JetBrains همزمانی، مالتی تردینگ و برنامه نویسی واکنشی JVM Dispatchers / Apple Darwin Dispatch Queues
Kotlinx Serialization JetBrains تبدیل داده های JSON و ساختارهای سریال پذیر کامپایلر پلاگین بومی بدون نیاز به Reflection
Koin جامعه کاتلین تزریق وابستگی (Dependency Injection) تزریق سبک کاتلین بدون وابستگی به فریم ورک جاوا

علاوه بر ابزار های فوق، کتابخانه هایی نظیر Kermit برای سیستم یکپارچه لاگینگ و Multiplatform Settings برای مدیریت تنظیمات جفت کلید و مقدار به طور گسترده در شرکت های بین المللی مورد استفاده قرار می گیرند.

آمارها نشان می دهد استفاده از این کتابخانه های استاندارد باعث شده تا احتمال بروز باگ های مقطعی تا ۴۰ درصد کاهش یابد و هماهنگی میان کدهای تیم اندروید و iOS به بالاترین حد ممکن برسد.

راه اندازی شبکه با Ktor Client و مدیریت ارتباط با سرور

فریم ورک رتروفیت سال های طولانی به عنوان رهبر ارتباطات شبکه در اندروید شناخته شده است که در راهنمای آموزش رتروفیت Retrofit در اندروید تمامی ابعاد آن شرح داده شد. اما رتروفیت به ران تایم جاوا مقید است و در محیط بومی iOS قابل اجرا نخواهد بود.

در دنیای کاتلین مولتی پلتفرم، فریم ورک پیشرفته Ktor Client استانداردی بی بدیل محسوب می شود. این ابزار با طراحی ماژولار و مبتنی بر کورتین ها، سرعت پردازش درخواست ها را تا ۳۵ درصد در شبکه های ناپایدار ارتقا می بخشد.

پیکربندی کلاینت شبکه در لایه commonMain به شکلی متمرکز پیاده سازی می شود تا تمامی تنظیمات عمومی نظیر هدرها، تایم اوت و پلاگین تبدیل JSON در یک نقطه کنترل گردند:

// commonMain/kotlin/ir/vahidhoseini/network/NetworkClient.kt
package ir.vahidhoseini.network

import io.ktor.client.HttpClient
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json

expect fun createHttpClientEngine(): HttpClientEngine

object NetworkClient {{
    val client = HttpClient(createHttpClientEngine()) {{
        install(ContentNegotiation) {{
            json(Json {{
                ignoreUnknownKeys = true
                isLenient = true
            }})
        }}
        defaultRequest {{
            headers.append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
        }}
    }}
}}

اکنون کافی است موتورهای اجرایی را برای سیستم عامل ها تعیین کنیم. در سورس ست اندروید، موتور پایدار OkHttp برای مدیریت کانکشن ها و مکانیزم تلاش مجدد تعبیه می شود:

// androidMain/kotlin/ir/vahidhoseini/network/KtorEngine.android.kt
package ir.vahidhoseini.network

import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.okhttp.OkHttp

actual fun createHttpClientEngine(): HttpClientEngine = OkHttp.create {{
    config {{
        retryOnConnectionFailure(true)
    }}
}}

در محیط سیستم عامل iOS، موتور بومی Darwin با کلاس های اصلی شبکه اپل نظیر NSURLSession هماهنگ می شود و سازگاری کامل با مصرف بهینه باتری دستگاه را تامین می نماید:

// iosMain/kotlin/ir/vahidhoseini/network/KtorEngine.ios.kt
package ir.vahidhoseini.network

import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.darwin.Darwin

actual fun createHttpClientEngine(): HttpClientEngine = Darwin.create {{
    configureRequest {{
        setAllowsCellularAccess(true)
    }}
}}

به این ترتیب، مدل های داده و لایه های پاسخ سرور تنها یک بار نوشته می شوند و روی هر دو بستر با سرعتی باورنکردنی به صورت امن مبادله می گردند.

ذخیره سازی آفلاین با Room KMP در اندروید و iOS

با معرفی نگارش ۲.۷ فریم ورک محبوب Room توسط مهندسان گوگل، رویای استفاده از پایگاه داده رابطه ای مشترک به حقیقت پیوست. ساختار دیتابیس Room که پیش تر در راهنمای جامع آموزش دیتابیس Room در اندروید آموزش دادیم، اکنون در iOS نیز کاملا قابل اجراست.

این ابزار امکان تعریف جداول، کوئری های بهینه اس کیو ال و کش محلی را با حداقل کد نویسی فراهم می کند. تمامی روابط و تغییرات داده ها از طریق کورتین ها به شکل ناهمگام پردازش می شوند.

در سورس ست مشترک، موجودیت ها و اینترفیس های دسترسی به دیتابیس را بر اساس نیازهای پروژه تعریف می کنیم:

// commonMain/kotlin/ir/vahidhoseini/database/AppDatabase.kt
package ir.vahidhoseini.database

import androidx.room.Dao
import androidx.room.Database
import androidx.room.Entity
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.RoomDatabase
import kotlinx.coroutines.flow.Flow

@Entity(tableName = "articles")
data class ArticleEntity(
    @PrimaryKey val id: Long,
    val title: String,
    val summary: String
)

@Dao
interface ArticleDao {{
    @Query("SELECT * FROM articles")
    fun getAllArticles(): Flow>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertArticles(items: List)
}}

@Database(entities = [ArticleEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {{
    abstract fun articleDao(): ArticleDao
}}

در مرحله بعد، نمونه سازی از پایگاه داده با سازنده پلتفرم محور انجام می پذیرد. در اندروید فایل دیتابیس در فضای سندی اپلیکیشن ذخیره می شود و در iOS مسیر معادل در پوشه اسناد سیستم ثبت می گردد.

بر اساس بررسی های بنچمارک، سرعت بازیابی رکوردها در نسخه چند سکویی روم با سرعت دیتابیس بومی برابری می کند و زمان بارگذاری اطلاعات کمتر از ۱۵ ms ارزیابی شده است.

مدیریت همزمانی و جریان داده با کورتین ها و Flow در KMP

توسعه نرم افزارهای مدرن بدون مدیریت بهینه مالتی تردینگ و استریم های داده امکان پذیر نیست. کاتلین مولتی پلتفرم از زیرساخت بی نظیر Coroutines و Flow استفاده می کند که مبانی عمیق آن در کورتین ها و Flow در کاتلین تشریح شده است.

لایه ریپازیتوری در معماری چند سکویی، داده ها را از کلاینت شبکه دریافت می کند، آنها را در دیتابیس محلی کش می نماید و تغییرات را در قالب جریان های واکنشی در اختیار برنامه قرار می دهد:

// commonMain/kotlin/ir/vahidhoseini/repository/ArticleRepository.kt
package ir.vahidhoseini.repository

import ir.vahidhoseini.database.ArticleDao
import ir.vahidhoseini.database.ArticleEntity
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.request.get
import kotlinx.coroutines.flow.Flow

class ArticleRepository(
    private val httpClient: HttpClient,
    private val articleDao: ArticleDao
) {{
    fun observeArticles(): Flow> = articleDao.getAllArticles()

    suspend fun refreshArticles(): Result = runCatching {{
        val remote: List = httpClient
            .get("https://api.vahidhoseini.ir/v1/articles")
            .body()
        articleDao.insertArticles(remote)
    }}
}}

یکی از دغدغه های همیشگی تیم های آی او اس، نحوه مصرف استریم های کاتلین در زبان سوئیفت بود. خوشبختانه با ظهور ابزار قدرتمند SKIE، این مانع به طور قطعی برطرف شده است.

ابزار SKIE تمامی استریم های Flow را به پروتکل مدرن AsyncSequence سوئیفت نگاشت می کند. بدین ترتیب برنامه نویس سوئیفت می تواند از سینتکس های جدید for await در محیط اپل بهره مند شود.

اتصال منطق مشترک به رابط کاربری در کاتلین و سوئیفت

پس از اتمام توسعه لایه های دامین و داده، گام بعدی ارائه اطلاعات به کاربر در لایه نمایش است. در مهندسی نرم افزارهای مدرن دو راهبرد بنیادین برای ارتباط با ویوها وجود دارد:

مقایسه استراتژی اشتراک منطق با رابط کاربری در کاتلین مولتی پلتفرم
تصویر ۳: مقایسه دو الگوی معماری: اشتراک گذاری منطق با UI بومی در برابر اشتراک گذاری کامل UI با کامپوز مولتی پلتفرم
  1. اشتراک منطق به همراه رابط کاربری بومی (Shared Logic + Native UI): در این استراتژی، تمام منطق در کاتلین پیاده شده اما ویوها در اندروید با آموزش جت پک کامپوز در اندروید و در iOS با فریم ورک سوئیفت یو آی طراحی می شوند.
  2. اشتراک کامل رابط کاربری با کامپوز مولتی پلتفرم (Compose Multiplatform): در این متدولوژی کل لایه رابط کاربری نیز به صورت اعلانی با کاتلین کامپوز نوشته شده و روی تمام پلتفرم ها رندر می گردد.

پیاده سازی کلاس ViewModel با استفاده از پکیج چند سکویی رسمی گوگل انجام می پذیرد تا چرخه حیات صفحات در هر سیستم عامل حفظ شود:

// commonMain/kotlin/ir/vahidhoseini/presentation/ArticlesViewModel.kt
package ir.vahidhoseini.presentation

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import ir.vahidhoseini.database.ArticleEntity
import ir.vahidhoseini.repository.ArticleRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class ArticlesViewModel(
    private val repository: ArticleRepository
) : ViewModel() {
    private val _articles = MutableStateFlow>(emptyList())
    val articles: StateFlow> = _articles.asStateFlow()

    init {
        viewModelScope.launch {
            repository.observeArticles().collect { _articles.value = it }
        }
    }
}

این ویومدل در پروژه iOS با فریم ورک سوئیفت یو آی بدون هیچ واسطه ای فراخوانی می شود و حس و حال صد در صد بومی سیستم عامل را به کاربر منتقل می نماید:

// iOSApp/ArticleListView.swift
import SwiftUI
import SharedKit

struct ArticleListView: View {
    @StateObject private var viewModel: ObservableArticlesViewModel
    
    var body: some View {
        NavigationView {
            List(viewModel.articles, id: \.id) { article in
                VStack(alignment: .leading) {
                    Text(article.title).font(.headline)
                    Text(article.summary).font(.subheadline)
                }
            }
            .navigationTitle("مقالات مهندسی")
        }
    }
}

تزریق وابستگی در کاتلین مولتی پلتفرم

در اپلیکیشن های بزرگ اندروید، ابزار های هیلت و دگر جایگاه ویژه ای دارند که مبانی آن در راهنمای آموزش تزریق وابستگی با Hilt در اندروید تشریح شد. اما هیلت وابسته به ران تایم جاوا بوده و در ماژول های مشترک KMP قابل اجرا نیست.

برای مدیریت وابستگی ها در ساختار چند سکویی، فریم ورک های سبکی نظیر Koin یا ابزار کامپایل تایم kotlin-inject انتخاب های برتر به شمار می روند.

کوین به دلیل عدم نیاز به کدهای تولیدی سنگین، فرایند کامپایل را بسیار سریع نگه می دارد و به سادگی می تواند سرویس های شبکه و ریپازیتوری ها را در تمام پلتفرم ها تامین نماید.

تیم های نرم افزاری گزارش داده اند که مهاجرت به کوین توانسته است پیچیدگی های ماژول های مشترک را تا ۴۵ درصد تقلیل داده و تست پذیری کدها را تضمین کند.

نمونه کد زیر ثبت وابستگی های دیتابیس، کلاینت شبکه و ویومدل را در ماژول مشترک کوین نمایش می دهد که به سادگی در پروژه های انترپرایز مقیاس پذیر است:

// commonMain/kotlin/ir/vahidhoseini/di/SharedModule.kt
package ir.vahidhoseini.di

import org.koin.dsl.module
import ir.vahidhoseini.network.NetworkClient
import ir.vahidhoseini.repository.ArticleRepository
import ir.vahidhoseini.presentation.ArticlesViewModel

val sharedModule = module {{
    single {{ NetworkClient.client }}
    single {{ ArticleRepository(get(), get()) }}
    factory {{ ArticlesViewModel(get()) }}
}}

با فراخوانی تابع startKoin در کلاس اپلیکیشن اندروید و متد آغازین اپلیکیشن در سوئیفت، کل زنجیره وابستگی ها به صورت خودکار مقداردهی می شود.

مقایسه کاتلین مولتی پلتفرم با فلاتر و ری اکت نیتیو

انتخاب استک توسعه مناسب یکی از حساس ترین وظایف معماران نرم افزار است. همان گونه که در مقاله تحلیلی مقایسه فلاتر، ری اکت نیتیو و KMP اشاره شد، تفاوت های بنیادین در مدل کامپایل و ارتباط با سخت افزار نهفته است.

معیار ارزیابی کاتلین مولتی پلتفرم (KMP) فلاتر (Flutter) ری اکت نیتیو (React Native)
مدل اجرایی در iOS کامپایل مستقیم به کد ماشین با LLVM اجرا در بستر Dart VM و موتور گرافیکی Impeller اجرا در موتور JavaScript Hermes به کمک JSI
رویکرد رابط کاربری ۱۰۰٪ بومی با Compose و SwiftUI (یا اختیاری Compose Multiplatform) رندرسازی تمام ویجت ها با موتور اختصاصی بوم (Canvas) نگاشت کامپوننت های JS به ویوهای نیتیو با پل نرم افزاری
افزایش حجم فایل نصبی بسیار ناچیز (کمتر از ۱ تا ۲ مگابایت برای منطق) حداقل ۱۰ تا ۱۵ مگابایت به دلیل امبد موتور رندرینگ حداقل ۸ تا ۱۲ مگابایت به دلیل ران تایم JS
دسترسی به APIهای اختصاصی دسترسی بی واسطه و مستقیم به تمام فریم ورک های اپل و گوگل نیاز به نوشتن پلاگین های MethodChannel با سربار داده نیاز به TurboModules و ماژول های Native
ریسک انطباق پذیری سیستم بسیار اندک (امکان ادغام تکه تکه در پروژه های موجود) بالا (نیاز به بازنویسی کامل کل اپلیکیشن در زبان Dart) متوسط (نیازمند معماری همزمان جاوااسکریپت و نیتیو)

در بررسی های فنی مشخص شد که حجم خروجی کاتلین مولتی پلتفرم تنها ۱.۵ MB به فایل نهایی اضافه می کند، در حالی که فلاتر حداقل ۱۲ MB حجم برنامه را افزایش می دهد.

همچنین سرعت اجرای محاسبات سنگین در کاتلین مولتی پلتفرم تا ۲ برابر سریع تر از فریم ورک های وابسته به ماشین مجازی جاوا اسکریپت برآورد شده است.

سازگاری بی نقص با ابزار های مانیتورینگ عملکرد و لاگین سیستمی نظیر کرش لیتیکس نیز از مزایای تعیین کننده این معماری نسبت به فریم ورک های وب محور است.

نقشه راه مهاجرت تدریجی پروژه های اندروید به KMP

برجسته ترین ویژگی رقابتی کاتلین مولتی پلتفرم، قابلیت مهاجرت گام به گام و بدون ریسک است. شما نیاز ندارید پروژه باسابقه خود را بازنویسی کنید، بلکه به تدریج لایه های مختلف آن را مشترک می سازید.

نقشه راه مهاجرت تدریجی پروژه اندروید به کاتلین مولتی پلتفرم
تصویر ۴: فرآیند مرحله ای ۴ گانه برای مهاجرت ایمن پروژه های اندروید به کاتلین مولتی پلتفرم بدون توقف سرویس

برای پیاده سازی موفق و ایمن این فرایند، مراحل چهارگانه زیر را در دستور کار قرار دهید:

  1. فاز اول - جداسازی ماژول مشترک و مدل های داده: ابتدا ماژول :shared را ایجاد کنید. مدل های داده و کلاس های خالص را به این ماژول انتقال دهید. برای سنجش درستی عملکرد آنها از راهنمای آموزش تست نویسی در اندروید بهره ببرید.
  2. فاز دوم - انتقال لایه شبکه به Ktor: سرویس های وب و کدهای فراخوانی را از رتروفیت به Ktor Client تغییر داده و موتورهای مناسب هر پلتفرم را متصل نمایید.
  3. فاز سوم - هماهنگ سازی دیتابیس محلی: پایگاه داده را به کتابخانه Room KMP مجهز کنید تا ریپازیتوری ها و منطق کش داده کاملا بین اندروید و iOS مشترک گردند.
  4. فاز چهارم - تولید خروجی فریم ورک و اتصال اپلیکیشن iOS: پکیج خروجی SharedKit.framework را در پروژه Xcode اضافه کرده و لایه های سوئیفت یو آی را متصل نمایید.

با پیاده سازی این مراحل، تیم فنی می تواند بدون ایجاد وقفه در توسعه قابلیت های جدید، برنامه را به یکی از پیشرفته ترین استک های نرم افزاری مجهز سازد.

تجربه پیاده سازی نشان می دهد که پس از اجرای موفق این چهار فاز، بیش از ۶۵ درصد کدهای پروژه بین اندروید و iOS مشترک شده و بهره وری مهندسان تا ۲ برابر ارتقا می یابد.

پرسش های متداول درباره آموزش کاتلین مولتی پلتفرم (FAQ)

۱. کاتلین مولتی پلتفرم چیست و چه تفاوتی با فلاتر دارد؟

کاتلین مولتی پلتفرم یا KMP رویکردی بر پایه اشتراک منطق تجاری با حفظ رابط کاربری کاملا بومی است. در مقابل، فلاتر کل سیستم رندرینگ را درون یک بوم اختصاصی شبیه سازی می کند. در KMP کدهای کاتلین در iOS به باینری مستقیم تبدیل شده و هیچ سربار اجرایی ندارند.

۲. آیا یادگیری کاتلین مولتی پلتفرم برای برنامه نویسان اندروید دشوار است؟

خیر، به دلیل اینکه زبان اصلی KMP همان کاتلین است و ابزار هایی نظیر کورتین ها، Flow، Room و ViewModel مشترک هستند، توسعه دهندگان اندروید با کمترین زمان می توانند بر آن مسلط شوند.

۳. آیا برای خروجی iOS در پروژه KMP به سیستم عامل مک نیاز است؟

برای کامپایل نسخه نهایی iOS به دلیل ابزار های انحصاری اپل به محیط macOS و Xcode نیاز دارید. با این حال توسعه منطق مشترک روی ویندوز یا لینوکس انجام پذیر است و کامپایل iOS را می توان به گیت هاب اکشنز سپرد.

۴. مکانیزم expect و actual در کاتلین مولتی پلتفرم چه نقشی دارد؟

این مکانیزم به شما امکان می دهد امضای یک کلاس یا تابع را در بخش مشترک با expect اعلان کرده و پیاده سازی متناسب با قابلیت های بومی اندروید و iOS را با actual در سورس ست های هر پلتفرم فراهم آورید.

۵. آیا گوگل رسما از کاتلین مولتی پلتفرم حمایت می کند؟

بله، گوگل رسما KMP را به عنوان راهکار پیشنهادی اشتراک کد معرفی کرده و کتابخانه های اندروید جت پک نظیر Room، DataStore، Paging و ViewModel را برای این محیط منتشر ساخته است.

۶. ابزار SKIE چیست و چه مزیتی در KMP ایجاد می کند؟

ابزار SKIE پلاگینی فوق العاده برای ارتقای خروجی سوئیفت است. این ابزار کورتین ها و استریم های Flow کاتلین را مستقیما به ساختارهای async/await و AsyncSequence بومی زبان سوئیفت تبدیل می کند.

۷. بهترین کتابخانه شبکه در کاتلین مولتی پلتفرم چیست؟

کتابخانه Ktor Client استانداردترین ابزار ارتباط با وب سرویس ها در KMP است که از موتور OkHttp در اندروید و موتور بومی Darwin در سیستم عامل iOS استفاده می کند.

۸. آیا رابط کاربری را نیز می توان با KMP به صورت مشترک پیاده کرد؟

بله، از طریق فناوری Compose Multiplatform می توانید کدهای رابط کاربری جت پک کامپوز را علاوه بر اندروید، روی iOS، دسکتاپ و وب به صورت مشترک اجرا کنید.

۹. اثر استفاده از KMP بر حجم نهایی اپلیکیشن چقدر است؟

افزایش حجم فایل بسیار ناچیز و معمولا کمتر از ۲ مگابایت است، زیرا کدهای مشترک مستقیما به باینری ماشین تبدیل شده و هیچ موتور رندرینگی به پروژه اضافه نمی شود.

۱۰. تزریق وابستگی در کاتلین مولتی پلتفرم چگونه مدیریت می شود؟

به دلیل اینکه هیلت وابسته به ران تایم جاواست، در پروژه های چند سکویی از فریم ورک سبک Koin یا کتابخانه کامپایل تایم kotlin-inject استفاده می گردد.

نتیجه گیری و گام های بعدی توسعه

کاتلین مولتی پلتفرم تحولی بنیادین در مهندسی نرم افزارهای موبایل ایجاد کرده است. با ترکیب منطق تجاری یکپارچه و حفظ رابط کاربری صد در صد بومی، KMP زمان توسعه را به نصف رسانده و بالاترین رضایت کاربران را تامین می نماید.

پیشنهاد می کنیم با ایجاد ماژول مشترک در پروژه فعلی خود و انتقال مدل های پایه، ورود به دنیای هیجان انگیز کاتلین مولتی پلتفرم را آغاز نمایید.

امتیاز و نظرات

۰.۰ (۰ نظر)
برای ثبت دیدگاه باید وارد حساب کاربری شوید. ورود

هنوز نظری ثبت نشده است. اولین نفر باشید.