Inactive — Active اور Background کے درمیان ایپلیکیشن لائف سائیکل میں ایک عبوری حالت، جس میں ایپ اسکرین پر نظر آتی ہے لیکن ٹچ ایونٹس وصول نہیں کرتی۔ ہم وضاحت کرتے ہیں کہ iOS اور Android پر Inactive کیسے پیدا ہوتا ہے، کون سے ڈیلیگیٹ طریقے اس کے ذمہ دار ہیں اور رکاوٹوں — کالز، اطلاعات اور سسٹم جیسچرز — کو صحیح طریقے سے کیسے پروسیس کریں۔
اہم نکات
Inactive موبائل ایپ لائف سائیکل میں ایک درمیانی حالت ہے جو Active اور Background کے درمیان منتقلی کے دوران پیدا ہوتی ہے۔ اس حالت میں، ایپ ابھی بھی پیش منظر میں ہے اور صارف کو نظر آتی ہے، لیکن ٹچ ایونٹس، کی پریس یا دیگر UI ایونٹس وصول نہیں کرتی۔ سسٹم ایپ کو ایونٹس کی ترسیل کو روکتا ہے، لیکن UI اسکرین پر رہتا ہے اور چھوٹا نہیں ہوتا۔
Inactive کی نوعیت عارضی ہے۔ یہ حالت بالکل اسی وقت تک رہتی ہے جتنی سسٹم رکاوٹ رہتی ہے: Control Center کو جلدی بند کرنے پر 0.1 سیکنڈ سے لے کر کال اسکرین کے ساتھ آنے والی کال کے دوران کئی سیکنڈ تک۔ رکاوٹ ختم ہونے کے بعد، ایپ یا تو Active میں واپس آتی ہے یا Background میں چلی جاتی ہے اگر صارف نے دوسری ایپ پر سوئچ کیا ہو۔ Inactive واحد حالت ہے جو دونوں سمتوں میں منتقل ہو سکتی ہے: واپس Active میں یا آگے Background میں۔
iOS پر، Inactive سسٹم کے ذریعے خود بخود منظم کیا جاتا ہے۔ ڈویلپر Inactive میں گزارے گئے وقت کو بڑھا یا گھٹا نہیں سکتا — یہ مکمل طور پر UIApplication کے زیر کنٹرول ہے۔ ڈویلپر صرف ایک چیز کر سکتا ہے — applicationWillResignActive کے ذریعے Inactive میں منتقلی اور applicationDidBecomeActive کے ذریعے واپسی کو صحیح طریقے سے سنبھالنا۔ Android پر، مساوی onPause ہے، اگرچہ معنویات مختلف ہیں: onPause تب بھی کال کیا جاتا ہے جب کوئی Activity کسی دوسرے جزو سے جزوی طور پر ڈھکی ہو۔
iOS پر، Inactive ایپلیکیشن لائف سائیکل کی ایک علیحدہ حالت ہے (پانچ میں سے ایک: Not Running، Active، Inactive، Background، Suspended)۔ Android پر کوئی براہ راست مساوی نہیں ہے — onPause اشارہ کرتا ہے کہ Activity ان پٹ فوکس کھو رہی ہے لیکن نظر آ سکتی ہے (مثال کے طور پر، جب ڈائیلاگ کھلتا ہے)۔ کلیدی فرق: iOS Inactive پوری ایپ کی حالت ہے، جبکہ Android onPause فی Activity حالت ہے۔ Android ملٹی ونڈو میں، ایک Activity onPause (بغیر فوکس) میں ہو سکتی ہے جبکہ دوسری onResume (فوکس کے ساتھ) میں ہو۔
| خصوصیت | iOS Inactive | Android onPause |
|---|---|---|
| UI نظر آتا ہے | ہاں | ہاں (جزوی یا مکمل) |
| ٹچ ایونٹس | وصول نہیں کرتا | وصول نہیں کرتا |
| مدت | رکاوٹ ختم ہونے تک | فوکس واپس آنے یا پس منظر میں جانے تک |
| اگلی حالت | Active یا Background | onResume یا onStop |
| سطح | ایپ (UIApplication) | Activity |
| ملٹی ونڈو | ایک سین فعال | متعدد Activity onPause میں |
Inactive iOS پر کئی سختی سے متعین منظرناموں میں پیدا ہوتا ہے۔ صارف Control Center کھولتا ہے (iPhone X+ پر اوپری دائیں کونے سے نیچے سوائپ یا پرانے ماڈلز پر اوپر سوائپ)۔ صارف Notification Center کھولتا ہے (اوپری بائیں کونے سے نیچے سوائپ)۔ آنے والی کال آتی ہے — سسٹم ایپ کے اوپر کال اسکرین دکھاتا ہے۔ سسٹم کی اجازت درخواست کی جاتی ہے — جغرافیائی محل وقوع، مائیکروفون، کیمرہ، رابطے۔ iPad پر، Slide Over یا Split View شروع کیا جاتا ہے — فعال سین Inactive ہو جاتا ہے۔
Android پر، onPause (Inactive کا مساوی) حالات کی ایک وسیع رینج میں پیدا ہوتا ہے۔ ڈائیلاگ کھولنا (AlertDialog، DialogFragment)۔ ایک Activity کا دوسری Activity کے ذریعے جزوی اوورلے (مثال کے طور پر، تصدیق کے لیے شفاف Activity)۔ اسکرین گھومنا (Activity دوبارہ بنائی جاتی ہے، ترتیب: onPause → onStop → onDestroy → onCreate → onStart → onResume)۔ ملٹی ونڈو موڈ — غیر فعال ونڈو onPause وصول کرتی ہے۔ ان میں سے ہر ایک واقعہ میں بیٹری اور کارکردگی بچانے کے لیے وسائل پر مبنی کاموں کو معطل کرنا ضروری ہے۔
import UIKit
extension Notification.Name {
static let systemInterruptionBegan = Notification.Name("systemInterruptionBegan")
static let systemInterruptionEnded = Notification.Name("systemInterruptionEnded")
}
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillResignActive(_ application: UIApplication) {
// ایپ Inactive میں جاتی ہے — سسٹم رکاوٹ
print("رکاوٹ: Control Center، کال یا سسٹم الرٹ")
// وقت کے لحاظ سے حساس کاموں کو معطل کرنا
pauseVideoPlayback()
stopContinuousDataCollection()
hideSensitiveInformation()
// اجزاء کو مطلع کرنا
NotificationCenter.default.post(name: .systemInterruptionBegan, object: nil)
}
// Inactive سے Active میں واپسی
func applicationDidBecomeActive(_ application: UIApplication) {
resumeVideoPlayback()
restartDataCollection()
NotificationCenter.default.post(name: .systemInterruptionEnded, object: nil)
}
private func pauseVideoPlayback() {
// ویڈیو روکنا تاکہ آواز اوورلیپ نہ ہو
}
private func hideSensitiveInformation() {
// اسکرین شاٹ پر حساس ڈیٹا چھپانا
// Control Center/App Switcher UI کا اسکرین شاٹ لیتے ہیں
}
}کوڈ UIKit میں Inactive ہینڈلنگ دکھاتا ہے۔ applicationWillResignActive ویڈیو روکتا ہے، ڈیٹا اکٹھا کرنا بند کرتا ہے اور حساس معلومات چھپاتا ہے۔ یہ اہم ہے کیونکہ جب Control Center یا App Switcher کھولا جاتا ہے، سسٹم موجودہ UI کا اسکرین شاٹ لیتا ہے — صارف پیش نظارہ میں خفیہ ڈیٹا دیکھ سکتا ہے۔ NotificationCenter ایپ کے اجزاء کو رکاوٹ کے واقعات کو سبسکرائب کرنے کی اجازت دیتا ہے۔
iOS پر، Inactive کو طریقوں کی ایک جوڑی سے سنبھالا جاتا ہے: applicationWillResignActive (Inactive میں منتقلی) اور applicationDidBecomeActive (Inactive سے واپسی)۔ یہ طریقے UIApplicationDelegate کا حصہ ہیں اور Inactive کے ذریعے ہر منتقلی کے لیے کال کیے جاتے ہیں۔ iOS 13 اور UISceneDelegate کے بعد سے، ملٹی ونڈو منظرناموں کے لیے sceneWillResignActive اور sceneDidBecomeActive شامل کیے گئے ہیں۔
iOS 13+ والے iPad پر، ایک ایپ میں متعدد سین (ونڈوز) ہو سکتے ہیں۔ ہر سین کا اپنا لائف سائیکل ہوتا ہے۔ ایک سین Inactive ہو سکتا ہے (صارف نے دوسرے سین پر سوئچ کیا) جبکہ دوسرا Active رہتا ہے۔ یہ iPhone سے ایک اہم فرق ہے، جہاں Inactive پوری ایپ کے لیے ایک عالمی حالت ہے۔ iPad کے لیے ڈیولپمنٹ کرتے وقت، آپ کو ہر سین کے لیے الگ سے Inactive سنبھالنا ہوگا۔
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
// سین غیر فعال ہو جاتا ہے
func sceneWillResignActive(_ scene: UIScene) {
// iPad پر یہ سین فوکس کھو دیتا ہے، لیکن دوسرے فعال رہ سکتے ہیں
print("سین سرگرمی کھو دیتا ہے")
// اس سین کے کام معطل کرنا
pauseSceneSpecificOperations()
}
// سین فعال ہو جاتا ہے
func sceneDidBecomeActive(_ scene: UIScene) {
print("سین فعال ہو گیا")
resumeSceneSpecificOperations()
}
private func pauseSceneSpecificOperations() {
// اس سین کے لیے مخصوص کام معطل کرنا
}
private func resumeSceneSpecificOperations() {
// فوکس واپس آنے پر کام دوبارہ شروع کرنا
}
}
// AppDelegate داخلے کا نقطہ رہتا ہے، سین کو تفویض کرتا ہے
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions
) -> UISceneConfiguration {
return UISceneConfiguration(
name: "Default Configuration",
sessionRole: connectingSceneSession.role
)
}
}کوڈ سین کی سطح پر Inactive کو سنبھالنے کے لیے SceneDelegate دکھاتا ہے۔ sceneWillResignActive تب کال کیا جاتا ہے جب کوئی مخصوص ونڈو فوکس کھو دیتی ہے — یہ iPad پر ونڈوز کے درمیان سوئچ کرتے وقت ہو سکتا ہے۔ AppDelegate ملٹی ونڈو کو سپورٹ کرنے کے لیے UISceneConfiguration کنفیگر کرتا ہے۔ ہر سین کی آزاد حالت ہوتی ہے اور ڈویلپر کو انہیں الگ سے سنبھالنا چاہیے۔
Android پر، iOS Inactive کا براہ راست مساوی Activity لائف سائیکل کا onPause() طریقہ ہے۔ یہ تب کال کیا جاتا ہے جب Activity ان پٹ فوکس کھو دیتی ہے لیکن نظر آ سکتی ہے۔ عام منظرنامے: ڈائیلاگ کھولنا، اسی ایپ میں دوسری Activity شروع کرنا، آنے والی کال، Home یا Recents بٹن دبانا۔ onPause میں، ڈویلپر کو وسائل پر مبنی کاموں — اینیمیشنز، ویڈیو پلے بیک، کیمرہ کام — کو معطل کرنا چاہیے۔
Android کا ایک اہم فرق یہ ہے کہ onPause ہمیشہ onStop سے پہلے آتا ہے، لیکن اس کے برعکس نہیں۔ ایک Activity onStop کے بغیر onPause وصول کر سکتی ہے (مثال کے طور پر، شفاف Activity کھولتے وقت)۔ نیز، onPause کو Activity کی زندگی میں کئی بار کال کیا جا سکتا ہے — ہر فوکس سوئچ پر۔ onPause میں ایک بار کی منطق نہ رکھیں — آخری کاموں کے لیے onStop استعمال کریں اور onPause صرف انٹرایکٹو اعمال کو معطل کرنے کے لیے استعمال کریں۔
class VideoPlayerActivity : AppCompatActivity() {
private var exoPlayer: ExoPlayer? = null
private var currentPosition: Long = 0L
override fun onPause() {
super.onPause()
// ایپ فوکس کھو دیتی ہے — ویڈیو روک رہے ہیں
exoPlayer?.let { player ->
if (player.isPlaying) {
currentPosition = player.currentPosition
player.pause()
}
}
// حساس ڈیٹا چھپا رہے ہیں (GDPR/بینکنگ اسکرینز)
if (window.decorView.systemUiVisibility and
View.SYSTEM_UI_FLAG_SECURE == 0
) {
hideSensitiveOverlay()
}
}
override fun onResume() {
super.onResume()
// فوکس واپس آتا ہے — پلے بیک دوبارہ شروع کر رہے ہیں
exoPlayer?.seekTo(currentPosition)
exoPlayer?.play()
showSensitiveOverlay()
}
private fun hideSensitiveOverlay() {
// مالی ڈیٹا کے اوپر سیاہ اسکرین رکھ رہے ہیں
}
}کوڈ ویڈیو پلیئر کے لیے صحیح onPause ہینڈلنگ دکھاتا ہے۔ ExoPlayer روک دیا جاتا ہے جب فوکس کھو جاتا ہے، اور پلے بیک پوزیشن محفوظ کر لی جاتی ہے۔ onResume پر واپس آنے پر، پلیئر محفوظ کردہ پوزیشن سے پلے بیک دوبارہ شروع کرتا ہے۔ مزید برآں، حساس ڈیٹا چھپانے کا ایک پیٹرن دکھایا گیا ہے — مالی اور طبی ایپس کے لیے اہم جنہیں سوئچ کرتے وقت اسکرین شاٹس سے تحفظ کی ضرورت ہوتی ہے۔
پہلا اصول — Inactive میں منتقلی کے وقت خفیہ ڈیٹا چھپائیں۔ جب صارف Control Center یا App Switcher کھولتا ہے، iOS موجودہ اسکرین کا اسکرین شاٹ لیتا ہے۔ Android پر، اسی طرح، سسٹم Recents میں آخری Activity کا پیش نظارہ دکھاتا ہے۔ خفیہ اسکرینوں کے تحفظ کے لیے UIApplication.shouldSnapshotSecureApp (iOS 16+) یا FLAG_SECURE (Android) استعمال کریں۔
دوسرا اصول — اینیمیشنز اور میڈیا روکیں۔ Inactive ویڈیو یا اینیمیشن چلانے کا اچھا وقت نہیں ہے، کیونکہ صارف انہیں دیکھ نہیں سکتا۔ مزید برآں، پس منظر میں پلے بیک سسٹم کی آوازوں (رنگ ٹون، اطلاع) کے ساتھ آڈیو اوورلیپ کا سبب بن سکتا ہے۔ Inactive میں جاتے وقت AVPlayer، ExoPlayer اور UIView.animate روکیں اور Active میں واپس آنے پر دوبارہ شروع کریں۔
تیسرا اصول — ڈیٹا ان پٹ کو روکیں۔ اگر ایپ میں ان پٹ فارم یا ڈرافٹ ہیں، تو Inactive میں جاتے وقت کی بورڈ اور ان پٹ فیلڈز لاک کریں۔ یہ واپسی پر حادثاتی ان پٹ کو روکتا ہے اور سسٹم اوورلیز کے ذریعے ڈیٹا کی روک تھام سے بچاتا ہے۔ iOS پر، پہلا جواب دہندہ چھوڑیں (view.endEditing(true))، Android پر — فوکس صاف کریں (currentFocus?.clearFocus())۔
چوتھا اصول — applicationWillResignActive یا onPause میں لمبے کام نہ کریں۔ یہ طریقے سیکنڈ کے کسر میں مکمل ہونے چاہئیں۔ اگر آپ کو بڑی مقدار میں ڈیٹا محفوظ کرنے کی ضرورت ہے، تو پس منظر کے تھریڈ پر محفوظ کرنا شروع کریں اور applicationDidEnterBackground یا onStop میں مکمل کریں۔ iOS applicationWillResignActive کے نفاذ کے لیے 5 سیکنڈ دیتا ہے، جس کے بعد سسٹم ایپ کو زبردستی ختم کر سکتا ہے۔
import UIKit
final class SecureOverlayManager {
private var blurView: UIVisualEffectView?
func showBlurOverlay() {
guard let window = UIApplication.shared.keyWindow,
blurView == nil
else { return }
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
blur.frame = window.bounds
blur.autoresizingMask = [.flexibleWidth, .flexibleHeight]
window.addSubview(blur)
blurView = blur
}
func removeBlurOverlay() {
blurView?.removeFromSuperview()
blurView = nil
}
}
// AppDelegate میں استعمال
func applicationWillResignActive(_ application: UIApplication) {
SecureOverlayManager().showBlurOverlay()
}
func applicationDidBecomeActive(_ application: UIApplication) {
SecureOverlayManager().removeBlurOverlay()
}کوڈ Inactive میں منتقلی کے دوران ڈیٹا کے تحفظ کے لیے محفوظ اوورلے کا نفاذ دکھاتا ہے۔ بلر اثر کے ساتھ UIVisualEffectView Inactive میں جاتے وقت پورے UI کے اوپر رکھا جاتا ہے اور Active میں واپس آنے پر ہٹا دیا جاتا ہے۔ یہ یقینی بناتا ہے کہ خفیہ ڈیٹا App Switcher اور Control Center اسکرین شاٹس میں نظر نہیں آئے گا۔ اسی طرح، آپ برانڈڈ اوورلے کے لیے لوگو کے ساتھ UIImageView استعمال کر سکتے ہیں۔
اکثر پوچھے گئے سوالات
ہاں۔ Inactive iOS پر Background میں جانے سے پہلے ایک لازمی درمیانی حالت ہے۔ کوئی ایپ Active سے براہ راست Background میں نہیں جا سکتی — پہلے وہ Inactive ہوتی ہے، پھر Background۔ Android پر، اسی طرح، onPause ہمیشہ onStop سے پہلے کال کیا جاتا ہے۔ یہ ڈویلپر کو مکمل طور پر پس منظر میں جانے سے پہلے ڈیٹا کو محفوظ کرنے کے لیے تیار کرنے کا موقع دیتا ہے۔
ہاں۔ iPad پر، Slide Over یا Split View شروع کرتے وقت، فعال سین Inactive ہو جاتا ہے، حالانکہ کوئی سسٹم رکاوٹ نہیں ہوتی — صرف دوسرے سین کے ساتھ تعامل کر رہا ہوتا ہے۔ یہ ملٹی ونڈو iPadOS کی ایک خصوصیت ہے۔ iPhone پر، Inactive ہمیشہ سسٹم رکاوٹ — کال، اطلاع، Control Center یا Notification Center — سے متحرک ہوتا ہے۔
عام طور پر 0.1 سے 2 سیکنڈ تک۔ کال اسکرین کے ساتھ آنے والی کال کے دوران — 30 سیکنڈ تک (جب تک صارف کال کا جواب نہ دے یا مسترد نہ کرے)۔ iOS Inactive میں وقت کو زبردستی محدود نہیں کرتا، لیکن سسٹم ایپ کو ختم کر سکتا ہے اگر وہ ایونٹس (watchdog) کا جواب نہ دے۔ Android پر، onPause کی کوئی وقت کی حد نہیں ہے، لیکن 200 ms میں کام مکمل کرنے کی سفارش کی جاتی ہے۔
ScenePhase.inactive — ScenePhase enum کی وہ قدر جو اس وقت سیٹ ہوتی ہے جب سین پیش منظر میں ہو لیکن ایونٹس وصول نہ کر رہی ہو۔ SwiftUI میں، آپ اسے @Environment(\.scenePhase) کے ذریعے دیکھ سکتے ہیں اور onChange کے ذریعے رد عمل ظاہر کر سکتے ہیں۔ .active سے .inactive میں منتقلی کے وقت، ٹائمر اور اینیمیشن روکیں۔ .active پر واپسی پر، انہیں دوبارہ شروع کریں۔ .background میں جاتے وقت، حالت محفوظ کریں۔
نہیں، صرف ان ایپس کے لیے جو خفیہ ڈیٹا سنبھالتی ہیں: بینکنگ، طبی، کارپوریٹ اور نجی چیٹ والی میسجنگ ایپس۔ گیمز اور تفریحی ایپس کے لیے، UI چھپانا ضروری نہیں ہے۔ تاہم، Inactive کے دوران گیم پلے اور آواز روکنا سسٹم اطلاعات کے ساتھ آڈیو اوورلیپ سے بچنے کے لیے اچھا عمل ہے۔ Apple حساس ڈیٹا چھپانے کی سفارش کرتا ہے لیکن اس کی ضرورت نہیں ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں