Belajar Mobile Developer - iOS dengan Swift & SwiftUI
Episode 4 of 28

Belajar Mobile Developer - iOS dengan Swift & SwiftUI

Mendalami iOS native dengan Swift & SwiftUI: struktur proyek Xcode, declarative views, state management @State/@Binding, lifecycle scene, dan Human Interface Guidelines — sambil membangun halaman utama Fitku untuk iOS sebagai padanan dari versi Android

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah menguasai Android di episode 3, sekarang giliran sisi seberang: iOS dengan Swift & SwiftUI. Pola pikirnya mirip dengan Compose — UI deklaratif sebagai fungsi dari state — tetapi dengan bahasa (Swift), tooling (Xcode), dan design language (HIG) yang khas. Memahami kedua native platform membuat kalian mampu memilih strategi terbaik dan mengevaluasi solusi cross-platform dengan kepala dingin.

Penting: episode ini bisa diikuti penuh tanpa Mac jika kalian membaca kode dengan saksama — tapi idealnya jalankan di Xcode untuk benar-benar merasakan workflow-nya.

Struktur Proyek iOS

Proyek SwiftUI di Xcode terstruktur seperti ini:

Struktur proyek SwiftUI
Fitku/
├── Fitku.xcodeproj/
├── Fitku/
│   ├── FitkuApp.swift       → entry point (@main)
│   ├── ContentView.swift    → root view
│   ├── Models/              → data model (Workout, StepCount)
│   ├── ViewModels/          → observasi state
│   └── Assets.xcassets      → gambar & warna
└── FitkuTests/              → unit tests

Semua file ber-ekstensi .swift. Tidak ada manifest; Xcode mengelola build lewat project file. Build config (signing, deployment target) diatur lewat Signing & Capabilities di Xcode.

View dan Modifier

SwiftUI membangun UI dari View (struct conform View) dan modifier — padanan composable & modifier di Compose:

View dasar SwiftUI
struct HomeView: View {
    var userName: String
 
    var body: some View {
        VStack(alignment: .leading, spacing: 16) {
            Text("Halo, \(userName)!")
                .font(.title)
            Text("Siap workout hari ini?")
                .font(.subheadline)
            Button("Mulai Workout") {
                // aksi
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

Perhatikan alur yang sama dengan Compose: struktur kolom, spacing, padding, tombol — bedanya hanya sintaks.

State di SwiftUI

SwiftUI menyediakan beberapa property wrappers untuk state:

  • @State — state lokal milik satu view.
  • @Binding — jembatan untuk mengubah state dari child view.
  • @ObservedObject/@StateObject — state bersama dari class ObservableObject.
  • @EnvironmentObject — state yang diinjeksikan ke banyak view.

Contoh penghitung langkah:

State dasar SwiftUI
struct StepCounterView: View {
    @State private var steps = 0
 
    var body: some View {
        VStack(spacing: 12) {
            Text("Langkah hari ini: \(steps)")
                .font(.title2)
            Button("Tambah langkah") {
                steps += 1
            }
            .buttonStyle(.bordered)
        }
    }
}

Important

Satu perbedaan penting dari Compose: di SwiftUI, @State didesain untuk state kecil milik view. Untuk state aplikasi (workout, profil), pakai ObservableObject di atas class @MainActor — kita bangun pola ini di episode 8 dan 9.

Lifecycle dan Scene

Entry point iOS adalah @main App struct yang mendeklarasikan Scene. SwiftUI menawarkan scenePhase untuk merespons perubahan foreground/background:

Merespons scene phase
@main
struct FitkuApp: App {
    @Environment(\.scenePhase) private var scenePhase
 
    var body: some Scene {
        WindowGroup {
            HomeView()
        }
        .onChange(of: scenePhase) { _, newPhase in
            switch newPhase {
            case .active:    print("aplikasi aktif")
            case .inactive:  print("transisi")
            case .background:
                // simpan state sebelum di-suspend
                savePendingWorkout()
            @unknown default: break
            }
        }
    }
}

Ingat pelajaran episode 2: iOS hanya memberi waktu singkat saat masuk background — gunakan momen ini untuk menyimpan progress.

Human Interface Guidelines (HIG)

HIG adalah pedoman desain resmi Apple. Prinsip inti yang wajib dipahami:

  • Clarity — teks readable, ikon jelas, tidak berlebihan.
  • Deference — UI tidak bersaing dengan konten; sistem menyediakan pola familiar.
  • Depth — hierarki visual dan navigasi yang intuitif.

Implementasi praktisnya: pakai SF Symbols untuk ikon, sistem font (Dynamic Type), material & blur bawaan, dan komponen native (NavigationStack, TabView, List). Membangun UI "seenak" platform menuntut kalian mengikuti pola ini — bukan memaksakan pola dari platform lain.

Praktik: Halaman Utama Fitku (iOS)

Mari bangun halaman setara dengan versi Android episode 3:

HomeView Fitku (iOS)
struct HomeView: View {
    @StateObject private var viewModel = HomeViewModel()
    @State private var showingWorkout = false
 
    var body: some View {
        NavigationStack {
            VStack(alignment: .leading, spacing: 16) {
                Text("Halo, \(viewModel.userName)!")
                    .font(.title.bold())
 
                Card {
                    VStack(alignment: .leading, spacing: 4) {
                        Text("Langkah hari ini")
                            .font(.caption)
                            .foregroundStyle(.secondary)
                        Text("\(viewModel.steps)")
                            .font(.system(size: 40, weight: .bold))
                    }
                }
 
                Button("Mulai Workout") {
                    showingWorkout = true
                }
                .font(.headline)
                .frame(maxWidth: .infinity)
                .buttonStyle(.borderedProminent)
            }
            .padding()
            .navigationTitle("Fitku")
            .navigationDestination(isPresented: $showingWorkout) {
                WorkoutView()
            }
        }
    }
}

Common Pitfalls iOS

  • Update state dari background queue: SwiftUI akan crash atau error "Main actor-isolated". Selalu gunakan MainActor.
  • Tidak handle scenePhase: state hilang saat aplikasi di-suspend.
  • Memaksakan layout: target berbagai ukuran layar; pakai ViewThatFits, LazyVGrid, dan ScrollView dengan benar.
  • Mengabaikan Dynamic Type: teks tetap saja sulit dibaca bagi pengguna dengan teks besar → masalah aksesibilitas (episode 25).

Tip

Kalian belum punya Mac dan hanya bisa memilih satu native platform untuk praktik sekarang? Fokus dulu di Android (episode 3). Konsep iOS tetap kalian pelajari di episode-episode selanjutnya lewat contoh kode — dan begitu ada akses Xcode, migrasi pemahamannya cepat karena pola deklaratifnya identik.

Penutup

Pada episode 4 ini, kalian telah membangun fondasi iOS modern:

  • Struktur proyek Xcode, @main App, dan Scene/lifecycle dengan scenePhase.
  • UI deklaratif dengan View + modifier, state via @State/@StateObject.
  • Prinsip Human Interface Guidelines: clarity, deference, depth.
  • Halaman utama Fitku di iOS sebagai padanan versi Android.

Di episode 5 selanjutnya kita masuk dunia cross-platform: React Native + Expo — bagaimana satu codebase JavaScript/TypeScript bisa menjalankan aplikasi di Android & iOS, apa itu New Architecture (Fabric), dan membangun Fitku lintas platform dengan ekosistem JS. Sampai jumpa!

Belajar Mobile Developer - iOS dengan Swift & SwiftUI | Belajar Mobile Developer