Router — основе обрасца рутирања у iOS и Android

Аутор: IT Sectr Објављено: 2026-02-19 Време читања: 9 мин

Router (рутер) — архитектонски образац који централизује логику навигације између екрана апликације. Router одређује куда и како прећи када наступи догађај. У iOS-у Router апстрахује UINavigationController и segue, у Android-у — FragmentManager и NavController из Jetpack Navigation. Router може радити као самостални образац или као компонента Coordinator (Router-per-Coordinator) и VIPER (Router-per-module). Више — у Android Navigation Component Guide.

Главно

  • Router — образац рутирања који централизује навигацију између екрана
  • Два нивоа — Router може бити компонента Coordinator или самостални образац
  • iOS Router — апстракција над UINavigationController са методама push/present/pop
  • Android Router — Jetpack Navigation Component са NavController и deep links
  • URL Routing — рутирање на основу URL шема (deeplink, universal link)

Шта је Router: суштина обрасца рутирања

Router — образац који енкапсулира логику преласка између екрана. Главна идеја: ViewController (или Presenter/ViewModel) не позива директно navigationController.pushViewController, већ обавештава Router о намери за прелазак. Router одлучује који ViewController креирати и како га приказати. Router може бити једноставан (скуп метода за навигацију) или сложен (са рутирањем по URL шемама, deep link-овима и push обавештењима).

Три приступа Router-у — Router као сервис (глобални Navigator-singleton), Router као компонента модула (VIPER приступ), Router као протокол (апстракција за Coordinator). Глобални Router — једноставност (једна инстанца по апликацији) — популаран у малим пројектима. Модуларни Router — свака функција има свој Router — стандард VIPER и Clean Architecture. Протоколни Router — користи се у Coordinator-у: RouterProtocol са методама push/present/pop/dismiss.

ПриступСтруктураКада користити
Глобални NavigatorSingleton са методама преласкаМали пројекти, прототипови
Модуларни RouterRouter унутар сваког модулаVIPER, Clean Architecture
Протоколни RouterProtocol + имплементација за CoordinatorMVVM-C, Coordinator pattern

Историја обрасца — Router се појавио у веб фрејмворцима (URL Router — Rails Routes, Express.js) и адаптиран је за мобилни развој. У iOS-у, Router је постао популаран са растом VIPER-а (2015-2017). У Android-у, Router — део Jetpack Navigation (2018), Google-овог стандардног решења за навигацију. Сада је Router неодвојиви део сваке модуларне архитектуре мобилних апликација.

Router у iOS-у: имплементација у Swift-у

iOS Router — протокол са методама за различите типове навигације. Основна имплементација обавија UINavigationController. Router може управљати модалним презентацијама (present/dismiss), push/pop у навигационом стек-у, showDetail за Split View Controller и презентацијама преко целог екрана (iOS 13+). Router не креира ViewController — он добија готову инстанцу и приказује је. Креирање ViewController-а обавља фабрика (Assembly, DI-контејнер) или Coordinator.

swift
// RouterProtocol за 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)
}

// Имплементација Router-а кроз 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 — креирање модула са Router-ом
protocol ProfileModuleFactory {
    func makeProfileView() -> UIViewController
}

Router у VIPER-у — сваки VIPER модул има свој Router који зна које екране отворити из тренутног модула. Router креира ViewController следећег модула кроз фабрику и преноси контролу. Router у VIPER-у — једина компонента која садржи import UIKit (осим View). Ово поједностављује тестирање Presenter-а и Interactor-а: они не зависе од UIKit-а.

Router у Android-у: Jetpack Navigation Component

Jetpack Navigation Component — стандардни рутер за Android, препоручен од Google-а од 2018. године. Навигација је дефинисана у XML графу (nav_graph.xml): чворови (fragments, activities, destinations) и ивице (actions). NavController управља преласцима: позива FragmentManager.replace/add и управља back stack-ом. Navigation Component подржава deep link-ове, аргументе, анимације прелазака и Safe Args за типско-безбедан пренос података.

kotlin
// nav_graph.xml — граф навигације
<!-- @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 — навигација кроз 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 — типски безбедни аргументи
class HomeFragmentArgs : NavArgs {
    val userId: Int get() = arguments?.getInt("userId") ?: 0
}

// NavigationUI — интеграција са 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-ови у Android Navigation-у — Navigation Component подржава експлицитне deep link-ове (PendingIntent + NavDeepLinkBuilder) и имплицитне (кроз intent-filter у манифесту). Deep link може водити до било ког чвора у nav_graph-у. Обрада push обавештења: Notification креира PendingIntent са NavDeepLinkBuilder-ом који обнавља back stack и отвара жељени екран. Navigation Component аутоматски обрађује Up/Back дугмад и враћа корисника на претходни екран.

URL Routing: Deeplink и Universal Link рутирање

URL Routing — рутирање на основу URL шема, deep link-ова и universal link-ова. Апликација региструје шему (myapp://profile/42) или universal link (https://example.com/profile/42). Router парсира URL, издваја параметре (userId=42) и отвара одговарајући екран. URL Routing омогућава отварање апликације споља: путем линка са сајта, из имејла, push обавештења, QR кода. iOS користи NSUserActivity + universal link, Android — intent-filter + deep link.

swift
// URL Router — парсирање deep link-а и навигација
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 — мапирање URL-а на руте
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 у пракси — апликација мора обрадити deep link у три стања: није покренута (покретање са deep link-ом), у позадини (обнављање из позадине), активна (onNewIntent/SceneDelegate). URL Router мора правилно обновити back stack: при deep link-у на екран профила, корисник мора моћи притиснути Back и вратити се на претходни екран. iOS и Android различито обрађују back stack — Router мора узети у обзир платформске карактеристике.

Поређење Router-а са Coordinator-ом и Navigator-ом

Router vs Coordinator — Router одговара на питање "како приказати екран?" (push/present), Coordinator — "који екран приказати?" (који flow покренути). Router — алат за навигацију, Coordinator — организатор flow-а. Router користи Coordinator. У VIPER-у Router обавља обе функције: одлучује куда прећи и како приказати. У MVVM-C-у, Router — засебан протокол који користи Coordinator. Обрасци се не искључују, већ допуњују.

КарактеристикаRouterCoordinatorNavigator
ФокусМеханика навигацијеFlow навигацијеГлобални приступ
НивоUI-framework (push/present)Пословна логика (flow)Инфраструктура
Креирање екранаДобија готов VCКреира VC кроз фабрикуКреира VC
Животни циклусЈедан по навигацијиchildCoordinatorsSingleton

Router vs Navigator — Navigator — застарели назив за Router у iOS заједници. У раним имплементацијама, Navigator је био Singleton класа са методама преласка. Navigator — глобални Router-singleton. Navigator је једноставнији, али ствара скривене зависности. Router на протоколима — тестирабилнији и модуларнији. Navigator одговара за пројекте без строге архитектуре, Router — за Clean Architecture и VIPER.

Често постављана питања

Која је разлика између Router-а и Coordinator-а?

Router — апстракција над UINavigationController (push/present/pop). Coordinator — слој изнад Router-а који управља flow-ом (који екран приказати следећи). Router је одговоран за механику, Coordinator — за логику навигације. Coordinator користи Router за извршење прелазака. У VIPER-у Router комбинује обе функције, у MVVM-C су раздвојене.

Да ли је обавезно користити Router у мобилној апликацији?

Не. За апликације са 3-5 екрана директно позивање navigationController.pushViewController је нормално решење. Router постаје користан код 10+ екрана, deep link-ова, push обавештења и модуларне архитектуре. Router поједностављује тестирање навигације и омогућава централизовану обраду прелазака из било ког извора (дугме, deep link, push).

Како је Router повезан са Deep Links?

URL Router — проширење Router-а које парсира deep link-ове и universal link-ове. URL Router одређује подударање између URL-а и екрана апликације. На пример, route myapp://profile/42 → ProfileViewController(userId: 42). URL Router централизује обраду deep link-ова из различитих извора: push обавештења, QR кодови, имејл линкови, универзални линкови.

Може ли се Router користити без Coordinator-а?

Да. Router може радити самостално — као глобални Navigator или као компонента VIPER модула. Router без Coordinator-а — једноставно енкапсулација UINavigationController-а иза протокола. Coordinator без Router-а — теже (ViewController сам позива push/present), али могуће. Најбоља пракса — Router + Coordinator заједно.

Да ли је Router у Android-у исто што и iOS Router?

Функционално — да, оба централизују навигацију. Имплементација је различита: iOS Router — протокол + класа око UINavigationController; Android — Jetpack Navigation Component са XML графом и NavController-ом. Android Router је уграђен у framework (Navigation Component), iOS Router — спољна имплементација. Android Router подржава Safe Args, iOS Router — не (потребни су generics или Codable).

Закључак

  • Router — образац рутирања који енкапсулира логику прелазака између екрана
  • iOS Router — протокол са методама push/present/pop око UINavigationController
  • Android Router — Jetpack Navigation Component са XML nav_graph и NavController
  • URL Routing — рутирање кроз deep link-ове и универзалне линкове
  • Router vs Coordinator — Router одговоран за механику, Coordinator за flow навигације
  • Примена — модуларна архитектура, deep link-ови, тестирање навигације

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође