VIPER: کلیدی تصورات، View-Interactor-Presenter-Entity-Router پیٹرن

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

VIPER (View-Interactor-Presenter-Entity-Router) — Mutual Mobile کمپنی نے iOS ایپلیکیشنز کے لیے تیار کیا گیا ایک ماڈیولر آرکیٹیکچر ہے۔ VIPER ایپلیکیشن کو پانچ تہوں میں تقسیم کرتا ہے: View ڈسپلے کے لیے، Interactor کاروباری منطق کے لیے، Presenter ڈیٹا کی تیاری کے لیے، Entity ڈیٹا ماڈلز کے لیے، Router ماڈیولز کے درمیان نیویگیشن کے لیے ذمہ دار ہے۔ VIPER موبائل آرکیٹیکچرز میں واحد ذمہ داری کے اصول کا سب سے تفصیلی نفاذ ہے۔ مزید معلومات کے لیے objc.io پر مضمون دیکھیں۔

اہم نکات

  • VIPER — پانچ اجزاء: View، Interactor، Presenter، Entity، Router واضح ذمہ داری کی حدوں کے ساتھ
  • ماڈیولریٹی — ہر اسکرین (ماڈیول) الگ تھلگ ہے، پروٹوکول کے ذریعے مواصلات
  • Router — نیویگیشن کو Presenter سے باہر نکالتا ہے، iOS نیویگیشن مسئلہ حل کرتا ہے
  • Interactor — کاروباری منطق رکھتا ہے اور UIKit پر منحصر نہیں، یونٹ ٹیسٹ سے قابل آزمائش
  • iOS-native — VIPER SwiftUI سے پہلے UIKit کے لیے بنایا گیا تھا اور بڑے iOS منصوبوں کے لیے معیار بنا ہوا ہے

VIPER کیا ہے: ماڈیولر آرکیٹیکچر کے پانچ اجزاء

VIPER (View-Interactor-Presenter-Entity-Router) — 2013–2014 میں Mutual Mobile میں بڑے iOS منصوبوں کے لیے تیار کیا گیا ایک آرکیٹیکچرل پیٹرن ہے۔ ایپلیکیشن کی ہر اسکرین سختی سے متعین ذمہ داریوں کے ساتھ پانچ اجزاء کا ایک علیحدہ ماڈیول ہے۔ VIPER موبائل ڈیولپمنٹ میں واحد ذمہ داری کے اصول (Single Responsibility Principle) کا سب سے سخت نفاذ ہے: کوئی بھی جزو وہ نہیں کرتا جو دوسرا کر سکتا ہے۔

View ایک غیر فعال جزو ہے جو صرف Presenter کے بھیجے گئے ڈیٹا کو ڈسپلے کرنے کا ذمہ دار ہے۔ View میں کوئی کاروباری منطق نہیں، نیویگیشن نہیں سنبھالتا، نیٹ ورک کی درخواستیں نہیں کرتا۔ iOS میں — ViewProtocol کے ساتھ UIViewController۔ Interactor کاروباری منطق کی تہہ ہے جو Entity اور خدمات (نیٹ ورک، DB، GPS) کے ساتھ کام کرتی ہے۔ Interactor UIKit کو امپورٹ نہیں کرتا۔ Presenter View اور Interactor کے درمیان ثالث ہے: Interactor سے ڈیٹا وصول کرتا ہے، ڈسپلے کے لیے فارمیٹ کرتا ہے، View کو بھیجتا ہے۔ Presenter بھی UIKit کو امپورٹ نہیں کرتا۔ Entity — ڈیٹا ماڈل (struct, class)۔ Router — نیویگیشن کا انتظام کرتا ہے: ماڈیول بناتا ہے، اسکرینیں کھولتا ہے، ماڈیولز کے درمیان ڈیٹا بھیجتا ہے۔

جزوذمہ داریانحصار
Viewڈسپلے، اینیمیشن، جیسچرUIKit (صرف View)
Interactorکاروباری منطق، نیٹ ورک، DBEntity، خدمات
Presenterڈیٹا فارمیٹنگ، View کمانڈزViewProtocol، Interactor
Entityڈیٹا ماڈلکوئی نہیں
Routerنیویگیشن، ماڈیول تخلیقUIViewController (منتقلی کے لیے)

اجزاء کے درمیان تعلقات پروٹوکول کے ذریعے بیان کیے گئے ہیں۔ ViewProtocol ڈسپلے کے طریقوں کی وضاحت کرتا ہے، InteractorProtocol کاروباری منطق کے طریقوں کی، PresenterProtocol واقعہ ہینڈلنگ کے طریقوں کی، RouterProtocol نیویگیشن کے طریقوں کی وضاحت کرتا ہے۔ ہر جزو دوسرے کے ساتھ صرف پروٹوکول کے ذریعے بات چیت کرتا ہے، جس سے نفاذ کو آسانی سے تبدیل کرنا اور الگ تھلگ جانچ ممکن ہوتی ہے۔ اوسطاً، ایک اسکرین کے لیے VIPER ماڈیول میں 5 پروٹوکول + 5 کلاسز + 1 Builder/Assembler = 11 فائلیں فی اسکرین ہوتی ہیں۔

Swift میں VIPER: ماڈیول، Router اور Presenter

VIPER ماڈیول کی تعمیر Builder (یا Assembler) میں کی جاتی ہے، جو پانچوں اجزاء بناتا ہے اور انہیں پروٹوکول کے ذریعے جوڑتا ہے۔ Builder واحد جگہ ہے جہاں اجزاء ایک دوسرے کی ٹھوس اقسام کو جانتے ہیں۔ اسمبلی کے بعد، View ڈسپلے کے لیے باہر واپس کر دیا جاتا ہے، باقی چین صاف ہے اور الگ تھلگ جانچا جاتا ہے۔

swift
// پروٹوکول — View
protocol UserViewProtocol: AnyObject {
    func display(name: String)
    func display(email: String)
    func showLoading()
    func hideLoading()
}

// پروٹوکول — Interactor
protocol UserInteractorProtocol {
    func fetchUser(id: Int, completion: @escaping (Result<User, Error>) -> Void)
}

// پروٹوکول — Router
protocol UserRouterProtocol {
    func navigateToProfile(userId: Int)
}

// Interactor — کاروباری منطق
final class UserInteractor: UserInteractorProtocol {
    private let service: UserService

    init(service: UserService) { self.service = service }

    func fetchUser(id: Int, completion: @escaping (Result<User, Error>) -> Void) {
        service.fetchUser(id: id, completion: completion)
    }
}

// Presenter — ڈیٹا کی تیاری
final class UserPresenter {
    private weak var view: UserViewProtocol?
    private let interactor: UserInteractorProtocol
    private let router: UserRouterProtocol

    init(interactor: UserInteractorProtocol, router: UserRouterProtocol) {
        self.interactor = interactor
        self.router = router
    }

    func setView(_ view: UserViewProtocol) {
        self.view = view
    }

    func viewDidLoad() {
        view?.showLoading()
        interactor.fetchUser(id: 42) { [weak self] result in
            guard let self else { return }
            self.view?.hideLoading()
            switch result {
            case .success(let user):
                self.view?.display(name: user.name)
                self.view?.display(email: user.email)
            case .failure(let error):
                // غلطی کا انتظام
            }
        }
    }
}

// Router — نیویگیشن
final class UserRouter: UserRouterProtocol {
    private weak var viewController: UIViewController?

    func setViewController(_ vc: UIViewController) {
        viewController = vc
    }

    func navigateToProfile(userId: Int) {
        let profileModule = ProfileModuleBuilder.build(userId: userId)
        viewController?.navigationController?.pushViewController(profileModule, animated: true)
    }
}

// Builder — ماڈیول اسمبلی
enum UserModuleBuilder {
    static func build(userId: Int) -> UIViewController {
        let service = UserService()
        let interactor = UserInteractor(service: service)
        let router = UserRouter()
        let presenter = UserPresenter(interactor: interactor, router: router)
        let viewController = UserViewController(presenter: presenter)
        presenter.setView(viewController)
        router.setViewController(viewController)
        return viewController
    }
}

Builder/Assembler VIPER کا ایک اہم عنصر ہے، جو دستی طور پر انحصار انجیکشن (Dependency Injection) کو نافذ کرتا ہے۔ کنسٹرکٹر کے ذریعے انحصار انجیکشن (constructor injection) اس بات کی ضمانت دیتا ہے کہ کوئی جزو اپنے انحصار کے بغیر نہیں بنایا جا سکتا۔ جدید VIPER میں، Builder Swinject (DI کنٹینر) استعمال کر سکتا ہے، لیکن دستی اسمبلی جانچ کے لیے زیادہ شفاف رہتی ہے۔ IT Sectr میں، ہم پیچیدہ منطق والے ماڈیولز کے لیے دستی اسمبلی کے ساتھ VIPER استعمال کرتے ہیں — یہ نئے ڈویلپرز کے لیے کوڈ پڑھنے کو آسان بناتا ہے۔

Mapper (Formatter) VIPER کا ایک اختیاری چھٹا جزو ہے۔ Mapper Entity (DB/سرور ماڈل) کو ViewModel (ڈسپلے ماڈل) میں تبدیل کرتا ہے۔ Entity میں id، first_name، last_name، email فیلڈز کے ساتھ UserDTO ہوتا ہے۔ ViewModel — name (first_name + last_name) اور email کے ساتھ UserDisplayItem۔ Mapper Presenter میں عمل میں لایا جاتا ہے۔ اگر ڈیٹا میپنگ پیچیدہ ہے (متعدد Entity → ایک ViewModel)، تو Mapper کو جانچ کے لیے علیحدہ کلاس میں نکالا جاتا ہے۔

VIPER ماڈیولز کے درمیان مواصلات

VIPER ماڈیولز الگ تھلگ ہیں اور ایک دوسرے کے بارے میں نہیں جانتے۔ ماڈیولز کے درمیان مواصلات Router کے ذریعے ہوتا ہے۔ جب صارف یوزر اسکرین پر "پروفائل" بٹن پر کلک کرتا ہے، Presenter router.navigateToProfile(userId: 42) کو کال کرتا ہے۔ Router ProfileModuleBuilder.build(userId: 42) کے ذریعے نیا ماڈیول بناتا ہے اور navigationController.push کے ذریعے کھولتا ہے۔ ڈیٹا کا بہاؤ: ماڈیول A → Router A → ماڈیول B Builder → ماڈیول B بنایا اور کھولا جاتا ہے۔

ڈیٹا واپس بھیجنا (مثال کے طور پر، انتخاب کی اسکرین پر شہر منتخب کرنا → پروفائل ایڈیٹنگ اسکرین پر واپس آنا) VIPER میں ڈیلیگیٹ یا کلوزر کے ذریعے نافذ کیا جاتا ہے۔ ماڈیول B didSelectCity(_ city: City) طریقہ کے ساتھ ModuleBDelegate پروٹوکول کی وضاحت کرتا ہے۔ ماڈیول A اس پروٹوکول کو نافذ کرتا ہے۔ Router A ڈیلیگیٹ کو ماڈیول B Builder کو بھیجتا ہے۔ جب شہر منتخب ہوتا ہے، ماڈیول B delegate?.didSelectCity(city) کو کال کرتا ہے۔ یہ معیاری iOS عمل ہے، جو کسی بھی UIKit ڈویلپر سے واقف ہے۔

منظرمیکانزممثال
آگے کی نیویگیشنRouter → BuildernavigateToProfile(userId:)
ڈیٹا واپس بھیجناDelegatedidSelectCity(_:)
سسٹم نوٹیفکیشنNotificationCenterUserDidLogout
Interactor سے واقعہPresenter → ViewWebSocket پیغام

NotificationCenter سسٹم کے واقعات (لاگ آؤٹ، پلان تبدیلی، پش نوٹیفکیشن) کے لیے استعمال ہوتا ہے جو ایک ساتھ متعدد ماڈیولز کو متاثر کرتے ہیں۔ Router یا AppDelegate Notification کو سبسکرائب کرتا ہے، مطلوبہ ماڈیول بناتا ہے یا حالت کو اپ ڈیٹ کرتا ہے۔ VIPER NotificationCenter کو منع نہیں کرتا — اہم بات یہ ہے کہ یہ صرف 1-to-many واقعات کے لیے استعمال ہو، جبکہ 1-to-1 مواصلات کے لیے ڈیلیگیٹ یا کلوزر استعمال کیے جائیں۔

VIPER کا MVVM اور Clean Architecture سے موازنہ

VIPER بمقابلہ MVVM — VIPER کو فی اسکرین 2–3 گنا زیادہ کوڈ درکار ہوتا ہے لیکن یہ مکمل جزو کی علیحدگی فراہم کرتا ہے۔ MVVM ViewModel + SwiftUI کے ساتھ آسان اور تیز ہے لیکن 5+ ڈویلپرز کی ٹیموں کے لیے کم قابل توسیع ہے۔ VIPER سختی سے متعین کرتا ہے کہ کون کس چیز کا ذمہ دار ہے: Interactor — صرف کاروباری منطق، Presenter — فارمیٹنگ، Router — نیویگیشن۔ MVVM میں، ViewModel اکثر بڑھتا ہے، نیویگیشن اور کاروباری منطق اپنے ہاتھ میں لے لیتا ہے۔

VIPER بمقابلہ Clean Architecture — VIPER iOS UIKit کے لیے ڈھالا گیا Clean Architecture کا ایک مخصوص معاملہ ہے۔ Interactor = Use Case، Entity = Domain Model، Presenter = Presentation، Router = Controller رابرٹ مارٹن کی اصطلاحات میں۔ Clean Architecture Interactor اور ڈیٹا کے درمیان Gateway/Repository تہہ شامل کرتا ہے، جو VIPER میں عام طور پر الگ نہیں کی جاتی۔ جدید SwiftUI منصوبوں کے لیے، زیادہ تر ٹیمیں Clean Architecture (The Composable Architecture) یا MVVM کا انتخاب کرتی ہیں، VIPER کو UIKit میراث کے لیے چھوڑ دیتی ہیں۔

VIPER کب منتخب کریں — 5+ ڈویلپرز کی ٹیمیں، 50+ اسکرینوں والے UIKit منصوبے، 80% سے زیادہ جانچ کی ضروریات، صرف iOS (VIPER بغیر دوبارہ لکھے Android پر منتقل نہیں کیا جا سکتا)۔ VIPER ایک پیش قیاسی ساخت فراہم کرتا ہے: ایک نیا ڈویلپر 15 منٹ میں ماڈیول سمجھ لیتا ہے۔ تاہم، زیادہ فائلوں کی وجہ سے ترقی کی رفتار MVVM کے مقابلے میں 20–30% کم ہے۔ IT Sectr میں، ہم 3+ افراد کی ٹیموں کے ساتھ انٹرپرائز UIKit منصوبوں کے لیے VIPER استعمال کرتے ہیں اور نئے SwiftUI منصوبوں کے لیے Clean Architecture کو ترجیح دیتے ہیں۔

VIPER ماڈیولز کی جانچ

VIPER جانچ کے لیے ڈیزائن کیا گیا ہے — ہر جزو پروٹوکول کے ذریعے الگ تھلگ جانچا جاتا ہے۔ Interactor کو فرضی خدمات سے جانچا جاتا ہے: یہ تصدیق کی جاتی ہے کہ fetchUser صحیح ID کے ساتھ کال ہوا اور نتیجہ Presenter کو بھیجا گیا۔ Presenter کو فرضی View اور Interactor اشیاء سے جانچا جاتا ہے۔ Router کو فرضی نیویگیشن سے جانچا جاتا ہے: یہ تصدیق کی جاتی ہے کہ navigateToProfile صحیح userId کے ساتھ کال ہوا اور صحیح ماڈیول بنایا گیا۔ View کو UI ٹیسٹ (XCUITest) سے جانچا جاتا ہے۔

swift
import XCTest

final class UserPresenterTests: XCTestCase {
    func testViewDidLoad_callsFetchUserAndUpdatesView() {
        // Given
        let view = MockUserView()
        let interactor = MockUserInteractor()
        let router = MockUserRouter()
        let presenter = UserPresenter(interactor: interactor, router: router)
        presenter.setView(view)
        let expectedUser = User(id: 42, name: "John", email: "john@test.com")
        interactor.result = .success(expectedUser)

        // When
        presenter.viewDidLoad()

        // Then
        XCTAssertEqual(interactor.capturedUserId, 42)
        XCTAssertEqual(view.displayedName, "John")
        XCTAssertTrue(view.didShowLoading)
    }
}

فرضی اشیاء VIPER کے لیے دستی طور پر بنائی جاتی ہیں (ذخیرہ شدہ کیپچر خصوصیات والی کلاس) یا Cuckoo / Mockingbird جیسی لائبریریوں کے ذریعے۔ دستی فرضی کلاسیں آسان اور واضح ہوتی ہیں، خاص طور پر نئے ڈویلپرز کی تربیت کے لیے۔ ہر فرضی شے کیپچر کردہ اقدار (capturedUserId، displayedName) اور کال فلیگ (didShowLoading) کو ذخیرہ کرتی ہے۔ ٹیسٹ کے اختتام پر، نہ صرف یہ چیک کیا جاتا ہے کہ طریقہ کال ہوا، بلکہ یہ بھی کہ کن پیرامیٹرز کے ساتھ — یہ ڈیٹا کے بہاؤ کی درستگی میں اعتماد دیتا ہے۔

کوڈ کوریج IT Sectr VIPER منصوبوں میں Interactor کے لیے 85–95%، Presenter کے لیے 90–95%، Router کے لیے 70–80%، View کے لیے 30–50% (UI ٹیسٹ کے ذریعے) تک پہنچتی ہے۔ View کو اسنیپ شاٹ ٹیسٹ (SnapshotTesting، 1.5K ستارے) سے جانچا جاتا ہے — یہ XCUITest سے تیز ہے اور زیادہ کیسز کا احاطہ کرتا ہے۔ VIPER منصوبے کی کل کوریج عام طور پر 70–80% ہوتی ہے، جو MVVM منصوبے (50–65%) سے زیادہ ہے، لیکن ٹیسٹ لکھنے میں زیادہ وقت لگتا ہے (ترقی کے وقت کا 30–40% بمقابلہ MVVM میں 20–25%)۔

اکثر پوچھے گئے سوالات

ایک VIPER ماڈیول میں کتنی فائلیں ہیں؟

کم از کم 11 فائلیں: 5 پروٹوکول (ViewProtocol، InteractorProtocol، PresenterProtocol، RouterProtocol، Entity)، 5 نفاذ (ViewController، Interactor، Presenter، Router، Entity) اور Builder/Assembler۔ Mapper (Formatter) کے ساتھ — 12–13۔ 50 اسکرینوں کے منصوبے کے لیے، صرف VIPER ماڈیولز کی 550–650 فائلیں ہوتی ہیں۔ MVVM کو فی اسکرین 3 فائلوں کی ضرورت ہوتی ہے (ViewModel، View، Model) — 50 اسکرینوں کے لیے 150 فائلیں۔

کیا VIPER Android پر استعمال کیا جا سکتا ہے؟

ہاں، نظریاتی طور پر VIPER Android پر منتقل کیا جا سکتا ہے، لیکن عملی طور پر استعمال نہیں ہوتا — Google Jetpack کے ساتھ MVVM کی سفارش کرتا ہے۔ VIPER iOS UIKit کے لیے بنایا گیا تھا، جہاں ViewController اپنی زندگی کے دور کی وجہ سے جانچنا مشکل ہے۔ Android پر، Jetpack ViewModel VIPER علیحدگی کے بغیر جانچ کا مسئلہ حل کرتا ہے۔ Android پر VIPER کا مساوی Clean Architecture ہے جس میں ماڈیول/فیچر کی تقسیم ہے۔

VIPER اور Clean Architecture میں کیا فرق ہے؟

VIPER Clean Architecture کا iOS-specific نفاذ ہے۔ Interactor Use Case سے مطابقت رکھتا ہے، Entity — Domain Model، Presenter — Presentation تہہ۔ Clean Architecture Interactor اور ڈیٹا کے درمیان Repository/Gateway شامل کرتا ہے، جو VIPER میں عام طور پر Interactor کے اندر نافذ کیا جاتا ہے۔ Clean Architecture Router کو مقرر نہیں کرتا — نیویگیشن نفاذ پر چھوڑ دی جاتی ہے۔

کیا SwiftUI منصوبوں کے لیے VIPER ضروری ہے؟

نہیں — SwiftUI MVVM + Combine کے لیے ڈیزائن کیا گیا ہے۔ SwiftUI میں VIPER بے کار ہے: اعلانیہ UI کے ساتھ فی اسکرین پانچ اجزاء فائدہ کے بغیر بوجھ ہے۔ SwiftUI کے لیے، MVVM یا TCA (The Composable Architecture) منتخب کریں۔ VIPER UIKit میراث اور ان منصوبوں کے لیے متعلقہ رہتا ہے جہاں iOS 12 اور اس سے نیچے کم از کم ورژن ہے۔

VIPER ماڈیولز کے درمیان ڈیٹا کیسے بھیجیں؟

Router کے ذریعے۔ ماڈیول A router.navigateToProfile(userId: id) کال کرتا ہے۔ Router A Builder کے ذریعے ماڈیول B بناتا ہے، userId بھیجتا ہے۔ واپسی مواصلات — ڈیلیگیٹ کے ذریعے: ماڈیول B ModuleBDelegate پروٹوکول کی وضاحت کرتا ہے، ماڈیول A اسے نافذ کرتا ہے اور Router کے ذریعے بھیجتا ہے۔ سسٹم کے واقعات (لاگ آؤٹ) — NotificationCenter کے ذریعے۔

خلاصہ

  • VIPER — سخت علیحدگی کے ساتھ پانچ اجزاء: View، Interactor، Presenter، Entity، Router
  • ماڈیولریٹی — ہر اسکرین الگ تھلگ ہے، Builder کنسٹرکٹر انجیکشن کے ذریعے انحصار کو جوڑتا ہے
  • Router — نیویگیشن کو Presenter سے باہر نکالتا ہے، iOS پر نیویگیشن کا مسئلہ حل کرتا ہے
  • Interactor — UIKit کے بغیر صاف کاروباری منطق، یونٹ ٹیسٹ سے قابل آزمائش
  • کوڈ کا حجم — فی اسکرین 11+ فائلیں، ترقی MVVM سے 20–30% سست
  • جانچ — 70–80% کوریج، Interactor اور Presenter فرضی اشیاء کے ذریعے جانچے جاتے ہیں
  • SwiftUI بمقابلہ UIKit — UIKit (میراث) کے لیے VIPER، SwiftUI کے لیے MVVM/TCA

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

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

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

مزید پڑھیں