Router (marşrutlaşdırıcı) — tətbiqin ekranları arasında naviqasiya məntiqini mərkəzləşdirən memarlıq nümunəsi. Router hadisə baş verdikdə hara və necə keçiləcəyini müəyyən edir. iOS-da Router UINavigationController və segue-ni abstraksiya edir, Android-də — FragmentManager və Jetpack Navigation-dan NavController-i. Router müstəqil nümunə kimi və ya Coordinator (Router-per-Coordinator) və VIPER (Router-per-module) komponenti kimi işləyə bilər. Ətraflı — Android Navigation Component Guide.
Əsas məqamlar
Router — ekranlar arasında keçid məntiqini inkapsulyasiya edən nümunə. Əsas ideya: ViewController (və ya Presenter/ViewModel) birbaşa navigationController.pushViewController çağırmır, Router-ə keçid niyyəti barədə məlumat verir. Router hansı ViewController-ın yaradılacağını və onun necə göstəriləcəyini qərar verir. Router sadə (naviqasiya metodları toplusu) və ya mürəkkəb (URL sxemləri, deep link-lər və push bildirişləri ilə marşrutlaşdırma) ola bilər.
Router-ə üç yanaşma — Router xidmət kimi (qlobal Navigator-sinqleton), Router modul komponenti kimi (VIPER yanaşması), Router protokol kimi (Coordinator üçün abstraksiya). Qlobal Router — sadəlik (tətbiq üçün bir nümunə) — kiçik layihələrdə populyardır. Modul Router — hər bir funksiya öz Router-inə malikdir — VIPER və Clean Architecture standartı. Protokol Router — Coordinator-da istifadə olunur: push/present/pop/dismiss metodları ilə RouterProtocol.
| Yanaşma | Struktur | Nə vaxt istifadə etməli |
|---|---|---|
| Qlobal Navigator | Keçid metodları ilə Singleton | Kiçik layihələr, prototiplər |
| Modul Router | Hər modul daxilində Router | VIPER, Clean Architecture |
| Protokol Router | Protocol + Coordinator üçün tətbiq | MVVM-C, Coordinator nümunəsi |
Nümunənin tarixi — Router veb-freymvorklarda (URL Router — Rails Routes, Express.js) yaranmış və mobil inkişaf üçün uyğunlaşdırılmışdır. iOS-da Router VIPER-in inkişafı ilə (2015-2017) məşhurlaşdı. Android-də Router — Jetpack Navigation (2018), Google-ın naviqasiya üçün standart həllinin bir hissəsidir. Hal-hazırda Router mobil tətbiqlərin istənilən modul memarlığının ayrılmaz hissəsidir.
iOS Router — müxtəlif naviqasiya növləri üçün metodları olan protokol. Əsas tətbiq UINavigationController-i sarır. Router modal təqdimatları (present/dismiss), naviqasiya yığınında push/pop, Split View Controller üçün showDetail və tam ekran təqdimatlarını (iOS 13+) idarə edə bilər. Router ViewController yaratmır — o hazır nümunə alır və onu göstərir. ViewController yaradılması zavod (Assembly, DI-konteyner) və ya Coordinator tərəfindən həyata keçirilir.
// RouterProtocol iOS üçün
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 vasitəsilə Router tətbiqi
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 ilə modulun yaradılması
protocol ProfileModuleFactory {
func makeProfileView() -> UIViewController
}
VIPER-də Router — hər bir VIPER modulunun cari moduldan hansı ekranların açılacağını bilən öz Router-i var. Router növbəti modulun ViewController-nı zavod vasitəsilə yaradır və idarəni ötürür. VIPER-də Router — View-dən başqa import UIKit olan yeganə komponentdir. Bu, Presenter və Interactor-un test edilməsini asanlaşdırır: onlar UIKit-dən asılı deyil.
Jetpack Navigation Component — 2018-ci ildən Google tərəfindən tövsiyə edilən Android üçün standart router. Naviqasiya XML qrafında (nav_graph.xml) müəyyən edilir: qovşaqlar (fragments, activities, destinations) və kənarlar (actions). NavController keçidləri idarə edir: FragmentManager.replace/add çağırır və back stack-i idarə edir. Navigation Component deep link-ləri, arqumentləri, keçid animasiyalarını və tip təhlükəsiz məlumat ötürülməsi üçün Safe Args-ı dəstəkləyir.
// nav_graph.xml — naviqasiya qrafı
<!-- @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 vasitəsilə naviqasiya
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 təhlükəsiz arqumentlər
class HomeFragmentArgs : NavArgs {
val userId: Int get() = arguments?.getInt("userId") ?: 0
}
// NavigationUI — Toolbar, BottomNav, Drawer ilə inteqrasiya
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-lər — Navigation Component açıq deep link-ləri (PendingIntent + NavDeepLinkBuilder) və gizli deep link-ləri (manifestdə intent-filter vasitəsilə) dəstəkləyir. Deep link nav_graph-ın istənilən qovşağına apara bilər. Push bildirişlərin işlənməsi: Notification NavDeepLinkBuilder ilə PendingIntent yaradır, back stack-i bərpa edir və lazımi ekranı açır. Navigation Component avtomatik olaraq Up/Back düymələrini idarə edir və istifadəçini əvvəlki ekrana qaytarır.
URL Routing — URL sxemləri, deep link-lər və universal link-lər əsasında marşrutlaşdırma. Tətbiq sxemi (myapp://profile/42) və ya universal link-i (https://example.com/profile/42) qeydiyyatdan keçirir. Router URL-i təhlil edir, parametrləri çıxarır (userId=42) və müvafiq ekranı açır. URL Routing tətbiqin xaricdən açılmasına imkan verir: saytdan keçid, email, push bildirişi, QR kodu vasitəsilə. iOS NSUserActivity + universal link, Android isə intent-filter + deep link istifadə edir.
// URL Router — deep link təhlili və naviqasiya
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-lərin marşrutlarla uyğunlaşdırılması
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 praktikada — tətbiq deep link-i üç vəziyyətdə idarə etməlidir: işə salınmamış (deep link ilə işə salma), fonda (fondan bərpa), aktiv (onNewIntent/SceneDelegate). URL Router back stack-i düzgün bərpa etməlidir: profil ekranına deep link zamanı istifadəçi Back düyməsini sıxaraq əvvəlki ekrana qayıda bilməlidir. iOS və Android back stack-i fərqli idarə edir — Router platforma xüsusiyyətlərini nəzərə almalıdır.
Router vs Coordinator — Router "ekranı necə göstərmək?" sualına cavab verir (push/present), Coordinator — "hansı ekranı göstərmək?" (hansı flow-u işə salmaq). Router naviqasiya alətidir, Coordinator flow təşkilatçısıdır. Router Coordinator tərəfindən istifadə olunur. VIPER-də Router hər iki funksiyanı yerinə yetirir: hara keçəcəyini və necə göstərəcəyini qərar verir. MVVM-C-də Router — Coordinator tərəfindən istifadə olunan ayrıca protokoldur. Nümunələr bir-birini istisna etmir, əksinə tamamlayır.
| Xüsusiyyət | Router | Coordinator | Navigator |
|---|---|---|---|
| Fokus | Naviqasiya mexanikası | Naviqasiya flow-u | Qlobal giriş |
| Səviyyə | UI-freymvork (push/present) | Biznes məntiqi (flow) | İnfrastruktur |
| Ekran yaradılması | Hazır VC alır | Zavod vasitəsilə VC yaradır | VC yaradır |
| Həyat dövrü | Hər naviqasiya üçün bir | childCoordinators | Singleton |
Router vs Navigator — Navigator — iOS icmasında Router-in köhnəlmiş adı. Erkən tətbiqlərdə Navigator keçid metodları olan Singleton sinfi idi. Navigator — qlobal Router-singletondur. Navigator daha sadədir, lakin gizli asılılıqlar yaradır. Protokollarda Router — daha test edilə bilən və modul xarakterlidir. Navigator ciddi memarlığı olmayan layihələr üçün, Router isə Clean Architecture və VIPER üçün uyğundur.
Tez-tez verilən suallar
Router — UINavigationController (push/present/pop) üzərində abstraksiyadır. Coordinator — Router üzərində qat, flow-u (növbəti ekranı göstərmək) idarə edir. Router mexanikaya, Coordinator naviqasiya məntiqinə cavabdehdir. Coordinator keçidləri yerinə yetirmək üçün Router-dən istifadə edir. VIPER-də Router hər iki funksiyanı birləşdirir, MVVM-C-də ayrılır.
Xeyr. 3-5 ekranlı tətbiqlər üçün birbaşa navigationController.pushViewController çağırışları normal həlldir. Router 10+ ekran, deep link-lər, push bildirişləri və modul memarlıqda faydalı olur. Router naviqasiyanın test edilməsini asanlaşdırır və istənilən mənbədən (düymə, deep link, push) keçidlərin mərkəzləşdirilmiş işlənməsinə imkan verir.
URL Router — deep link-ləri və universal link-ləri təhlil edən Router genişləndirməsidir. URL Router URL ilə tətbiq ekranı arasında uyğunluğu müəyyən edir. Məsələn, route myapp://profile/42 → ProfileViewController(userId: 42). URL Router müxtəlif mənbələrdən deep link-lərin işlənməsini mərkəzləşdirir: push bildirişləri, QR kodları, email keçidləri, universal keçidlər.
Bəli. Router müstəqil işləyə bilər — qlobal Navigator kimi və ya VIPER modul komponenti kimi. Coordinator olmadan Router — sadəcə UINavigationController-in protokol arxasında inkapsulyasiyasıdır. Coordinator olmadan Router — daha çətindir (ViewController özü push/present çağırır), lakin mümkündür. Ən yaxşı təcrübə — Router + Coordinator birlikdə.
Funksional olaraq — bəli, hər ikisi naviqasiyanı mərkəzləşdirir. Tətbiq fərqlidir: iOS Router — protokol + UINavigationController ətrafında sinif; Android — Jetpack Navigation Component XML qraf və NavController ilə. Android Router freymvorka daxildir (Navigation Component), iOS Router — xarici tətbiqdir. Android Router Safe Args-ı dəstəkləyir, iOS Router — yox (generics və ya Codable lazımdır).
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun