Router (روٹر) — ایک آرکیٹیکچرل پیٹرن جو ایپلیکیشن اسکرینوں کے درمیان نیویگیشن منطق کو مرکزی بناتا ہے۔ Router تعین کرتا ہے کہ کسی واقعہ کے پیش آنے پر کہاں اور کیسے نیویگیٹ کرنا ہے۔ iOS میں، Router UINavigationController اور segue کو تجرید کرتا ہے؛ Android میں — FragmentManager اور Jetpack Navigation کے NavController کو۔ Router ایک آزاد پیٹرن کے طور پر یا Coordinator (Router-per-Coordinator) اور VIPER (Router-per-module) کے جزو کے طور پر کام کر سکتا ہے۔ مزید تفصیلات — Android Navigation Component Guide میں۔
اہم نکات
Router — ایک پیٹرن جو اسکرینوں کے درمیان منتقلی کی منطق کو سمیٹتا ہے۔ بنیادی خیال: ViewController (یا Presenter/ViewModel) براہ راست navigationController.pushViewController کو نہیں بلاتا، بلکہ Router کو نیویگیٹ کرنے کے ارادے سے آگاہ کرتا ہے۔ Router فیصلہ کرتا ہے کہ کون سا ViewController بنانا ہے اور اسے کیسے دکھانا ہے۔ Router سادہ (نیویگیشن طریقوں کا ایک سیٹ) یا پیچیدہ (URL اسکیم روٹنگ، deep links اور push اطلاعوں کے ساتھ) ہو سکتا ہے۔
Router کے تین طریقے — خدمت کے طور پر Router (عالمی Navigator singleton)، ماڈیول جزو کے طور پر Router (VIPER طریقہ)، پروٹوکول کے طور پر Router (Coordinator کے لیے تجرید)۔ عالمی Router — سادگی (فی ایپ ایک مثال) — چھوٹے منصوبوں میں مقبول۔ ماڈیولر Router — ہر فیچر کا اپنا Router — VIPER اور Clean Architecture معیار۔ پروٹوکول Router — Coordinator میں استعمال: push/present/pop/dismiss طریقوں کے ساتھ RouterProtocol۔
| طریقہ | ساخت | کب استعمال کریں |
|---|---|---|
| عالمی Navigator | نیویگیشن طریقوں کے ساتھ Singleton | چھوٹے منصوبے، نمونے |
| ماڈیولر Router | ہر ماڈیول کے اندر Router | VIPER, Clean Architecture |
| پروٹوکول Router | Coordinator کے لیے پروٹوکول + نفاذ | MVVM-C, Coordinator پیٹرن |
پیٹرن کی تاریخ — Router ویب فریم ورکس (URL Router — Rails Routes, Express.js) میں ظاہر ہوا اور موبائل ڈویلپمنٹ کے لیے ڈھال لیا گیا۔ iOS میں، VIPER (2015-2017) کے عروج کے ساتھ Router مقبول ہوا۔ Android میں، Router Jetpack Navigation (2018) کا حصہ ہے، Google کا معیاری نیویگیشن حل۔ آج، Router کسی بھی ماڈیولر موبائل ایپلیکیشن آرکیٹیکچر کا لازمی حصہ ہے۔
iOS Router — مختلف نیویگیشن اقسام کے لیے طریقوں والا ایک پروٹوکول۔ بنیادی نفاذ UINavigationController کو لپیٹتا ہے۔ Router موڈل پریزنٹیشن (present/dismiss)، نیویگیشن اسٹیک میں push/pop، Split View Controller کے لیے showDetail اور فل اسکرین پریزنٹیشن (iOS 13+) کو سنبھال سکتا ہے۔ Router ViewControllers نہیں بناتا — یہ ایک تیار مثال حاصل کرتا ہے اور اسے دکھاتا ہے۔ ViewController کی تخلیق ایک فیکٹری (Assembly, DI کنٹینر) یا Coordinator کرتا ہے۔
// iOS کے لیے RouterProtocol
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 کے ذریعے Router نفاذ
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
}
VIPER میں Router — ہر VIPER ماڈیول کا اپنا Router ہوتا ہے، جو جانتا ہے کہ موجودہ ماڈیول سے کون سی اسکرینیں کھولنی ہیں۔ Router ایک فیکٹری کے ذریعے اگلے ماڈیول کا ViewController بناتا ہے اور کنٹرول منتقل کرتا ہے۔ VIPER میں Router واحد جزو ہے جس میں import UIKit ہے (View کے علاوہ)۔ یہ Presenter اور Interactor کی جانچ کو آسان بناتا ہے: وہ UIKit پر منحصر نہیں ہوتے۔
Jetpack Navigation Component — Android کے لیے معیاری روٹر، 2018 سے Google کی تجویز کردہ۔ نیویگیشن XML گراف (nav_graph.xml) میں بیان کی گئی ہے: نوڈ (fragments, activities, destinations) اور کنارے (actions)۔ NavController منتقلی کا انتظام کرتا ہے: FragmentManager.replace/add کو کال کرتا ہے اور بیک اسٹیک کا انتظام کرتا ہے۔ Navigation Component deep links، آرگیومینٹس، منتقلی اینیمیشنز اور type-safe ڈیٹا منتقلی کے لیے Safe Args کو سپورٹ کرتا ہے۔
// 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 — type-safe آرگیومینٹس
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)
}
}
Android Navigation میں Deep links — Navigation Component واضح deep links (PendingIntent + NavDeepLinkBuilder) اور مضمر (مینیفیسٹ میں intent-filter کے ذریعے) کو سپورٹ کرتا ہے۔ ایک deep link nav_graph کے کسی بھی نوڈ تک جا سکتی ہے۔ push اطلاع پروسیسنگ: Notification NavDeepLinkBuilder کے ساتھ PendingIntent بناتا ہے، جو بیک اسٹیک کو بحال کرتا ہے اور مطلوبہ اسکرین کھولتا ہے۔ Navigation Component خود بخود Up/Back بٹنوں کو سنبھالتا ہے اور صارف کو پچھلی اسکرین پر واپس لاتا ہے۔
URL Routing — URL اسکیموں، deep links اور universal links پر مبنی روٹنگ۔ ایپ ایک اسکیم (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۔
// 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 — URLs کو راستوں سے ملانا
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 روٹنگ — ایپ کو تین حالتوں میں deep links کو سنبھالنا چاہیے: چل نہیں رہی (deep link کے ساتھ شروع)، پس منظر میں (پس منظر سے بحالی)، فعال (onNewIntent/SceneDelegate)۔ URL Router کو بیک اسٹیک کو صحیح طریقے سے بحال کرنا چاہیے: پروفائل اسکرین پر deep link کرتے وقت، صارف Back دبا کر پچھلی اسکرین پر واپس آنے کے قابل ہونا چاہیے۔ iOS اور Android بیک اسٹیک کو مختلف طریقے سے سنبھالتے ہیں — Router کو پلیٹ فارم کے مخصوص خصوصیات کو مدنظر رکھنا چاہیے۔
Router vs Coordinator — Router سوال کا جواب دیتا ہے "اسکرین کیسے دکھائیں؟" (push/present)، Coordinator — "کون سی اسکرین دکھائیں؟" (کون سا بہاؤ شروع کریں)۔ Router نیویگیشن کا آلہ ہے، Coordinator بہاؤ کا منتظم ہے۔ Coordinator Router استعمال کرتا ہے۔ VIPER میں، Router دونوں کام انجام دیتا ہے: فیصلہ کرتا ہے کہ کہاں جانا ہے اور کیسے دکھانا ہے۔ MVVM-C میں، Router ایک علیحدہ پروٹوکول ہے جو Coordinator استعمال کرتا ہے۔ پیٹرن ایک دوسرے کو خارج نہیں کرتے بلکہ مکمل کرتے ہیں۔
| خصوصیت | Router | Coordinator | Navigator |
|---|---|---|---|
| فوکس | نیویگیشن میکانکس | نیویگیشن بہاؤ | عالمی رسائی |
| سطح | UI فریم ورک (push/present) | کاروباری منطق (بہاؤ) | بنیادی ڈھانچہ |
| اسکرین تخلیق | تیار VC وصول کرتا ہے | فیکٹری کے ذریعے VC بناتا ہے | VC بناتا ہے |
| زندگی کا دور | فی نیویگیشن ایک | childCoordinators | Singleton |
Router vs Navigator — Navigator iOS کمیونٹی میں Router کا پرانا نام ہے۔ ابتدائی نفاذ میں، Navigator نیویگیشن طریقوں والا ایک Singleton کلاس تھا۔ Navigator ایک عالمی Router singleton ہے۔ Navigator آسان ہے لیکن پوشیدہ انحصار پیدا کرتا ہے۔ پروٹوکول پر مبنی Router زیادہ جانچ کے قابل اور ماڈیولر ہے۔ Navigator سخت آرکیٹیکچر کے بغیر منصوبوں کے لیے موزوں ہے، Router — Clean Architecture اور VIPER کے لیے۔
اکثر پوچھے گئے سوالات
Router UINavigationController (push/present/pop) پر ایک تجرید ہے۔ Coordinator Router کے اوپر ایک پرت ہے جو بہاؤ (اگلی کون سی اسکرین دکھانی ہے) کا انتظام کرتی ہے۔ Router میکانکس کو سنبھالتا ہے، Coordinator نیویگیشن منطق کو سنبھالتا ہے۔ Coordinator منتقلی انجام دینے کے لیے Router استعمال کرتا ہے۔ VIPER میں، Router دونوں کاموں کو یکجا کرتا ہے؛ MVVM-C میں، وہ الگ ہیں۔
نہیں۔ 3-5 اسکرینوں والی ایپلیکیشنز کے لیے، براہ راست navigationController.pushViewController کالز ایک مکمل قابل قبول حل ہیں۔ Router 10+ اسکرینوں، deep links، push اطلاعوں اور ماڈیولر آرکیٹیکچر کے ساتھ مفید ہو جاتا ہے۔ Router نیویگیشن کی جانچ کو آسان بناتا ہے اور کسی بھی ماخذ (بٹن، deep link، push اطلاع) سے منتقلی کو مرکزی طور پر سنبھالنے کی اجازت دیتا ہے۔
URL Router Router کی ایک توسیع ہے جو deep links اور universal links کو پارس کرتا ہے۔ URL Router URLs اور ایپ اسکرینوں کے درمیان میپنگ کا تعین کرتا ہے۔ مثال کے طور پر، راستہ myapp://profile/42 → ProfileViewController(userId: 42)۔ URL Router مختلف ذرائع سے deep link ہینڈلنگ کو مرکزی بناتا ہے: push اطلاعیں، QR کوڈز، ای میل لنکس، یونیورسل لنکس۔
جی ہاں۔ Router آزادانہ طور پر کام کر سکتا ہے — عالمی Navigator کے طور پر یا VIPER ماڈیول جزو کے طور پر۔ Coordinator کے بغیر Router صرف ایک پروٹوکول کے پیچھے UINavigationController کو سمیٹنا ہے۔ Coordinator کے بغیر Router زیادہ پیچیدہ ہے (ViewController براہ راست push/present کال کرتا ہے)، لیکن ممکن ہے۔ بہترین عمل Router + Coordinator کو ایک ساتھ استعمال کرنا ہے۔
فعال طور پر — جی ہاں، دونوں نیویگیشن کو مرکزی بناتے ہیں۔ نفاذ مختلف ہے: iOS Router — UINavigationController کے ارد گرد پروٹوکول + کلاس؛ Android — XML گراف اور NavController کے ساتھ Jetpack Navigation Component۔ Android Router فریم ورک (Navigation Component) میں بنایا گیا ہے، iOS Router تیسرے فریق کا نفاذ ہے۔ Android Router Safe Args کو سپورٹ کرتا ہے، iOS Router نہیں کرتا (generics یا Codable کی ضرورت ہے)۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں