Coordinator: کلیدی تصورات، iOS نیویگیشن کے لیے کوآرڈینیٹر پیٹرن

مصنف: IT Sectr اشاعت: 2026-02-18 مطالعے کا وقت: 9 منٹ

Coordinator (کوآرڈینیٹر) — ایک آرکیٹیکچرل نیویگیشن پیٹرن ہے جو اسکرینوں کے درمیان منتقلی کی منطق کو ViewController سے علیحدہ کلاسز میں منتقل کرتا ہے۔ یہ پیٹرن 2015 میں Soroush Khanlou نے تجویز کیا تھا اور iOS کمیونٹی میں وسیع پیمانے پر اپنایا گیا۔ Coordinator ایپلیکیشن کے بہاؤ کو منظم کرتا ہے: ViewController بناتا اور دکھاتا ہے، اسکرینوں کے درمیان ڈیٹا منتقل کرتا ہے، اور بہاؤ کی تکمیل کو ہینڈل کرتا ہے۔ یہ پیٹرن کنٹرولر سے نیویگیشن نکال کر Massive View Controller کے مسئلے کو حل کرتا ہے۔ مزید معلومات کے لیے Coordinator پر اصل مضمون دیکھیں۔

اہم نکات

  • Coordinator — نیویگیشن پیٹرن جو ViewController سے منتقلی کی منطق نکالتا ہے
  • ذمہ داریوں کی علیحدگی — ViewController UI کا انتظام کرتا ہے، Coordinator نیویگیشن کا
  • Router — UINavigationController کو تجریدی بنانے کے لیے Coordinator کا معاون جزو
  • Flow — ایک Coordinator کے زیر انتظام اسکرینوں کا سلسلہ (مثال، onboarding)
  • تفویض — ذیلی کوآرڈینیٹر delegate/protocol کے ذریعے والدین کو رپورٹ کرتے ہیں

Coordinator کیا ہے: نیویگیشن پیٹرن کا جوہر

Coordinator — ایک پیٹرن ہے جو iOS ایپلیکیشن میں نیویگیشن کی ذمہ داری سنبھالتا ہے۔ معیاری UIKit میں، ViewController خود منتقلی کا انتظام کرتا ہے: present، push، show segue — تمام نیویگیشن طریقے UIViewController سے بلائے جاتے ہیں۔ Coordinator اس منطق کو نکالتا ہے: ViewController ایک واقعہ رپورٹ کرتا ہے (مثال، «صارف نے لاگ ان بٹن پر کلک کیا»)، Coordinator فیصلہ کرتا ہے کہ اگلی کون سی اسکرین دکھانی ہے۔ ViewController صرف UI منطق کے ساتھ رہتا ہے اور نیویگیشن کو کوآرڈینیٹر کو سونپتا ہے۔

پیٹرن کا ڈھانچہ — start() اور finish() طریقوں کے ساتھ CoordinatorProtocol۔ start() — بہاؤ کا آغاز: پہلا ViewController بنانا اور دکھانا۔ finish() — والدین کوآرڈینیٹر کو اطلاع کے ساتھ بہاؤ کی تکمیل۔ Router — UINavigationController (یا UISplitViewController) کے گرد ایک لفافہ، جو show، push، pop، dismiss طریقے فراہم کرتا ہے۔ کوآرڈینیٹر براہ راست UINavigationController کے ساتھ کام نہیں کرتا — صرف Router کے ذریعے۔ یہ نیویگیشن کی جانچ اور UI فریم ورک تبدیل کرنے کی اجازت دیتا ہے۔

جزوکردارمثال
Coordinatorنیویگیشن بہاؤ کا انتظامAuthCoordinator, ProfileCoordinator
RouterUINavigationController پر تجریدpush, present, pop, dismiss
ViewControllerUI + Coordinator کو واقعات کی تفویضLoginViewController.delegate

مسائل جو Coordinator حل کرتا ہے — Massive View Controller (نیویگیشن کنٹرولر کے بڑھنے کی ایک عام وجہ ہے)۔ معیاری UIKit میں، ViewController میں prepareForSegue، نیویگیشن ڈیلیگیٹس، unwind segues کی ہینڈلنگ شامل ہے۔ Coordinator اسے ختم کرتا ہے۔ Storyboard میں Segues اسکرینوں کے درمیان جامد کنکشن ہیں، Coordinator شرائط کے ساتھ متحرک نیویگیشن فراہم کرتا ہے۔ نیویگیشن کی جانچ ممکن ہو جاتی ہے: Router کالوں کی ترتیب کی تصدیق کرکے Coordinator کو UI کے بغیر جانچا جا سکتا ہے۔

Swift میں Coordinator: Router اور Flow کے ساتھ نفاذ

Swift میں بنیادی Coordinator — Router کے لیے ایک منسلک قسم اور start/finish طریقوں کے ساتھ ایک پروٹوکول۔ Router — UINavigationController کو تجریدی بنانے والا پروٹوکول۔ Router کا ٹھوس نفاذ UINavigationController کو لپیٹتا ہے اور اسے طریقے سونپتا ہے۔ Coordinator init میں Router قبول کرتا ہے اور نیویگیشن کے لیے استعمال کرتا ہے۔ ذیلی کوآرڈینیٹر زندگی کے دورانیے کے انتظام کے لیے childCoordinators صف میں محفوظ کیے جاتے ہیں۔

swift
// Router — نیویگیشن تجرید
protocol RouterProtocol: AnyObject {
    func push(_ viewController: UIViewController, animated: Bool)
    func pop(animated: Bool)
    func present(_ viewController: UIViewController, animated: Bool)
    func dismiss(animated: Bool)
}

final class NavigationRouter: RouterProtocol {
    private let navigationController: UINavigationController

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

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

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

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

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

// Coordinator — بہاؤ کا انتظام
protocol CoordinatorProtocol: AnyObject {
    var childCoordinators: [CoordinatorProtocol] { get set }
    var router: RouterProtocol { get }
    func start()
    func finish()
}

class AuthCoordinator: CoordinatorProtocol {
    var childCoordinators: [CoordinatorProtocol] = []
    let router: RouterProtocol

    init(router: RouterProtocol) {
        self.router = router
    }

    func start() {
        let loginVC = LoginViewController()
        loginVC.onLogin = { [weak self] in
            self?.showHome()
        }
        router.push(loginVC, animated: true)
    }

    private func showHome() {
        let homeCoordinator = HomeCoordinator(router: router)
        childCoordinators.append(homeCoordinator)
        homeCoordinator.start()
    }

    func finish() {
        childCoordinators.removeAll()
        router.pop(animated: true)
    }
}

AppDelegate/SceneDelegate میں Coordinator بنانا — AppDelegate یا SceneDelegate UINavigationController بناتا ہے، اسے NavigationRouter میں لپیٹتا ہے، ایک جڑ Coordinator (AppCoordinator) بناتا ہے اور start() کال کرتا ہے۔ AppCoordinator ایپلیکیشن کی حالت کے لحاظ سے onboarding، لاگ ان یا مرکزی اسکرین دکھانے کا فیصلہ کرتا ہے۔ Coordinator نیویگیشن کے لیے واحد داخلہ نقطہ ہے، ViewController دوسری اسکرینوں کے بارے میں نہیں جانتا۔

ذیلی Coordinator اور کوآرڈینیٹر کا درجہ بندی

کوآرڈینیٹر کا درجہ بندی — AppCoordinator → AuthCoordinator/MainCoordinator → ProfileCoordinator/SettingsCoordinator۔ ذیلی کوآرڈینیٹر والدین کے ذریعے بنایا جاتا ہے اور childCoordinators صف میں محفوظ کیا جاتا ہے۔ جب ذیلی کوآرڈینیٹر اپنا کام مکمل کرتا ہے، تو یہ والدین پر finish() کال کرتا ہے، اور والدین اسے childCoordinators سے ہٹا دیتا ہے۔ یہ میموری لیک کو روکتا ہے: Coordinator کے پاس ViewController پر ایک مضبوط حوالہ ہوتا ہے (Router کے ذریعے)، اور childCoordinators سے ہٹائے بغیر آبجیکٹ آزاد نہیں ہوگا۔

swift
// Coordinator -> Parent مواصلت کے لیے Delegate
protocol AuthCoordinatorDelegate: AnyObject {
    func authCoordinatorFinished(_ coordinator: AuthCoordinator)
}

class AuthCoordinator: CoordinatorProtocol {
    weak var delegate: AuthCoordinatorDelegate?

    func finish() {
        delegate?.authCoordinatorFinished(self)
    }
}

// AppCoordinator — والدین
class AppCoordinator: AuthCoordinatorDelegate {
    func startAuthFlow() {
        let authCoordinator = AuthCoordinator(router: router)
        authCoordinator.delegate = self
        childCoordinators.append(authCoordinator)
        authCoordinator.start()
    }

    func authCoordinatorFinished(_ coordinator: AuthCoordinator) {
        childCoordinators.removeAll { $0 is AuthCoordinator }
        startMainFlow()
    }
}

childCoordinators کا انتظام — Coordinator کو صف سے ہٹانا اسے آزاد کرنے کا واحد طریقہ ہے۔ اگر آپ مکمل شدہ Coordinator کو ہٹانا بھول جاتے ہیں، تو یہ اپنے ViewControllers سمیت میموری میں رہتا ہے۔ تجویز کردہ طریقے: والدین کا didMove(toParent:)، تکمیل پر callback، یا خودکار ہٹانے کے لیے Combine publisher۔ Coordinator پیٹرن اطلاع کے طریقہ کار کی وضاحت نہیں کرتا — delegate، closure یا Combine — انتخاب ڈویلپر پر منحصر ہے۔

کوآرڈینیٹرز کے درمیان ڈیٹا منتقل کرنے کے طریقے

delegate کے ذریعے ڈیٹا کی منتقلی — ذیلی Coordinator ایک delegate پروٹوکول کی وضاحت کرتا ہے جس کے طریقوں کے ذریعے نتائج منتقل کیے جاتے ہیں: func authCoordinator(_:didLoginWith user: User)۔ والدین پروٹوکول کو نافذ کرتا ہے اور ذیلی بہاؤ کی تکمیل پر ڈیٹا وصول کرتا ہے۔ یہ قسم سے محفوظ اور واضح ہے۔ نقصان: ہر ذیلی Coordinator کے لیے علیحدہ پروٹوکول درکار ہے۔ 10+ Coordinator والے منصوبوں کے لیے یہ فائلوں میں اضافے کا باعث بنتا ہے۔

Result قسم کے ذریعے ڈیٹا کی منتقلی — finish طریقہ Result قبول کرتا ہے، جہاں Output بہاؤ کے نتیجے کی عام قسم ہے۔ Coordinator — ایک منسلک نتیجہ قسم کے ساتھ عام قسم۔ callback کے ساتھ start(): start(completion: @escaping (Output) -> Void)۔ یہ کوڈ کو کم کرتا ہے: ہر coordinator کے لیے علیحدہ پروٹوکول لکھنے کی ضرورت نہیں ہے۔ RxSwift/Combine: Coordinator PassthroughSubject/Publisher کے ذریعے نتیجہ شائع کرتا ہے۔ انتخاب ٹیم کے آرکیٹیکچرل نقطہ نظر پر منحصر ہے۔

طریقہفوائدنقصانات
Delegateقسم سے محفوظ، واضح، علیحدہ پروٹوکولبہت سے پروٹوکول، بہت زیادہ بائلرپلیٹ
Closureمختصر، کم فائلیںretain cycle کو ڈیبگ کرنا مشکل
Combine/Rxرد عمل، آسانی سے ملایا جا سکتا ہےلائبریری پر انحصار، ڈیبگ کرنا مشکل

مشترکہ ڈیٹا پرت — Coordinator براہ راست ڈیٹا منتقل نہیں کرتے بلکہ مشترکہ سروس/ریپوزٹری استعمال کرتے ہیں۔ AuthCoordinator ٹوکن کو Keychain/UserDefaults میں محفوظ کرتا ہے، ProfileCoordinator وہاں سے پڑھتا ہے۔ Coordinator براہ راست کالوں کے بجائے مشترکہ حالت (Dependency Injection کنٹینر) کے ذریعے بات چیت کرتے ہیں۔ یہ Coordinator کے درمیان وابستگی کو کم کرتا ہے لیکن مشترکہ حالت پر پوشیدہ انحصار پیدا کرتا ہے۔

Coordinator کا Router، VIPER اور MVVM-C سے موازنہ

Coordinator بمقابلہ Router — Router Coordinator کا ایک جزو ہے جو UINavigationController کو تجریدی بناتا ہے۔ Coordinator بہاؤ (کون سی اسکرین دکھانی ہے) کے لیے ذمہ دار ہے، Router — میکانکس (کیسے دکھانا ہے: push/present) کے لیے۔ Router «کیسے» ہے، Coordinator «کیا» ہے۔ آپ Router کو Coordinator کے بغیر استعمال کر سکتے ہیں (مثال، Navigator سنگلٹن)، لیکن Coordinator بغیر Router کے صرف ایک مختلف تجرید کے ساتھ ViewController ہے۔ عام طور پر دونوں پیٹرن ایک ساتھ استعمال ہوتے ہیں۔

Coordinator بمقابلہ VIPER — VIPER میں نیویگیشن کے لیے ذمہ دار Wireframe جزو ہے — Coordinator کے مشابہ۔ VIPER میں، Wireframe ماڈیول کا حصہ ہے، Coordinator ماڈیولز کے اوپر ایک علیحدہ پرت ہے۔ VIPER ماڈیول (View-Interactor-Presenter-Entity-Router) نیویگیشن کو ماڈیول کے حصے کے طور پر شامل کرتا ہے۔ Coordinator ماڈیولز کے لیے خارجی ہے: یہ ماڈیولز بناتا اور جوڑتا ہے، لیکن ان کا حصہ نہیں ہے۔ Coordinator مختلف بہاؤ میں اسکرینوں کے دوبارہ استعمال کے لیے زیادہ لچکدار ہے۔

MVVM-C — Coordinator کے ساتھ MVVM کی توسیع۔ ViewModel براہ راست Coordinator کے بارے میں نہیں جانتا — ViewController ViewModel کے ذریعے نیویگیشن سونپتا ہے، ViewModel ایک پروٹوکول کے ذریعے coordinator کو کال کرتا ہے۔ MVVM-C SwiftUI کے ساتھ iOS منصوبوں کے لیے معیاری نقطہ نظر ہے: Coordinator NavigationStack یا fullScreenCover کا انتظام کرتا ہے، ViewModel حالت شائع کرکے coordinator کو کال کرتا ہے۔ Apple SwiftUI کے لیے Coordinator کی سفارش نہیں کرتا — NavigationStack اور NavigationPath بلٹ ان نیویگیشن میکانزم ہیں۔

swift
// MVVM-C: ViewModel پروٹوکول کے ذریعے Coordinator کو کال کرتا ہے
protocol AuthNavigationProtocol: AnyObject {
    func showMainScreen()
    func showForgotPassword()
}

class AuthViewModel: ObservableObject {
    weak var navigation: AuthNavigationProtocol?

    func loginTapped() {
        // منطق...
        navigation?.showMainScreen()
    }
}

اکثر پوچھے جانے والے سوالات

کیا SwiftUI کے لیے Coordinator ضروری ہے؟

SwiftUI کے لیے، بلٹ ان نیویگیشن (NavigationStack, NavigationPath) اکثر Coordinator کی جگہ لے لیتی ہے۔ Apple path-based نیویگیشن کی سفارش کرتا ہے۔ Coordinator پیچیدہ بہاؤ کے لیے معنی رکھتا ہے جس میں گہری شرائط ہوں (کردار کے لحاظ سے onboarding-لاگ ان-مرکزی اسکرین)۔ سادہ SwiftUI ایپلیکیشنز کے لیے Coordinator ضرورت سے زیادہ ہے — NavigationPath استعمال کریں۔

کیا Coordinator ایک Router ہے؟

نہیں، یہ مختلف پیٹرن ہیں۔ Coordinator نیویگیشن بہاؤ کا انتظام کرتا ہے: فیصلہ کرتا ہے کہ کون سی اسکرین دکھانی ہے، ViewControllers بناتا ہے اور انہیں جوڑتا ہے۔ Router UINavigationController پر ایک تجرید ہے: push, present, pop, dismiss۔ Coordinator نیویگیشن انجام دینے کے لیے Router استعمال کرتا ہے۔ کچھ نفاذات میں Router Coordinator منطق شامل کرتا ہے (Router-per-screen)، لیکن یہ اصل پیٹرن سے انحراف ہے۔

Coordinator میں retain cycle سے کیسے بچیں؟

دو اہم لیک ذرائع: childCoordinators (والدین ذیلی کو رکھتا ہے، ہٹانا بھول جاتا ہے) اور Router (UINavigationController ViewController کو رکھتا ہے)۔ حل: finish() پر ذیلی Coordinator کو ہمیشہ صف سے ہٹائیں۔ delegate کے لیے weak حوالہ استعمال کریں۔ Router کے لیے — UINavigationController پر مضبوط حوالہ نہ رکھیں اگر یہ پہلے سے window کے درجہ بندی میں ہے۔ Coordinator کے deinit کو جانچیں۔

Coordinator کب ضرورت سے زیادہ ہے؟

3-5 اسکرینوں والی ایپلیکیشنز کے لیے Coordinator ضرورت سے زیادہ ہے — segue یا سادہ navigationController.pushViewController آسان ہے۔ NavigationStack کے ساتھ SwiftUI ایپلیکیشنز کے لیے بھی ضرورت سے زیادہ ہے۔ Coordinator 15+ اسکرینوں، پیچیدہ بہاؤ (شاخوں کے ساتھ onboarding، پاس ورڈ کی بازیابی کے ساتھ تصدیق) اور مخلوط UIKit/SwiftUI منصوبوں کے لیے جائز ہے۔

Coordinator کو کیسے جانچیں؟

Mock Router — چیک کریں کہ کون سے طریقے اور کن پیرامیٹرز کے ساتھ بلائے گئے۔ childCoordinators چیک کریں: start() کے بعد صف خالی نہیں ہے، finish() کے بعد — خالی۔ Coordinator UI کے بغیر جانچا جاتا ہے: Router ایک پروٹوکول ہے، اس کے mock کو UIKit کی ضرورت نہیں ہے۔ async بہاؤ کے لیے XCTestExpectation استعمال کریں۔ Android میں — mock نیویگیشن کے ساتھ NavigationController اور NavHost کی اسی طرح جانچ۔

خلاصہ

  • Coordinator — نیویگیشن پیٹرن جو ViewController سے منتقلی کو علیحدہ کلاس میں نکالتا ہے
  • Router — Coordinator کے ذریعے استعمال کردہ UINavigationController کا تجرید
  • درجہ بندی — نتائج کی تفویض کے ساتھ والدین اور ذیلی Coordinator
  • MVVM-C — Coordinator کے ساتھ UIKit منصوبوں کے لیے معیاری نقطہ نظر
  • SwiftUI — NavigationStack کے ذریعے بلٹ ان نیویگیشن Coordinator کی جگہ لیتی ہے
  • جانچ — Coordinator کو UIKit کے بغیر mock Router کے ذریعے جانچا جاتا ہے

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں