Router — dasar-dasar pola routing di iOS dan Android

Penulis: IT Sectr Diterbitkan: 2026-02-19 Waktu membaca: 9 mnt

Router — pola arsitektur yang memusatkan logika navigasi antar layar aplikasi. Router menentukan ke mana dan bagaimana berpindah saat suatu peristiwa terjadi. Di iOS, Router mengabstraksi UINavigationController dan segue, di Android — FragmentManager dan NavController dari Jetpack Navigation. Router dapat berfungsi sebagai pola mandiri atau sebagai komponen Coordinator (Router-per-Coordinator) dan VIPER (Router-per-module). Selengkapnya — di Android Navigation Component Guide.

Poin utama

  • Router — pola routing yang memusatkan navigasi antar layar
  • Dua level — Router bisa menjadi komponen Coordinator atau pola mandiri
  • iOS Router — abstraksi di atas UINavigationController dengan metode push/present/pop
  • Android Router — Jetpack Navigation Component dengan NavController dan deep links
  • URL Routing — routing berdasarkan skema URL (deeplink, universal link)

Apa itu Router: esensi pola routing

Router — pola yang mengenkapsulasi logika perpindahan antar layar. Ide utama: ViewController (atau Presenter/ViewModel) tidak memanggil langsung navigationController.pushViewController, melainkan memberi tahu Router tentang niat berpindah. Router memutuskan ViewController mana yang akan dibuat dan bagaimana menampilkannya. Router bisa sederhana (kumpulan metode navigasi) atau kompleks (dengan routing berdasarkan skema URL, deep link, dan notifikasi push).

Tiga pendekatan Router — Router sebagai layanan (Navigator-singleton global), Router sebagai komponen modul (pendekatan VIPER), Router sebagai protokol (abstraksi untuk Coordinator). Router global — kesederhanaan (satu instance per aplikasi) — populer di proyek kecil. Router modular — setiap fitur memiliki Router sendiri — standar VIPER dan Clean Architecture. Router protokol — digunakan di Coordinator: RouterProtocol dengan metode push/present/pop/dismiss.

PendekatanStrukturKapan digunakan
Navigator globalSingleton dengan metode perpindahanProyek kecil, prototipe
Router modularRouter di dalam setiap modulVIPER, Clean Architecture
Router protokolProtocol + implementasi untuk CoordinatorMVVM-C, Coordinator pattern

Sejarah pola — Router muncul di framework web (URL Router — Rails Routes, Express.js) dan diadaptasi untuk pengembangan mobile. Di iOS, Router menjadi populer seiring pertumbuhan VIPER (2015-2017). Di Android, Router — bagian dari Jetpack Navigation (2018), solusi standar Google untuk navigasi. Saat ini Router merupakan bagian tak terpisahkan dari setiap arsitektur modular aplikasi mobile.

Router di iOS: implementasi di Swift

iOS Router — protokol dengan metode untuk berbagai jenis navigasi. Implementasi dasar membungkus UINavigationController. Router dapat mengelola presentasi modal (present/dismiss), push/pop di tumpukan navigasi, showDetail untuk Split View Controller dan presentasi layar penuh (iOS 13+). Router tidak membuat ViewController — ia menerima instance jadi dan menampilkannya. Pembuatan ViewController dilakukan oleh pabrik (Assembly, wadah DI) atau Coordinator.

swift
// RouterProtocol untuk iOS
protocol RouterProtocol {
    func push(_ viewController: UIViewController, animated: Bool)
    func pop(animated: Bool)
    func popToRoot(animated: Bool)
    func present(_ viewController: UIViewController, animated: Bool)
    func dismiss(animated: Bool)
    func setViewControllers(_: [UIViewController], animated: Bool)
}

// Implementasi Router melalui UINavigationController
class NavigationRouter: RouterProtocol {
    private let navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    func push(_ vc: UIViewController, animated: Bool) {
        if navigationController.presentedViewController {
            navigationController.dismiss(animated: false)
        }
        navigationController.pushViewController(vc, animated: animated)
    }

    func pop(animated: Bool) {
        navigationController.popViewController(animated: animated)
    }

    func popToRoot(animated: Bool) {
        navigationController.popToRootViewController(animated: animated)
    }

    func present(_ vc: UIViewController, animated: Bool) {
        navigationController.present(vc, animated: animated)
    }

    func dismiss(animated: Bool) {
        navigationController.dismiss(animated: animated)
    }

    func setViewControllers(_ vcs: [UIViewController], animated: Bool) {
        navigationController.setViewControllers(vcs, animated: animated)
    }
}

// Assembly — pembuatan modul dengan Router
protocol ProfileModuleFactory {
    func makeProfileView() -> UIViewController
}

Router di VIPER — setiap modul VIPER memiliki Router sendiri yang tahu layar mana yang akan dibuka dari modul saat ini. Router membuat ViewController modul berikutnya melalui pabrik dan mentransfer kendali. Router di VIPER — satu-satunya komponen yang berisi import UIKit (selain View). Ini menyederhanakan pengujian Presenter dan Interactor: mereka tidak bergantung pada UIKit.

Router di Android: Jetpack Navigation Component

Jetpack Navigation Component — router standar untuk Android, direkomendasikan oleh Google sejak 2018. Navigasi didefinisikan dalam grafik XML (nav_graph.xml): simpul (fragments, activities, destinations) dan tepi (actions). NavController mengelola transisi: memanggil FragmentManager.replace/add dan mengelola tumpukan balik (back stack). Navigation Component mendukung deep link, argumen, animasi transisi, dan Safe Args untuk transmisi data yang aman tipe.

kotlin
// nav_graph.xml — grafik navigasi
<!-- @xml/nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/loginFragment">

    <fragment android:id="@+id/loginFragment"
        android:name=".ui.login.LoginFragment">
        <action android:id="@+id/to_home"
            app:destination="@id/homeFragment" />
    </fragment>

    <fragment android:id="@+id/homeFragment"
        android:name=".ui.home.HomeFragment">
        <argument android:name="userId"
            android:defaultValue="0"
            app:argType="integer" />
        <deepLink app:uri="myapp://home/{userId}" />
    </fragment>
</navigation>

// Kotlin — navigasi melalui NavController
class LoginFragment : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.loginButton.setOnClickListener {
            val action = LoginFragmentDirections.toHome(userId = 42)
            findNavController().navigate(action)
        }
    }
}

// Safe Args — argumen aman tipe
class HomeFragmentArgs : NavArgs {
    val userId: Int get() = arguments?.getInt("userId") ?: 0
}

// NavigationUI — integrasi dengan Toolbar, BottomNav, Drawer
class MainActivity : AppCompatActivity() {
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val navHost = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        navController = navHost.navController
        NavigationUI.setupActionBarWithNavController(this, navController)
    }
}

Deep link di Android Navigation — Navigation Component mendukung deep link eksplisit (PendingIntent + NavDeepLinkBuilder) dan implisit (melalui intent-filter di manifes). Deep link dapat mengarah ke simpul mana pun di nav_graph. Pemrosesan notifikasi push: Notification membuat PendingIntent dengan NavDeepLinkBuilder yang memulihkan tumpukan balik dan membuka layar yang diinginkan. Navigation Component secara otomatis menangani tombol Up/Back dan mengembalikan pengguna ke layar sebelumnya.

URL Routing: routing Deeplink dan Universal Link

URL Routing — routing berdasarkan skema URL, deep link, dan universal link. Aplikasi mendaftarkan skema (myapp://profile/42) atau universal link (https://example.com/profile/42). Router mem-parse URL, mengekstrak parameter (userId=42) dan membuka layar yang sesuai. URL Routing memungkinkan pembukaan aplikasi dari luar: melalui tautan situs web, email, notifikasi push, kode QR. iOS menggunakan NSUserActivity + universal link, Android — intent-filter + deep link.

swift
// URL Router — parsing deep link dan navigasi
protocol URLRoute {
    var pattern: String { get }
    func navigate(parameters: [String: String], router: RouterProtocol)
}

struct ProfileRoute: URLRoute {
    let pattern = "myapp://profile/{userId}"

    func navigate(parameters: [String: String], router: RouterProtocol) {
        guard let userId = parameters["userId"] else { return }
        let profileVC = ProfileViewController(userId: userId)
        router.push(profileVC, animated: true)
    }
}

// URL Router — pemetaan URL ke rute
class URLRouter {
    private var routes: [URLRoute] = []

    func handle(_ url: URL, router: RouterProtocol) {
        for route in routes {
            if let params = matchPattern(route.pattern, url: url) {
                route.navigate(parameters: params, router: router)
                return
            }
        }
    }
}

Deep link routing dalam praktik — aplikasi harus memproses deep link dalam tiga keadaan: belum dimulai (memulai dengan deep link), di latar belakang (pemulihan dari latar belakang), aktif (onNewIntent/SceneDelegate). URL Router harus memulihkan tumpukan balik dengan benar: saat deep link ke layar profil, pengguna harus dapat menekan Back dan kembali ke layar sebelumnya. iOS dan Android menangani tumpukan balik secara berbeda — Router harus mempertimbangkan karakteristik platform.

Perbandingan Router dengan Coordinator dan Navigator

Router vs Coordinator — Router menjawab pertanyaan "bagaimana menampilkan layar?" (push/present), Coordinator — "layar mana yang akan ditampilkan?" (flow mana yang akan dijalankan). Router — alat navigasi, Coordinator — pengatur flow. Router digunakan oleh Coordinator. Di VIPER, Router menjalankan kedua fungsi: memutuskan ke mana pergi dan bagaimana menampilkan. Di MVVM-C, Router — protokol terpisah yang digunakan oleh Coordinator. Pola-pola ini tidak saling mengecualikan, melainkan saling melengkapi.

KarakteristikRouterCoordinatorNavigator
FokusMekanika navigasiFlow navigasiAkses global
TingkatUI-framework (push/present)Logika bisnis (flow)Infrastruktur
Pembuatan layarMenerima VC jadiMembuat VC melalui pabrikMembuat VC
Siklus hidupSatu per navigasichildCoordinatorsSingleton

Router vs Navigator — Navigator — nama lama Router di komunitas iOS. Dalam implementasi awal, Navigator adalah kelas Singleton dengan metode perpindahan. Navigator — Router-singleton global. Navigator lebih sederhana, tetapi menciptakan ketergantungan tersembunyi. Router berbasis protokol — lebih mudah diuji dan lebih modular. Navigator cocok untuk proyek tanpa arsitektur ketat, Router — untuk Clean Architecture dan VIPER.

Pertanyaan yang sering diajukan

Apa perbedaan antara Router dan Coordinator?

Router — abstraksi di atas UINavigationController (push/present/pop). Coordinator — lapisan di atas Router yang mengelola flow (layar mana yang akan ditampilkan berikutnya). Router bertanggung jawab atas mekanika, Coordinator — atas logika navigasi. Coordinator menggunakan Router untuk melakukan transisi. Di VIPER, Router menggabungkan kedua fungsi, di MVVM-C — dipisahkan.

Apakah wajib menggunakan Router di aplikasi mobile?

Tidak. Untuk aplikasi dengan 3-5 layar, pemanggilan langsung navigationController.pushViewController adalah solusi normal. Router menjadi berguna pada 10+ layar, deep link, notifikasi push, dan arsitektur modular. Router menyederhanakan pengujian navigasi dan memungkinkan pemrosesan terpusat transisi dari sumber mana pun (tombol, deep link, push).

Bagaimana Router terkait dengan Deep Links?

URL Router — ekstensi Router yang mem-parse deep link dan universal link. URL Router menentukan kecocokan antara URL dan layar aplikasi. Misalnya, route myapp://profile/42 → ProfileViewController(userId: 42). URL Router memusatkan pemrosesan deep link dari berbagai sumber: notifikasi push, kode QR, tautan email, tautan universal.

Bisakah Router digunakan tanpa Coordinator?

Ya. Router dapat berfungsi secara mandiri — sebagai Navigator global atau sebagai komponen modul VIPER. Router tanpa Coordinator — hanya enkapsulasi UINavigationController di belakang protokol. Coordinator tanpa Router — lebih sulit (ViewController sendiri memanggil push/present), tetapi mungkin. Praktik terbaik — Router + Coordinator bersama-sama.

Apakah Router di Android sama dengan iOS Router?

Secara fungsional — ya, keduanya memusatkan navigasi. Implementasi berbeda: iOS Router — protokol + kelas di sekitar UINavigationController; Android — Jetpack Navigation Component dengan grafik XML dan NavController. Android Router tertanam dalam framework (Navigation Component), iOS Router — implementasi eksternal. Android Router mendukung Safe Args, iOS Router — tidak (perlu generics atau Codable).

Kesimpulan

  • Router — pola routing yang mengenkapsulasi logika perpindahan antar layar
  • iOS Router — protokol dengan metode push/present/pop di sekitar UINavigationController
  • Android Router — Jetpack Navigation Component dengan XML nav_graph dan NavController
  • URL Routing — routing melalui deep link dan tautan universal
  • Router vs Coordinator — Router bertanggung jawab atas mekanika, Coordinator atas flow navigasi
  • Penerapan — arsitektur modular, deep link, pengujian navigasi

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga