Tampilkan postingan dengan label mobile apps. Tampilkan semua postingan
Tampilkan postingan dengan label mobile apps. Tampilkan semua postingan

 

Meta Description:

Tutorial lengkap membuat fitur login menggunakan SQLite di Kotlin Multiplatform (Android & iOS) dengan Compose Multiplatform, local database, session login, dan clean architecture.

Apa Itu Login SQLite di Kotlin Multiplatform?


https://images.openai.com/static-rsc-4/xwKI74IfSlTn1DbeDVGZNdBMT-Pi6vw4XBqwR1t7FrUV6N4tGxuhnYM6uGSL5GBg4T5wkeO0uDog9yvFir554fRI8q76rwzZTqDmlqe5ttzn6Xz_A_Py_z4TO3NvjRdjq__LWWMU-ydg8MOFK7bXHlbdOds1Q-bMEZ9nOcRniMizAxROcvO4lN6NKkBg4ZAW?purpose=fullsize

Pada aplikasi mobile modern, login tidak selalu harus menggunakan server API. Untuk aplikasi offline-first, internal company apps, POS, asset tracking, atau prototype, login lokal menggunakan database SQLite sangat berguna.

Pada tutorial ini kita akan membuat:


https://images.openai.com/static-rsc-4/qFR5EdTp68wY3cIsMRf48VWPB1hGlsEkf1Y-Ju6a9dxGmmbfdVcV23dReJ9Ma2v0EsoYAkpX-FWHppTWWXkbcOKryLPsDjMOaduMW1I5wWAQrpGrZqA6vjxRVPfnVphAFuZ4_oACOtkVGwJqe3SOZdQAQE6NM8pq2tIITDbRuN9UelX6UVLB6xLr_RXBwAne?purpose=fullsize

✅ Login Android & iOS dengan satu codebase
✅ Database SQLite lokal
✅ Validasi username & password
✅ Session login sederhana
✅ UI modern Compose Multiplatform
✅ Clean Architecture project

 


Kita akan menggunakan:

  • Kotlin Multiplatform
  • Compose Multiplatform
  • SQLite
  • SQLDelight

Kenapa Menggunakan SQLite?


https://images.openai.com/static-rsc-4/qFR5EdTp68wY3cIsMRf48VWPB1hGlsEkf1Y-Ju6a9dxGmmbfdVcV23dReJ9Ma2v0EsoYAkpX-FWHppTWWXkbcOKryLPsDjMOaduMW1I5wWAQrpGrZqA6vjxRVPfnVphAFuZ4_oACOtkVGwJqe3SOZdQAQE6NM8pq2tIITDbRuN9UelX6UVLB6xLr_RXBwAne?purpose=fullsize


SQLite cocok digunakan untuk:

  • Login offline
  • Asset tracking
  • Internal apps perusahaan
  • POS system
  • Mobile enterprise apps
  • Penyimpanan credential lokal

Keunggulan SQLite:

  1. Ringan
  2. Tidak membutuhkan server
  3. Cepat
  4. Bisa berjalan offline
  5. Support Android dan iOS

Arsitektur Project

Struktur project:

composeApp

├── commonMain
│ ├── database
│ ├── model
│ ├── repository
│ ├── screen
│ └── viewmodel

├── androidMain
└── iosMain

Flow aplikasi:

Login Screen

ViewModel

Repository

SQLite Database

User Auth Success

Membuat Project Kotlin Multiplatform

Buka Android Studio:

New Project
→ Kotlin Multiplatform App

Pilih:

UI = Compose Multiplatform
Target = Android + iOS
6

Menambahkan Dependency SQLDelight

Edit:

build.gradle.kts

Tambahkan:

plugins {
id("app.cash.sqldelight")
}

Dependency:

commonMain.dependencies {

implementation(
"app.cash.sqldelight:runtime:2.0.2"
)

implementation(
"app.cash.sqldelight:coroutines-extensions:2.0.2"
)
}

Konfigurasi:

sqldelight {
databases {
create("AppDatabase") {
packageName.set("database")
}
}
}

Membuat Table User SQLite

Buat folder:

src/commonMain/sqldelight/database

File:

User.sq

Isi:

CREATE TABLE users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
password TEXT NOT NULL
);

insertUser:
INSERT INTO users(username,password)
VALUES (?, ?);

loginUser:
SELECT *
FROM users
WHERE username = ?
AND password = ?;

Penjelasan:

Table ini menyimpan:

id
username
password

Membuat Database Driver

File:

DatabaseFactory.kt
class DatabaseFactory(
driverFactory: DriverFactory
) {

val database = AppDatabase(
driverFactory.createDriver()
)
}

Driver Android

class AndroidDriverFactory(
private val context: Context
): DriverFactory {

override fun createDriver() =
AndroidSqliteDriver(
AppDatabase.Schema,
context,
"app.db"
)
}

Driver iOS

class IOSDriverFactory: DriverFactory {

override fun createDriver() =
NativeSqliteDriver(
AppDatabase.Schema,
"app.db"
)
}

Repository Login

File:

AuthRepository.kt
class AuthRepository(
private val database: AppDatabase
) {

fun register(
username: String,
password: String
) {

database.userQueries.insertUser(
username,
password
)
}

fun login(
username: String,
password: String
): Boolean {

return database
.userQueries
.loginUser(
username,
password
)
.executeAsOneOrNull() != null
}
}

Membuat UI Login

File:

LoginScreen.kt
@Composable
fun LoginScreen(
authRepository: AuthRepository
) {

var username by remember {
mutableStateOf("")
}

var password by remember {
mutableStateOf("")
}

var result by remember {
mutableStateOf("")
}

Column(
modifier = Modifier
.fillMaxSize()
.padding(20.dp),
verticalArrangement =
Arrangement.Center
) {

Text(
"Login SQLite KMP",
style = MaterialTheme
.typography
.headlineMedium
)

Spacer(
Modifier.height(20.dp)
)

OutlinedTextField(
value = username,
onValueChange = {
username = it
},
label = {
Text("Username")
}
)

Spacer(
Modifier.height(10.dp)
)

OutlinedTextField(
value = password,
onValueChange = {
password = it
},
label = {
Text("Password")
}
)

Spacer(
Modifier.height(20.dp)
)

Button(
onClick = {

val success =
authRepository.login(
username,
password
)

result =
if(success)
"Login Berhasil"
else
"Login Gagal"

}
) {

Text("Login")
}

Spacer(
Modifier.height(20.dp)
)

Text(result)
}
}

Menambahkan User Dummy

Saat aplikasi pertama kali berjalan:

repository.register(
"admin",
"12345"
)

Login:

username: admin
password: 12345

Hasil Tampilan Aplikasi

UI yang dihasilkan:

  • Input username
  • Input password
  • Tombol login
  • Validasi login
  • Pesan sukses / gagal
7

Menambahkan Session Login

Buat object:

object SessionManager {

var isLoggedIn = false
}

Ketika login berhasil:

SessionManager.isLoggedIn =
true

Password Hashing (Disarankan)

Jangan simpan password plaintext.

Gunakan hash:

SHA-256
bcrypt

Konsep:

password

hash

save database

Struktur Final Project

commonMain

├── database
│ ├── AppDatabase
│ └── User.sq

├── repository
│ └── AuthRepository

├── screen
│ └── LoginScreen

├── session
│ └── SessionManager

└── driver
├── AndroidDriverFactory
└── IOSDriverFactory

Kapan Harus Menggunakan SQLite Login?

Cocok untuk:

  • Absensi
  • Asset tracking
  • Warehouse
  • POS
  • Internal apps
  • Prototype
  • Offline apps

Tidak cocok untuk:

  • Banking online
  • Marketplace besar
  • Social media
  • Public apps

Karena sebaiknya menggunakan server authentication + JWT.