มาลอง Hello world ใน Kotlin multiple platform แบบ Step by Step กัน!

Vissanu
te<h @TDG
Published in
4 min readAug 26, 2020

ตอนนี้นับเป็นอีกทางเลือกนึงของโปรแกรมเมอร์หรือสตาร์ทอัพ ที่จะนำการเขียนโปรแกรมในรูปแบบ Multiple platform โดยครั้งนี้ผู้เขียนขอนำเสนอเฉพาะที่เป็น Mobile application หรือนั่นก็คือ iOS&Android และพัฒนาโดยใช้ภาษา Kotlin จริงๆไม่ใช่แค่ Kotlin เท่านั่นที่สามารถพัฒนา Application ในรูปแบบ Multiple plaform แต่ยังมีเครื่องมือหรือภาษาอื่นที่พัฒนาได้เช่นกัน ก็อย่างที่หัวข้อได้กล่าววันนี้เราจะมาเขียน Kotlin multiple platform กัน

Multiple platform คืออะไร?

คือการเขียน Code เพียงหนึ่งภาษาแต่สามารถใช้งานได้ทั้ง 2 ภาษา!! หรือนั่นก็คือเรานำ Logic ไปใช้ได้ทั้ง 2 platform (iOS/Android) นั่นเองโดยปกติถ้าเราเขียน Android เราจะใช้ JAVA หรือ Kotlin และถ้าจะเขียน iOS ก็ต้องใช้ C#, Swift 5 นั่นคือหากเราเขียนภาษาเดียวและใช้ร่วมกันได้ จะทำให้ประหยัดเวลาในการพัฒนา และต้นทุนก็ลดลงด้วยเช่นกัน จึงไม่แปลกที่กลุ่มสตาร์ทอัพจะสนใจในการพัฒนาในรูปแบบ Multiple platform

Get staring!!

เกริ่นกันไปพอสมควรงั้นเรามาเริ่มจากการ Set up project กันเลย โดยเป้าหมายเรานั่นก็คือ “Hello world” นั่นเอง !!

สิ่งที่ต้องเตรียม คือ
1. Android studio #จะใช้ IntelliJ IDEA Community หรือ Ultimate edition ก็ได้แต่ตัวอย่างนี้จะใช้ Android studio 4.0 ขึ้นไป
2. Kotlin plugin 1.3.50 ขึ้นไป
3. Xcode สำหรับเป็น host operating system ใช้ compile สำหรับ iOS และ macOS devices

Step one : Create an Android project

เราทำการ เปิด Android studio ขึ้นมาและทำการสร้างโปรเจ็คใหม่ “start a new Android studio project” > เลือก Empty Activity > ตั้งชื่อ Name และ Package name ภาษาที่ใช้ Kotlin
เท่านี้เราก็จะสร้าง Project เรียบร้อยแล้ว

Step two : Creating the Shared Module

แน่นอนว่าเป้าหมายเราคือการนำ Kotlin มาทำให้สามารถแชร์โค้ดได้ทั้ง iOS และ Android เราจะทำโครงสร้างของ Gradle ที่ใช้งานสำหรับ SharedCode ร่วมกันทั้งสอง platform
1. เริ่มจากเข้าไปที่ settings.gradle ของโปรเจ็ค และให้ include ‘:SharedCode’ เพิ่มเข้าไปให้ไฟล์

2. สร้าง Directory ใหม่ในโปรเจ็คเราโดย คลิกขวาที่โปรเจ็ค > New > Directory > ตั้งชื่อว่า SharedCode จากนั่นให้สร้างไฟล์ build.gradle.kts ไปที่ SharedCode โดยคลิกขวาและกดที่ SharedCode > New > File > ตั้งชื่อ build.gradle.kts เสร็จแล้วให้เราเปิดไฟล์ build.gradle.kts และทำการตั้งค่าดังนี้

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTargetplugins {
kotlin("multiplatform")
}
kotlin {
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework {
baseName = "SharedCode"
}
}
}
jvm("android")sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
}
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
}
}
val packForXcode by tasks.creating(Sync::class) {
val targetDir = File(buildDir, "xcode-frameworks")
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets
.getByName<KotlinNativeTarget>("ios")
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
from({ framework.outputDirectory })
into(targetDir)
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\n"
+ "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
+ "cd '${rootProject.rootDir}'\n"
+ "./gradlew \$@\n")
gradlew.setExecutable(true)
}
}
tasks.getByName("build").dependsOn(packForXcode)

เสร็จแล้วให้เราทำการ Sync Now เพื่อ refresh Gradle project ครับ
3. ให้เราดำเนินการสร้าง Directory ตาม sourceSets ที่เราได้ Setting ไว้ใน Gradle ได้เลย ตามภาพโดยตอนที่ตั้งชื่อให้ตั้งชื่อตามที่เราได้ตั้งไว้ใน sourceSets ของ Gradle

หลังจากนั่นเราจะเริ่มสร้าง Class ที่จะนำ Logic มาแชร์ร่วมกันทั้งสอง Platform นั่นก็คือ commonMain นั่นเองโดยเราจะคลิกขวาที่ commonMain > kotlin > New > Kotlin File/Class > ตั้งชื่อ “common”

ให้เขียนฟังค์ชั่นการทำงานตามตัวอย่าง เราจะ Hello world โดยบอกด้วยว่าจาก Platform ไหน

//package ตรงนี้ต้องใช้ที่เราได้ตั้งชื่อไว้ตอนสร้าง Project นะครับหรือไปดูได้ที่ AndroidManifest.xml
package com.truedigital.trueid.samplekotlinmultiple

expect fun platformName(): String

fun createApplicationScreenMessage() : String {
return "Hello world on ${platformName()}"
}

จะเห็นได้ว่าผมได้สร้างฟังค์ชั่นชื่อ createApplicationScreenMessage และ return กลับเป็น string โดยเป้าหมายเราคือ Hello world และแสดง platformName นั่นเอง
มาถึงตรงนี้ถ้า “platformName()” ยัง errorอยู่ไม่ต้องแปลกใจเพราะเราต้องไปสร้าง class เพิ่มเสียก่อน

ใน AndroidMain ให้เราสร้าง Kotlin file ขึ้นมาชื่อ actual.kt และสร้างฟังค์ชั่น output string ออกไปตามตัวอย่าง

//package ตรงนี้ต้องใช้ที่เราได้ตั้งชื่อไว้ตอนสร้าง Project นะครับหรือไปดูได้ที่ AndroidManifest.xml
package com.truedigital.trueid.samplekotlinmultiple

actual fun platformName(): String {
return "Android"
}

ฝั่ง iosMain ก็เช่นกันให้สร้าง Kotlin file เหมือนกับของ androidMain ตั้งชื่อ actual.kt และเพิ่ม code ตัวอย่างดังนี้

package com.truedigital.trueid.samplekotlinmultiple

import platform.UIKit.UIDevice

actual fun platformName(): String {
return UIDevice.currentDevice.systemName() +
" " +
UIDevice.currentDevice.systemVersion
}

เท่านี้ใน class “common” expect fun platformName(): String ก็จะสามารถใช้งานได้แล้ว !!!

Step Three : Shared Kotlin Code สำหรับ Android

ตอนนี้เรามาถึงจุดที่จะได้เริ่มทดสอบกันแล้วมาเริ่มกันเลยสำหรับนำ Shared Kotlin Code มาใช้กับ Android platform
ให้เราไปที่ app/build.gradle และเพิ่ม implementation project(‘:SharedCode’)

จากนั่นให้เราไปที่ activity_main.xml เพื่อไปตั้งชื่อ id ให้กับ TextView

จากตัวอย่างภาพบนผมตั้งชื่อ id เป็น mainMessageTextView นะครับและสุดท้ายให้เราไปที่ class MainActivity เพื่อทำการ import code ของ commom ที่เป็น class Shared Kotlin Code ของเรามาแสดง output ที่ mainMessageTextView กันเลย!!

mainMessageTextView.text = createApplicationScreenMessage()

และแล้วมาทดสอบกัน Run กันเลยยยย

เรียบร้อยนะครับสำหรับขั้นตอนของ Shared Kotlin Code สำหรับ Android เราสามารถนำ Code ที่เราได้จัดทำเพื่อเตรียมของไว้แชร์ร่วมกันทั้ง 2 platform และในช่วงหน้าผมจะมานำเสนอ สำหรับ “Creating iOS Application” และ “Shared Kotlin Code สำหรับ iOS” โดยเราจะใช้ createApplicationScreenMessage ที่เราได้แสดงบน Android สำเร็จแล้วไปแสดงต่อที่ iOS นะครับ

สำหรับเนื้อหาในครั้งนี้ผมผู้เขียนต้องขอขอบคุณที่ติดตามจนจบและหากมีข้อมูลใดที่ผิดพลาดหรืออธิบายได้ไม่เข้าใจก็ต้องขออภัยในที่นี้ด้วย แล้วเจอกันใหม่ในตอนที่สองนะครับ บาย!

--

--