ডিফার্ড নেভিগেশন (Deferred Navigation) হল বিলম্বিত নেভিগেশনের একটি প্যাটার্ন যেখানে পরবর্তী স্ক্রিনে স্থানান্তর একটি অ্যাসিনক্রোনাস অপারেশন সম্পূর্ণ হওয়ার পরে ঘটে, ব্যবহারকারীর কর্মের মুহূর্তে সরাসরি না। Android Developers (2024) অনুসারে, ডিফার্ড নেভিগেশন নেভিগেশন এবং ডেটা লোডিংয়ের মধ্যে রেস কন্ডিশন এড়াতে সাহায্য করে এবং পুশ নোটিফিকেশন ও ডিপলিংক থেকে স্থানান্তর প্রক্রিয়াকরণ সহজ করে। মূল পার্থক্য — সমস্ত প্রয়োজনীয় ডেটা উপলব্ধ হওয়ার পরে রুট গণনা করা হয়।
মুখ্য বিষয়
ডিফার্ড নেভিগেশন (Deferred Navigation) হল একটি আর্কিটেকচারাল প্যাটার্ন যেখানে নেভিগেশন সিদ্ধান্ত স্থগিত করা হয় যতক্ষণ না সমস্ত প্রয়োজনীয় ডেটা উপলব্ধ হয়। সরাসরি স্থানান্তরের বিপরীতে যেখানে ব্যবহারকারী একটি বোতাম চাপে এবং সাথে সাথে একটি নতুন স্ক্রিনে পৌঁছে যায়, ডিফার্ড নেভিগেশন ট্রিগার ইভেন্ট এবং প্রকৃত স্থানান্তরকে পৃথক করে, তাদের মধ্যে একটি অ্যাসিনক্রোনাস অপারেশন রেখে।
আর্কিটেকচারালভাবে, ডিফার্ড নেভিগেশন অবস্থা পরিবর্তনের উপর নির্মিত: বোতাম চাপা একটি অ্যাসিনক্রোনাস প্রক্রিয়া শুরু করে, এবং এর ফলাফলের সাবস্ক্রিপশন নেভিগেশন ট্রিগার করে। এটি MVVM বা MVI আর্কিটেকচারযুক্ত অ্যাপ্লিকেশনগুলিতে বিশেষভাবে গুরুত্বপূর্ণ, যেখানে ViewModel অবস্থা পরিচালনা করে এবং View (Activity, Fragment, SwiftUI View) পরিবর্তনগুলিতে সাবস্ক্রাইব করে এবং স্থানান্তরের মাধ্যমে প্রতিক্রিয়া জানায়। এই পদ্ধতি UI এবং নেভিগেশন লজিকের মধ্যে সরাসরি নির্ভরতা দূর করে।
Google I/O 2023 অনুসারে, ডিফার্ড নেভিগেশন সমস্ত পরিস্থিতির জন্য সুপারিশ করা হয় যেখানে নেভিগেশন নেটওয়ার্ক অনুরোধ, প্রমাণীকরণ পরীক্ষা, কনফিগারেশন লোডিং বা অনুমতির ফলাফলের উপর নির্ভর করে। ডিপলিংক প্রক্রিয়াকরণের সময়ও প্যাটার্নটি বাধ্যতামূলক, যেখানে অ্যাপ্লিকেশনটি প্রথমে চালু হতে হবে, রুট স্ক্রিন লোড করতে হবে এবং তারপরেই লক্ষ্য রুটে নেভিগেট করতে হবে।
ডিফার্ড নেভিগেশন সেই পরিস্থিতিতে ব্যবহার করা হয় যেখানে সরাসরি নেভিগেশন ভুল স্ক্রিন অবস্থা বা লোডিং ত্রুটির দিকে নিয়ে যায়। আসুন চারটি প্রধান ক্ষেত্রে পরীক্ষা করি যেখানে ডিফার্ড নেভিগেশন প্রয়োজনীয়।
যদি ব্যবহারকারী সুরক্ষিত সামগ্রীতে ট্যাপ করে, অ্যাপ্লিকেশনটিকে প্রথমে অ্যাক্সেস টোকেন পরীক্ষা করতে হবে। সরাসরি নেভিগেশন সামগ্রী স্ক্রিনে একটি খালি স্ক্রিন বা 401 ত্রুটির দিকে নিয়ে যাবে যদি টোকেন মেয়াদোত্তীর্ণ হয়। ডিফার্ড নেভিগেশন টোকেন পরীক্ষা করে, এবং শুধুমাত্র সাফল্যের উপর — লক্ষ্য স্ক্রিনে নেভিগেট করে। ব্যর্থতার উপর — লগইন স্ক্রিনে পুনঃনির্দেশ করে।
যখন একটি অ্যাপ্লিকেশন বাহ্যিক লিঙ্কের মাধ্যমে খোলা হয়, প্রথমে রুট স্ক্রিন লোড করতে হবে, নেভিগেশন অবস্থা পুনরুদ্ধার করতে হবে এবং তারপরেই ডিপলিংক স্থানান্তর করতে হবে। রুট প্রসঙ্গ ছাড়া লক্ষ্য স্ক্রিনে সরাসরি নেভিগেশন অস্বাভাবিকতার দিকে নিয়ে যাবে: খালি নেভিগেশন স্ট্যাক বা ভাঙা ব্যাক স্ট্যাক।
পুশ নোটিফিকেশনে ট্যাপ করার সময়, অ্যাপ্লিকেশনটি তিনটি অবস্থার একটিতে থাকতে পারে: বন্ধ, ব্যাকগ্রাউন্ডে বা সক্রিয়। ডিফার্ড নেভিগেশন অ্যাপ্লিকেশনের অবস্থা নির্ধারণ করে, প্রয়োজনীয় সামগ্রী লোড করে এবং তারপরেই লক্ষ্য স্ক্রিন দেখায়। iOS UNNotificationContentExtension-এর মাধ্যমে এই পরিস্থিতি প্রক্রিয়াকরণের অনুমতি দেয়।
যদি স্ক্রিনের কার্যকারিতা সার্ভার থেকে ফিচার ফ্ল্যাগ দ্বারা নিয়ন্ত্রিত হয়, ডিফার্ড নেভিগেশন প্রথমে কনফিগারেশন অনুরোধ করতে এবং তারপরেই স্ক্রিন দেখানোর অনুমতি দেয়। যদি বৈশিষ্ট্যটি নিষ্ক্রিয় থাকে — ব্যবহারকারী খালি স্ক্রিনের পরিবর্তে বিকল্প সামগ্রী বা প্লেসহোল্ডার দেখেন।
| পরিস্থিতি | সরাসরি নেভিগেশন | ডিফার্ড নেভিগেশন |
|---|---|---|
| অনুমোদন | মেয়াদোত্তীর্ণ টোকেন সহ খালি স্ক্রিন | লগইনে পুনঃনির্দেশ |
| ডিপলিংক | ভাঙা ব্যাক স্ট্যাক | সঠিক নেভিগেশন স্ট্যাক |
| পুশ | প্রসঙ্গ ছাড়া লোডিং | স্থানান্তরের আগে ডেটা প্রস্তুত |
| ফিচার ফ্ল্যাগ | অনুপলব্ধ কার্যকারিতা দেখানো | প্লেসহোল্ডার বা বিকল্প |
সরাসরি নেভিগেশন একটি ঐতিহ্যগত পদ্ধতি যেখানে একটি ইভেন্টের প্রতিক্রিয়ায় তাৎক্ষণিকভাবে স্থানান্তর করা হয়। ব্যবহারকারী একটি বোতাম চাপে, এবং UI রাউটার সাথে সাথে স্ক্রিন পরিবর্তন করে। এই পদ্ধতি সহজ এবং অনুমানযোগ্য কিন্তু সেই পরিস্থিতিতে সীমিত যেখানে সার্ভার থেকে ডেটা বা শর্ত পরীক্ষার প্রয়োজন হয়।
ডিফার্ড নেভিগেশন অ্যাসিনক্রোনাস অবস্থার আকারে একটি স্তর যোগ করে। ব্যবহারকারীর ইভেন্ট একটি অপারেশন শুরু করে, এবং ফলাফলের সাবস্ক্রিপশন নেভিগেশন নিয়ন্ত্রণ করে। এটি কোড জটিলতা বাড়ায় কিন্তু নমনীয়তা প্রদান করে: একই ট্রিগার লোড করা ডেটার উপর নির্ভর করে বিভিন্ন স্ক্রিনে নিয়ে যেতে পারে।
দুটি পদ্ধতির মধ্যে পছন্দ প্রয়োজনীয়তার উপর নির্ভর করে: যদি একটি স্ক্রিন প্রদর্শনের জন্য অ্যাসিনক্রোনাস ডেটার প্রয়োজন না হয় — সরাসরি নেভিগেশন ব্যবহার করুন। যদি স্ক্রিন একটি অনুরোধ, অনুমোদন বা বাহ্যিক অবস্থার ফলাফলের উপর নির্ভর করে — ডিফার্ড নেভিগেশন প্রয়োজনীয়। একটি হাইব্রিড পদ্ধতি, যেখানে কিছু স্থানান্তর সরাসরি এবং কিছু বিলম্বিত, শিল্প অ্যাপ্লিকেশনগুলিতে সবচেয়ে সাধারণ অভ্যাস।
Android Jetpack আর্কিটেকচার স্তরে ডিফার্ড নেভিগেশন বাস্তবায়নের জন্য প্রক্রিয়া প্রদান করে। মূল ধারণা — ViewModel অবস্থা পরিচালনা করে, যখন Activity বা Fragment পরিবর্তনগুলিতে সাবস্ক্রাইব করে এবং NavController-এর মাধ্যমে নেভিগেশন ট্রিগার করে।
StateFlow Kotlin করুটিনে ডিফার্ড নেভিগেশনের জন্য আদর্শ টুল। ViewModel একটি নেভিগেশন ইভেন্ট সহ StateFlow আপডেট করে, এবং Activity এটি পর্যবেক্ষণ করে এবং স্থানান্তর সম্পাদন করে। ইভেন্ট প্রক্রিয়া করা হলে, StateFlow পরিষ্কার হয়ে যায়, পুনরাবৃত্ত নেভিগেশন প্রতিরোধ করে।
class MainViewModel : ViewModel() {
private val _navigation = MutableSharedFlow<NavigationEvent>()
val navigation: SharedFlow<NavigationEvent> = _navigation
fun onDeepLinkReceived(link: String) {
viewModelScope.launch {
val data = resolveDeepLink(link)
_navigation.emit(NavigationEvent.GoToScreen(data))
}
}
}
Activity-তে, নেভিগেশনের সাবস্ক্রিপশন ViewModel থেকে রুট সহ NavController ট্রিগার করে। স্ক্রিন রোটেশনে পুনরাবৃত্ত নেভিগেশন প্রতিরোধ করতে, NavigationEventWrapper র্যাপার ব্যবহার করা হয় যা ইভেন্টটি শুধুমাত্র একবার প্রক্রিয়া করে। Jetpack Navigation 2.7+ টাইপ-নিরাপদ আর্গুমেন্ট পাসিংয়ের জন্য Safe Args সমর্থন করে।
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val vm: MainViewModel by viewModels()
repeatOnLifecycle(Lifecycle.State.STARTED) {
vm.navigation.collect { event ->
when (event) {
is NavigationEvent.GoToScreen ->
findNavController(R.id.nav_host)
.navigate(event.route)
}
}
}
}
}
iOS-এ Android Jetpack-এর মতো কোনো অন্তর্নির্মিত Navigation Component নেই, তাই ডেভেলপাররা Combine বা async/await-এর সাথে Coordinator Pattern-এর মাধ্যমে ডিফার্ড নেভিগেশন বাস্তবায়ন করে। Coordinator স্ক্রিন স্ট্যাক পরিচালনা করে এবং লোড করা ডেটার উপর ভিত্তি করে নেভিগেশন সিদ্ধান্ত নেয়।
Coordinator একটি অবজেক্ট যা ViewControllers-এর মধ্যে নেভিগেশন পরিচালনা করে। Combine-এর সাথে, ViewModel PassthroughSubject-এর মাধ্যমে ইভেন্ট প্রকাশ করে, এবং Coordinator সেগুলিতে সাবস্ক্রাইব করে এবং স্থানান্তর সম্পাদন করে। এই পদ্ধতি সম্পূর্ণরূপে UI-কে নেভিগেশন লজিক থেকে পৃথক করে এবং অ্যাপ্লিকেশন আর্কিটেকচারের জন্য Apple-এর সুপারিশ অনুসরণ করে।
final class AppCoordinator {
private var cancellables = Set<AnyCancellable>()
func start(viewModel: MainViewModel) {
viewModel.$navigationDestination
.compactMap { $0 }
.sink { [weak self] destination in
self?.navigateTo(destination)
}
.store(in: &cancellables)
}
}
Swift 5.5 স্ট্রাকচার্ড কনকারেন্সি চালু করেছে, যা Combine ছাড়া async/await-এর মাধ্যমে ডিফার্ড নেভিগেশন বাস্তবায়নের অনুমতি দেয়। ViewModel একটি async ফাংশন প্রদান করে যা ডেটা লোড করার পরে একটি রুট ফেরত দেয়। Coordinator Task-এ এই ফাংশনটি কল করে এবং প্রাপ্ত রুটের উপর ভিত্তি করে স্থানান্তর সম্পাদন করে।
class AuthViewModel: ObservableObject {
func resolveDeeplink(_ url: URL) async -> AppRoute? {
guard let token = await AuthService.shared.getValidToken() else { return .login }
return await DeeplinkRouter.resolve(url, token: token)
}
}
// In Coordinator:
Task {
if let route = await viewModel.resolveDeeplink(url) {
navigateTo(route)
}
}
ডিফার্ড নেভিগেশন অ্যাসিনক্রোনাস পরিস্থিতি প্রক্রিয়াকরণ সহজ করে কিন্তু অবস্থা পরিচালনার জন্য শৃঙ্খলিত পদ্ধতির প্রয়োজন। আসুন প্রধান ভুলগুলি পরীক্ষা করি যা ডেভেলপাররা ডিফার্ড নেভিগেশন বাস্তবায়নের সময় করে।
সবচেয়ে সাধারণ ভুল — রুট স্ক্রিন সম্পূর্ণরূপে ইনিশিয়ালাইজ হওয়ার এবং NavController বা Coordinator স্থানান্তরের জন্য প্রস্তুত হওয়ার আগে ডিফার্ড নেভিগেশন করার চেষ্টা। অ্যান্ড্রয়েডে এটি IllegalStateException-এর দিকে নিয়ে যায়, iOS-এ — অনির্ধারিত UI অবস্থার দিকে। সমাধান — নেভিগেশন ট্রিগার করার আগে নিশ্চিত করুন যে উপাদানের লাইফসাইকেল STARTED বা RESUMED অবস্থায় আছে।
যদি StateFlow বা Subject প্রক্রিয়াকরণের পরে ইভেন্টটি পরিষ্কার না করে, পূর্ববর্তী স্ক্রিনে ফিরে আসার সময় ব্যবহারকারী স্বয়ংক্রিয়ভাবে একই স্ক্রিনে পুনঃনির্দেশিত হতে পারে। অ্যান্ড্রয়েডে replay=0 সহ SharedFlow ব্যবহার করুন বা iOS-এ প্রক্রিয়াকরণের পরে CurrentValueSubject nil সহ, যাতে নেভিগেশন ইভেন্ট শুধুমাত্র একবার চালু হয়।
অ্যাপ্লিকেশনে সমস্ত নেভিগেশনের জন্য একটি কেন্দ্রীয় উপাদান ব্যবহার করুন। যখন প্রতিটি Activity, Fragment বা ViewController-এর নিজস্ব নেভিগেশন কন্ট্রোলার থাকে, অ্যাপ্লিকেশনের বিভিন্ন অংশের মধ্যে ডিফার্ড নেভিগেশন বিশৃঙ্খল হয়ে যায়। একক Coordinator নেভিগেশন পরিস্থিতির ডিবাগিং এবং পরীক্ষা সহজ করে।
ডিফার্ড নেভিগেশন সরাসরি নেভিগেশনের তুলনায় পরীক্ষা করা কঠিন কারণ অ্যাসিনক্রোনাস অপারেশন একটি সময়ের কারণ প্রবর্তন করে। অ্যান্ড্রয়েডে TestDispatcher (kotlinx-coroutines-test) এবং iOS-এ XCTestExpectation ব্যবহার করুন ডেটা লোডিং অনুকরণ করতে এবং নিশ্চিত করতে যে নেভিগেশন প্রত্যাশিত রুট অনুসরণ করে। প্রতিটি পরিস্থিতির বিচ্ছিন্ন পরীক্ষার জন্য অনুমোদন এবং ডিপলিংক পরিষেবাগুলি মক করুন।
সচরাচর জিজ্ঞাসিত প্রশ্ন
ডিফার্ড নেভিগেশন একটি বিলম্বিত স্থানান্তর প্যাটার্ন যা যেকোনো অ্যাসিনক্রোনাস পরিস্থিতিতে প্রয়োগ করা যেতে পারে। ডিপ লিংক ডিফার্ড নেভিগেশনের জন্য একটি ট্রিগার, কিন্তু একমাত্র নয়। প্রমাণীকরণ এবং ফিচার ফ্ল্যাগও বিলম্বিত নেভিগেশন ব্যবহার করে।
হ্যাঁ, বেশিরভাগ অ্যাপ্লিকেশন হাইব্রিড পদ্ধতি ব্যবহার করে। একটি পণ্য তালিকা স্ক্রিন (অ্যাসিনক্রোনাস নির্ভরতা ছাড়া) সরাসরি নেভিগেশন ব্যবহার করতে পারে, যখন ডেটা লোডিং সহ একটি বিবরণ স্ক্রিন — ডিফার্ড। বিভাজন প্রতিটি নির্দিষ্ট স্ক্রিনের আর্কিটেকচার দ্বারা নির্ধারিত হয়।
ব্যবহার করুন অ্যান্ড্রয়েডে replay ছাড়া SharedFlow এবং iOS-এ বাফারিং ছাড়া combineLatest। নতুন ট্রিগারে পূর্ববর্তী সাবস্ক্রিপশন বাতিল করুন। এটি নিশ্চিত করে যে শুধুমাত্র সর্বশেষ নেভিগেশন ইভেন্ট প্রক্রিয়া করা হয়।
হ্যাঁ, Compose-এ ডিফার্ড নেভিগেশন ViewModel StateFlow-এর সাবস্ক্রিপশন এবং LaunchedEffect-এ NavController.navigate কলের মাধ্যমে বাস্তবায়িত হয়। Google বিলম্বিত পরিস্থিতির জন্য ইভেন্ট-চালিত মডেল সহ Navigation Compose ব্যবহার করার সুপারিশ করে।
বিলম্বিত করুন নেভিগেশন যতক্ষণ না অ্যাপ্লিকেশন আবার সক্রিয় হয়। অ্যান্ড্রয়েডে ইভেন্ট ফিল্টার করতে Lifecycle.State.STARTED ব্যবহার করুন। iOS-এ Combine বা async/await ব্লকে UIApplication.State পরীক্ষা করুন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন