Active — iOS ایپلیکیشن کے لائف سائیکل کی فعال حالت، جس میں یہ پیش منظر میں ہوتی ہے، ٹچ ایونٹس وصول کرتی ہے اور صارف کے ساتھ تعامل کرتی ہے۔ ہم جانیں گے کہ Active حالت کیسے کام کرتی ہے، UIApplicationDelegate کے کون سے طریقے اس کے ذمہ دار ہیں اور Swift میں Active اور Inactive کے درمیان منتقلی کو صحیح طریقے سے کیسے ہینڈل کریں۔
اہم نکات
Active — موبائل ایپلیکیشن کے لائف سائیکل کی ایک حالت، جس میں یہ پیش منظر میں ہوتی ہے، ڈیوائس کی اسکرین پر ظاہر ہوتی ہے اور صارف کے ساتھ فعال طور پر تعامل کرتی ہے۔ اس حالت میں ایپلیکیشن تمام ٹچ ایونٹس، کی پریس، ایکسلرومیٹر اور جائروسکوپ ڈیٹا وصول کرتی ہے، اور انٹرفیس رینڈر کرنے کے لیے گرافکس پروسیسر تک مکمل رسائی رکھتی ہے۔
iOS میں Active حالت پانچ ریاستی لائف سائیکل ماڈل کا حصہ ہے: Not Running → Inactive → Active → Inactive → Background → Suspended → Not Running۔ Android میں اس کا مشابہ onResume کال کے بعد Activity کی حالت ہے، جب Activity اسٹیک کے اوپر ہوتی ہے اور صارف ان پٹ وصول کرتی ہے۔ Active وہ واحد حالت ہے جس میں UI مکمل طور پر انٹرایکٹو ہوتا ہے اور جیسچرز، اسکرول، پریس اور اینیمیشنز کا جواب دیتا ہے۔
سسٹم Active میں ایپلیکیشن کو CPU اور RAM میں زیادہ سے زیادہ ترجیح فراہم کرتا ہے۔ اس کا مطلب ہے کہ وسائل کی کمی پر سسٹم ایسی ایپلیکیشن کو ختم نہیں کرے گا — پہلے پس منظر اور معطل شدہ عمل ان لوڈ کیے جائیں گے۔ تاہم ایپلیکیشن کو بیٹری ختم ہونے اور CPU تھروٹلنگ سے بچنے کے لیے وسائل کو مؤثر طریقے سے استعمال کرنا چاہیے۔
صارف کے لیے Active ایپلیکیشن کے ساتھ کام کرنے کی معمول کی حالت ہے۔ صارف انٹرفیس دیکھتا ہے، بٹن دبا سکتا ہے، فارم بھر سکتا ہے، فیڈ اسکرول کر سکتا ہے۔ اس حالت میں کسی بھی رکاوٹ (کال، نوٹیفکیشن، Control Center کے لیے اوپر سوائپ) سے ایپلیکیشن Inactive میں چلی جاتی ہے، پھر یہ Active میں واپس آ سکتی ہے یا Background میں جا سکتی ہے۔
iOS حالت کو منظم کرنے کے لیے UIApplicationMain استعمال کرتا ہے۔ Active میں منتقلی پر سسٹم applicationDidBecomeActive کو کال کرتا ہے۔ SwiftUI کے لیے اسی طرح کا طریقہ کار Environment کے ذریعے scenePhase کا مشاہدہ ہے۔ Android پیش منظر میں Activity کی سرگرمی کے اشارے کے طور پر onResume استعمال کرتا ہے۔ دونوں طریقے اس بات کو یقینی بناتے ہیں کہ ایپلیکیشن کو حالت کی تبدیلی کا اطلاع ملے اور وہ اپنے رویے کو اپنا سکے۔
| پلیٹ فارم | طریقہ/واقعہ | Swift (UIKit) | SwiftUI | Android (Kotlin) |
|---|---|---|---|---|
| iOS | Active میں منتقلی | applicationDidBecomeActive | scenePhase == .active | — |
| iOS | Active سے نکلنا | applicationWillResignActive | scenePhase == .inactive | — |
| Android | Active میں منتقلی | — | — | onResume() |
| Android | Active سے نکلنا | — | — | onPause() |
iOS میں Active حالت UIApplicationDelegate کے ذریعے ہینڈل کی جاتی ہے۔ اہم طریقہ — applicationDidBecomeActive(_:)۔ یہ ایپلیکیشن کے پہلے لانچ پر اور Inactive سے واپسی پر کال کیا جاتا ہے۔ یہ طریقہ ان کاموں کو دوبارہ شروع کرنے کے لیے مثالی جگہ ہے جو Inactive میں جانے پر معطل کر دیے گئے تھے: اینیمیشنز شروع کرنا، ٹائمرز دوبارہ شروع کرنا، سینسرز دوبارہ فعال کرنا، سرور پر ڈیٹا اپ ڈیٹس کی جانچ کرنا۔
iOS 13 سے Apple نے iPad پر متعدد ونڈوز کو سپورٹ کرنے کے لیے UISceneDelegate متعارف کرایا۔ اس صورت میں applicationDidBecomeActive کو ہر انفرادی سین کے لیے sceneDidBecomeActive سے تبدیل کر دیا جاتا ہے۔ صرف ایک اسکرین کو سپورٹ کرنے والی ایپلیکیشنز UIApplicationDelegate استعمال جاری رکھ سکتی ہیں۔ دونوں طریقے اس لمحے کال کیے جاتے ہیں جب ایپلیکیشن یا سین فعال ہو جاتی ہے۔
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
// ایپلیکیشن فعال ہو گئی — کام دوبارہ شروع کر رہے ہیں
func applicationDidBecomeActive(_ application: UIApplication) {
resumeAnimations()
restartTimers()
refreshDataIfNeeded()
startObservingSensors()
}
// ایپلیکیشن فعالی کھو رہی ہے — معطل کر رہے ہیں
func applicationWillResignActive(_ application: UIApplication) {
pauseAnimations()
stopTimers()
saveDraftData()
}
private func resumeAnimations() {
UIView.animate(withDuration: 0.3) {
// UI اینیمیشنز دوبارہ شروع
}
}
private func refreshDataIfNeeded() {
let lastRefresh = UserDefaults.standard.object(forKey: "lastRefresh") as? Date ?? .distantPast
if Date().timeIntervalSince(lastRefresh) > 300 {
fetchDataFromServer()
}
}
}کوڈ UIKit میں Active کی صحیح ہینڈلنگ دکھاتا ہے۔ applicationDidBecomeActive اینیمیشنز، ٹائمرز کو دوبارہ شروع کرتا ہے اور چیک کرتا ہے کہ ڈیٹا اپ ڈیٹ کی ضرورت ہے یا نہیں۔ applicationWillResignActive ہر اس چیز کو معطل کرتا ہے جو وسائل استعمال کر سکتی ہے اور ڈرافٹ محفوظ کرتا ہے۔ طریقوں کا ایسا جوڑا اس بات کو یقینی بناتا ہے کہ ایپلیکیشن حالت کی تبدیلی پر صحیح ردعمل ظاہر کرے۔
SwiftUI میں AppDelegate نہیں ہے — حالت کا انتظام Environment<ScenePhase> کے ذریعے ہوتا ہے۔ .active ویلیو اس وقت سیٹ ہوتی ہے جب سین پیش منظر میں اور انٹرایکٹو ہو۔ SwiftUI Active میں واپسی پر خود بخود اینیمیشنز اور اپ ڈیٹس دوبارہ شروع کرتا ہے۔ ڈویلپر کو صرف onChange پر سبسکرائب کرنا ہوتا ہے ضمنی اثرات انجام دینے کے لیے۔
import SwiftUI
@main
struct ActiveDemoApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { oldPhase, newPhase in
switch newPhase {
case .active:
print("سین فعال ہو گئی")
resumeWork()
case .inactive:
print("سین غیر فعال ہو گئی")
pauseWork()
case .background:
print("سین پس منظر میں چلی گئی")
saveState()
@unknown default:
break
}
}
}
private func resumeWork() {
// نیٹ ورک کی درخواستیں، اینیمیشنز دوبارہ شروع
}
private func pauseWork() {
// وقت کے لحاظ سے حساس کام معطل
}
private func saveState() {
// ایپلیکیشن کی حالت محفوظ کرنا
}
}SwiftUI میں scenePhase ایپلیکیشن کی حالت کے بارے میں سچائی کا واحد ذریعہ ہے۔ onChange ہر منتقلی پر اعمال انجام دینے کی اجازت دیتا ہے۔ یہ یاد رکھنا ضروری ہے کہ scenePhase صرف iOS 14+ اور SwiftUI Lifecycle میں دستیاب ہے۔ SwiftUI اسکرینوں والی UIKit ایپلیکیشنز کے لیے UIApplicationDelegate طریقہ استعمال کریں۔
Active کئی راستوں سے حاصل کیا جاتا ہے۔ پہلا اور واضح — کولڈ اسٹارٹ: صارف آئیکن پر دباتا ہے، ایپلیکیشن Not Running سے Inactive ہو کر Active میں جاتی ہے۔ دوسرا — پس منظر سے واپسی: صارف App Switcher کے ذریعے ایپلیکیشن میں واپس آتا ہے، ایپلیکیشن Inactive سے گزر کر Active ہو جاتی ہے۔ تیسرا — عارضی رکاوٹ سے واپسی: صارف کال ختم کرتا ہے، Control Center بند کرتا ہے یا نوٹیفکیشن کا جواب دیتا ہے — ایپلیکیشن Inactive سے Active میں واپس آتی ہے۔
Not Running → Inactive → Active — کولڈ اسٹارٹ۔ Background → Inactive → Active — پس منظر سے واپسی۔ Inactive → Active — عارضی رکاوٹ سے واپسی۔ ہر صورت میں applicationDidBecomeActive کال کیا جاتا ہے، لیکن سیاق مختلف ہو سکتا ہے۔ کولڈ اسٹارٹ پر Active سے پہلے didFinishLaunchingWithOptions کال کیا جاتا ہے، پس منظر سے واپسی پر — willEnterForeground۔ ڈویلپر حالت بحالی کی حکمت عملی منتخب کرنے کے لیے ان فرقوں کو استعمال کر سکتا ہے۔
| منظرنامہ | منتقلی کا راستہ | iOS کال بیک | Android کال بیک |
|---|---|---|---|
| کولڈ اسٹارٹ | Not Running → Active | didFinishLaunching → didBecomeActive | onCreate → onStart → onResume |
| پس منظر سے واپسی | Background → Active | willEnterForeground → didBecomeActive | onRestart → onStart → onResume |
| Suspended سے واپسی | Suspended → Active | willEnterForeground → didBecomeActive | onRestart → onStart → onResume |
| رکاوٹ کے بعد | Inactive → Active | didBecomeActive | onResume |
اہم نوٹ: Suspended سے واپسی پر iOS didFinishLaunchingWithOptions کو کال نہیں کرتا، کیونکہ ایپلیکیشن پہلے سے میموری میں لوڈ تھی۔ اس کا مطلب ہے کہ اس طریقے میں رکھا گیا انیشیالائزیشن کوڈ دوبارہ عمل میں نہیں آتا۔ ڈویلپر اکثر اسے بھول جاتے ہیں اور دونوں منظرناموں کے لیے اہم منطق applicationWillEnterForeground یا applicationDidBecomeActive میں منتقل کر دیتے ہیں۔
Android میں Active کا مشابہ onResume() کال کے بعد Activity کی حالت ہے۔ Activity اس وقت فعال سمجھی جاتی ہے جب یہ پیش منظر میں ہو اور صارف ان پٹ وصول کرے۔ یہ حالت Activity اسٹیک کے اوپری حصے سے مطابقت رکھتی ہے۔ اگر کوئی دوسری Activity اوپر ظاہر ہو (جزوی طور پر بھی)، موجودہ Activity onPause حالت میں چلی جاتی ہے — iOS Inactive کا مشابہ۔
Android کی کلیدی خصوصیت — multi-window موڈ (split screen, freeform) میں متعدد Activity ایک ساتھ فعال ہو سکتی ہیں۔ اس صورت میں جس Activity کے ساتھ صارف تعامل کر رہا ہے وہ فعال سمجھی جاتی ہے، اور پڑوسی Activity معطل (onPause) ہوتی ہے۔ iOS iPhone پر multi-window کو سپورٹ نہیں کرتا، صرف iPad پر UIScene کے ذریعے۔
class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
// ایپلیکیشن فعال ہو گئی — کام دوبارہ شروع کر رہے ہیں
resumeCameraPreview()
startLocationUpdates()
activateSensors()
}
override fun onPause() {
super.onPause()
// ایپلیکیشن فعالی کھو رہی ہے — وسائل آزاد کر رہے ہیں
releaseCamera()
stopLocationUpdates()
deactivateSensors()
}
private fun resumeCameraPreview() {
// کیمرہ پیش منظر شروع (اجازت درکار)
cameraProvider?.unbindAll()
cameraProvider?.bindToLifecycle(
this,
cameraSelector,
preview,
imageAnalyzer
)
}
private fun startLocationUpdates() {
val locationRequest = LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY, 5000
).build()
locationClient.requestLocationUpdates(
locationRequest,
locationCallback,
Looper.getMainLooper()
)
}
}کوڈ Android میں onResume/onPause کے ذریعے Active کی ہینڈلنگ دکھاتا ہے۔ onResume کیمرہ، جغرافیائی محل وقوع اور سینسرز کے ساتھ کام دوبارہ شروع کرتا ہے — وہ وسائل جو صرف اس وقت فعال ہونے چاہئیں جب ایپلیکیشن صارف کو نظر آئے۔ onPause بیٹری خرچ نہ کرنے کے لیے ان وسائل کو آزاد کرتا ہے۔ CameraX lifecycle-aware API onPause پر خود بخود پیش منظر معطل کر دیتا ہے۔
پہلا اصول — applicationDidBecomeActive یا onResume میں بھاری کارروائیاں نہ کریں۔ ڈیٹا لوڈنگ، JSON پارسنگ، ڈیٹا بیس کے ساتھ کام — یہ سب غیر متزامن ہونا چاہیے اور مرکزی تھریڈ کو مسدود نہیں کرنا چاہیے۔ پس منظر کے کاموں کے لیے iOS میں GCD (DispatchQueue) اور Kotlin میں Coroutines استعمال کریں۔ مرکزی تھریڈ کو صرف UI اپ ڈیٹ کرنا چاہیے اور غیر متزامن کارروائیاں شروع کرنی چاہئیں۔
دوسرا اصول — Active میں ہر واپسی پر حالت کو ہم آہنگ کریں۔ صارف نے سسٹم ایپلیکیشن میں ترتیبات تبدیل کی ہو سکتی ہیں، push نوٹیفکیشن موصول کیا ہو سکتا ہے یا کسی دوسری ایپلیکیشن میں ڈیٹا اپ ڈیٹ کیا ہو سکتا ہے۔ Active میں منتقلی پر کیشے کی درستگی چیک کریں — صارف کی غیر موجودگی میں ڈیٹا پرانا ہو سکتا ہے۔
تیسرا اصول — Active کو واحد حالت کے طور پر مت سمجھیں۔ ایپلیکیشن Active کو چھوڑ سکتی ہے اور براہ راست Not Running سے Background میں جا سکتی ہے (اگر پس منظر موڈ میں لانچ کی گئی ہو)۔ iOS میں یہ content-available آپشن کے ساتھ push نوٹیفکیشن کے ذریعے لانچ کرنے پر ہوتا ہے۔ Android میں — BroadcastReceiver کے ذریعے لانچ کرنے پر۔ UI کارروائیاں کرنے سے پہلے ہمیشہ موجودہ حالت چیک کریں۔
چوتھا اصول — onActivityResult کے بجائے Android میں Activity Result API استعمال کریں۔ یہ Active حالت میں کیمرہ، گیلری یا اجازتوں کی کال کے نتیجے کو Activity کی دوبارہ تخلیق پر ڈیٹا ضائع کیے بغیر پروسیس کرنے کی اجازت دیتا ہے۔ iOS کے لیے سسٹم ڈائیلاگز کے لیے UIApplication.shared.open کے ساتھ async/await استعمال کریں۔
import UIKit
final class ActiveStateManager {
static let shared = ActiveStateManager()
private var isActive = false
func setActive(_ active: Bool) {
isActive = active
if active {
NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
}
}
func performWhenActive(_ block: @escaping () -> Void) {
if isActive {
block()
} else {
// Active میں واپسی تک انجام ملتوی کریں
NotificationCenter.default.addObserver(
forName: .appDidBecomeActive,
object: nil,
queue: .main
) { _ in
block()
}
}
}
}
extension Notification.Name {
static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}کوڈ Active حالت کا مینیجر دکھاتا ہے، جو ایپلیکیشن کے دوسرے اجزاء کو موجودہ فعال حالت چیک کرنے کی اجازت دیتا ہے۔ performWhenActive یا تو فوری طور پر بلاک کو انجام دیتا ہے اگر ایپلیکیشن فعال ہو، یا Active میں واپسی تک انجام کو ملتوی کر دیتا ہے۔ یہ ان خدمات کے لیے مفید ہے جنہیں صارف کے ایپلیکیشن میں واپس آنے کے بعد کارروائی کرنی ہو۔
اکثر پوچھے جانے والے سوالات
یہ طریقہ ہر بار کال ہوتا ہے جب ایپلیکیشن فعال حالت میں جاتی ہے: پہلے لانچ پر، پس منظر سے واپسی پر، Control Center یا Notification Center بند کرنے کے بعد، کال ختم ہونے کے بعد۔ عام سیشن میں صارف کے اعمال کے لحاظ سے 5–10 بار کال ہو سکتا ہے۔ اس طریقے میں ایک بار کی انیشیالائزیشن نہ رکھیں۔
Visible — ایک غیر سرکاری اصطلاح ہے، جس کا مطلب ہے کہ ایپلیکیشن اسکرین پر نظر آتی ہے لیکن واقعات وصول نہیں کر سکتی (مثال کے طور پر، iPad پر کسی دوسری ونڈو سے جزوی طور پر ڈھکی ہوئی)۔ Active — سرکاری حالت ہے، جس میں ایپلیکیشن نظر بھی آتی ہے اور انٹرایکٹو بھی ہے۔ iPhone پر Visible ایپلیکیشن ہمیشہ Active ہوتی ہے، iPad پر Visible + Inactive صورت ممکن ہے۔
willEnterForeground پس منظر سے واپسی پر کال ہوتا ہے، لیکن ایپلیکیشن ابھی فعال نہیں ہوتی — یہ Inactive میں ہوتی ہے۔ didBecomeActive ایپلیکیشن کے مکمل طور پر انٹرایکٹو ہونے کے بعد کال ہوتا ہے۔ اگر صارف کے انٹرفیس دیکھنے سے پہلے کوئی کارروائی کرنی ہو — willEnterForeground استعمال کریں۔ اگر دکھانے کے بعد — didBecomeActive استعمال کریں۔
نہیں۔ Active کا مطلب ہے کہ ایپلیکیشن پیش منظر میں ہے اور اسکرین پر ظاہر ہو رہی ہے۔ دکھائی دینے والے UI کے بغیر ایپلیکیشن Background یا Suspended میں ہو سکتی ہے۔ مستثنیٰ — iPad multi-window، جہاں ایک ونڈو فعال ہو سکتی ہے اور دوسری نہیں، لیکن دونوں نظر آتی ہیں۔ VoiceOver اور ڈکٹیشن اس اصول کو نہیں بدلتے۔
iOS سیمیولیٹر پر Home Screen پر جانے کے لیے Cmd+Shift+H دبائیں (ایپلیکیشن Background میں جاتی ہے)، پھر دوبارہ ایپلیکیشن آئیکن پر کلک کریں۔ اسکرین لاک (willResignActive) اور انلاک (didBecomeActive) کے لیے Cmd+L استعمال کریں۔ Inactive جانچنے کے لیے Control Center (macOS کی بورڈ کے لیے Cmd+Shift+;) یا Notification Center کال کریں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں