Router (marshrutlagich) — ilova ekranlari o'rtasidagi navigatsiya mantiqini markazlashtiradigan arxitektura namunasi. Router hodisa yuz berganda qayerga va qanday o'tishni aniqlaydi. iOS-da Router UINavigationController va segue-ni abstraksiya qiladi, Android-da — FragmentManager va Jetpack Navigation-dan NavController-ni. Router mustaqil namuna sifatida yoki Coordinator (Router-per-Coordinator) va VIPER (Router-per-module) komponenti sifatida ishlashi mumkin. Batafsil — Android Navigation Component Guide.
Asosiy fikrlar
Router — ekranlar o'rtasidagi o'tish mantiqini inkapsulyatsiya qiladigan namuna. Asosiy g'oya: ViewController (yoki Presenter/ViewModel) to'g'ridan-to'g'ri navigationController.pushViewController chaqirmaydi, balki Router-ga o'tish niyati haqida xabar beradi. Router qaysi ViewController yaratilishini va uni qanday ko'rsatishni hal qiladi. Router oddiy (navigatsiya metodlari to'plami) yoki murakkab (URL sxemalari, deep link-lar va push bildirishnomalari bilan marshrutlash) bo'lishi mumkin.
Router-ga uch yondashuv — Router xizmat sifatida (global Navigator-singleton), Router modul komponenti sifatida (VIPER yondashuvi), Router protokol sifatida (Coordinator uchun abstraksiya). Global Router — soddalik (ilova uchun bitta nusxa) — kichik loyihalarda mashhur. Modul Router — har bir funksiya o'z Router-iga ega — VIPER va Clean Architecture standarti. Protokol Router — Coordinator-da ishlatiladi: push/present/pop/dismiss metodlari bilan RouterProtocol.
| Yondashuv | Tuzilma | Qachon ishlatish |
|---|---|---|
| Global Navigator | O'tish metodlari bilan Singleton | Kichik loyihalar, prototiplar |
| Modul Router | Har bir modul ichida Router | VIPER, Clean Architecture |
| Protokol Router | Protocol + Coordinator uchun amalga oshirish | MVVM-C, Coordinator namunasi |
Namunaning tarixi — Router veb-freymvorklarda (URL Router — Rails Routes, Express.js) paydo bo'lgan va mobil ishlab chiqish uchun moslashtirilgan. iOS-da Router VIPERning rivojlanishi bilan (2015-2017) mashhur bo'ldi. Android-da Router — Jetpack Navigation (2018), Google-ning navigatsiya uchun standart yechimining bir qismi. Hozirda Router mobil ilovalarning har qanday modul arxitekturasining ajralmas qismidir.
iOS Router — turli xil navigatsiya turlari uchun metodlari bo'lgan protokol. Asosiy amalga oshirish UINavigationController-ni o'rab oladi. Router modal taqdimotlarni (present/dismiss), navigatsiya stekida push/pop, Split View Controller uchun showDetail va to'liq ekran taqdimotlarini (iOS 13+) boshqarishi mumkin. Router ViewController yaratmaydi — u tayyor nusxani oladi va uni ko'rsatadi. ViewController yaratilishi zavod (Assembly, DI-konteyner) yoki Coordinator tomonidan amalga oshiriladi.
// RouterProtocol iOS uchun
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)
}
// UINavigationController orqali Router amalga oshirish
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 bilan modul yaratish
protocol ProfileModuleFactory {
func makeProfileView() -> UIViewController
}
VIPER-da Router — har bir VIPER moduli joriy moduldan qaysi ekranlarni ochishni biladigan o'z Router-iga ega. Router navbatdagi modulning ViewController-ni zavod orqali yaratadi va boshqaruvni uzatadi. VIPER-da Router — View-dan tashqari import UIKit bo'lgan yagona komponent. Bu Presenter va Interactor-ni sinashni osonlashtiradi: ular UIKit-ga bog'liq emas.
Jetpack Navigation Component — 2018 yildan Google tomonidan tavsiya etilgan Android uchun standart router. Navigatsiya XML grafida (nav_graph.xml) belgilanadi: tugunlar (fragments, activities, destinations) va qirralar (actions). NavController o'tishlarni boshqaradi: FragmentManager.replace/add chaqiradi va back stack-ni boshqaradi. Navigation Component deep link-lar, argumentlar, o'tish animatsiyalari va ma'lumotlarni tip-xavfsiz uzatish uchun Safe Args-ni qo'llab-quvvatlaydi.
// nav_graph.xml — navigatsiya grafi
<!-- @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 orqali navigatsiya
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 — tip-xavfsiz argumentlar
class HomeFragmentArgs : NavArgs {
val userId: Int get() = arguments?.getInt("userId") ?: 0
}
// NavigationUI — Toolbar, BottomNav, Drawer bilan integratsiya
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)
}
}
Android Navigation-da Deep link-lar — Navigation Component ochiq deep link-larni (PendingIntent + NavDeepLinkBuilder) va yashirin deep link-larni (manifestda intent-filter orqali) qo'llab-quvvatlaydi. Deep link nav_graph-ning istalgan tuguniga olib borishi mumkin. Push bildirishnomalarini qayta ishlash: Notification NavDeepLinkBuilder bilan PendingIntent yaratadi, back stack-ni tiklaydi va kerakli ekranni ochadi. Navigation Component avtomatik ravishda Up/Back tugmalarini boshqaradi va foydalanuvchini oldingi ekranga qaytaradi.
URL Routing — URL sxemalari, deep link-lar va universal link-lar asosida marshrutlash. Ilova sxemani (myapp://profile/42) yoki universal link-ni (https://example.com/profile/42) ro'yxatdan o'tkazadi. Router URL-ni tahlil qiladi, parametrlarni chiqaradi (userId=42) va tegishli ekranni ochadi. URL Routing ilovani tashqaridan ochish imkonini beradi: sayt linki, email, push bildirishnoma, QR kod orqali. iOS NSUserActivity + universal link, Android esa intent-filter + deep link ishlatadi.
// URL Router — deep link tahlili va navigatsiya
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-larni marshrutlar bilan moslashtirish
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 amaliyotda — ilova deep link-ni uch holatda qayta ishlashi kerak: ishga tushirilmagan (deep link bilan ishga tushirish), fonda (fondan tiklash), faol (onNewIntent/SceneDelegate). URL Router back stack-ni to'g'ri tiklash kerak: profil ekraniga deep link paytida foydalanuvchi Back tugmasini bosib oldingi ekranga qaytishi mumkin bo'lishi kerak. iOS va Android back stack-ni turlicha boshqaradi — Router platforma xususiyatlarini hisobga olishi kerak.
Router vs Coordinator — Router "ekranni qanday ko'rsatish?" degan savolga javob beradi (push/present), Coordinator — "qaysi ekranni ko'rsatish?" (qaysi flow-ni ishga tushirish). Router navigatsiya vositasi, Coordinator flow tashkilotchisi. Router Coordinator tomonidan ishlatiladi. VIPER-da Router ikkala funksiyani bajaradi: qayerga o'tishni va qanday ko'rsatishni hal qiladi. MVVM-C-da Router — Coordinator tomonidan ishlatiladigan alohida protokol. Namunalar bir-birini istisno qilmaydi, aksincha to'ldiradi.
| Xususiyat | Router | Coordinator | Navigator |
|---|---|---|---|
| Fokus | Navigatsiya mexanikasi | Navigatsiya flow-i | Global kirish |
| Daraja | UI-freymvork (push/present) | Biznes mantiq (flow) | Infratuzilma |
| Ekran yaratish | Tayyor VC oladi | VC-ni zavod orqali yaratadi | VC yaratadi |
| Hayot sikli | Har bir navigatsiya uchun bitta | childCoordinators | Singleton |
Router vs Navigator — Navigator — iOS hamjamiyatida Router-ning eskirgan nomi. Dastlabki amalga oshirishlarda Navigator o'tish metodlari bilan Singleton sinfi edi. Navigator — global Router-singletondir. Navigator soddaroq, lekin yashirin bog'liqliklarni yaratadi. Protokollardagi Router — sinovdan o'tkaziladigan va modulliroq. Navigator qat'iy arxitekturasiz loyihalar uchun, Router esa Clean Architecture va VIPER uchun mos keladi.
Tez-tez beriladigan savollar
Router — UINavigationController (push/present/pop) ustidagi abstraksiya. Coordinator — Router ustidagi qatlam, flow-ni (keyingi ekranni ko'rsatish) boshqaradi. Router mexanika uchun, Coordinator navigatsiya mantig'i uchun javobgardir. Coordinator o'tishlarni amalga oshirish uchun Router-dan foydalanadi. VIPER-da Router ikkala funksiyani birlashtiradi, MVVM-C-da ular ajratilgan.
Yo'q. 3-5 ekranli ilovalar uchun to'g'ridan-to'g'ri navigationController.pushViewController chaqirishlari oddiy yechimdir. Router 10+ ekran, deep link-lar, push bildirishnomalari va modul arxitekturasida foydali bo'ladi. Router navigatsiyani sinashni osonlashtiradi va istalgan manbadan (tugma, deep link, push) o'tishlarni markazlashtirilgan qayta ishlash imkonini beradi.
URL Router — deep link-lar va universal link-larni tahlil qiluvchi Router kengaytmasi. URL Router URL bilan ilova ekrani o'rtasidagi moslikni aniqlaydi. Masalan, route myapp://profile/42 → ProfileViewController(userId: 42). URL Router turli manbalardan deep link-larni qayta ishlashni markazlashtiradi: push bildirishnomalari, QR kodlar, email havolalar, universal havolalar.
Ha. Router mustaqil ishlashi mumkin — global Navigator sifatida yoki VIPER modul komponenti sifatida. Coordinatorsiz Router — shunchaki UINavigationController-ni protokol orqasida inkapsulyatsiya qilish. Coordinatorsiz Router — qiyinroq (ViewController o'zi push/present chaqiradi), lekin mumkin. Eng yaxshi amaliyot — Router + Coordinator birgalikda.
Funksional jihatidan — ha, ikkalasi ham navigatsiyani markazlashtiradi. Amalga oshirish farq qiladi: iOS Router — protokol + UINavigationController atrofidagi sinf; Android — Jetpack Navigation Component XML grafi va NavController bilan. Android Router freymvorkka o'rnatilgan (Navigation Component), iOS Router — tashqi amalga oshirish. Android Router Safe Args-ni qo'llab-quvvatlaydi, iOS Router — yo'q (generics yoki Codable kerak).
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.