Audio Session هي الآلية المركزية في iOS لإدارة سلوك الصوت للتطبيق: التفاعل مع النظام، معالجة الانقطاعات، وتوجيه الصوت. يتلقى كل تطبيق iOS جلسة صوت واحدة تحدد كيفية تصرف الصوت عند قفل الشاشة، وأثناء المكالمات، وعند توصيل Bluetooth. وفقاً لـ وثائق مطوري Apple، 2026، يتم تكوين Audio Session من خلال فئة ووضع — بدون تكوين صحيح، قد لا يشغل التطبيق الصوت في الخلفية.
النقاط الرئيسية
Audio Session هي مثيل واحد من AVAudioSession ينشئه النظام عند تشغيل التطبيق ويوجد طوال دورة حياته بالكامل. تعمل كوسيط بين التطبيق ونظام الصوت في iOS: تكوين الفئة يحدد ما إذا كان مسموحاً للتطبيق بتشغيل الصوت في الخلفية، وما إذا كان الصوت سيكتم أثناء المكالمة، وإلى أي أجهزة يتم إخراج الصوت.
على عكس Android Audio Focus، حيث يطلب كل تطبيق التركيز ويحرره بشكل مستقل، تتم إدارة Audio Session في iOS مركزياً من خلال جلسة واحدة لكل تطبيق. عند تنشيط جلسة، يقوم النظام تلقائياً بإلغاء تنشيط جلسة التطبيق السابق، ويرسل له إشعار انقطاع. هذا الاختلاف المعماري يحدد الأساليب المختلفة لمعالجة الصوت على المنصتين.
وفقاً لجلسة WWDC 2024 رقم 211، حوالي 40% من مشاكل الصوت في تطبيقات iOS ناتجة عن تكوين غير صحيح لـ Audio Session. الخطأ الأكثر شيوعاً هو اختيار الفئة ambient بدلاً من playback، مما يتسبب في اختفاء الصوت عند قفل الشاشة.
عند التشغيل، يحصل التطبيق على sharedInstance للجلسة، ويحدد الفئة عبر استدعاء setCategory(_:mode:options:) وينشط الجلسة من خلال setActive(true). بعد التنشيط، يأخذ iOS في الاعتبار سياسات الفئة للتوجيه. إذا قام تطبيق آخر بتنشيط جلسته، يتلقى التطبيق الحالي إشعار AudioSessionInterruptionType.began عبر Notification.Name.AVAudioSessionInterruption.
الفئة هي المعلمة الرئيسية لـ Audio Session، حيث تحدد ستة خيارات سلوك محددة مسبقاً. اختيار الفئة هو القرار الأول والأهم عند إعداد الصوت في iOS.
| الفئة | متى تستخدم | صوت في الخلفية | كتم الصوت يؤثر |
|---|---|---|---|
| ambient | الألعاب، تأثيرات الخلفية | لا | نعم |
| playback | الموسيقى، البودكاست، الكتب الصوتية | نعم | لا |
| record | مسجل الصوت، تسجيل الصوت | لا | غير متاح |
| playAndRecord | VoIP، الرسائل الصوتية | نعم | لا |
| multiRoute | خلاطات DJ، كاريوكي | نعم | لا |
| soloAmbient | افتراضي (iOS default) | لا | نعم |
لمشغلات الموسيقى والفيديو، استخدم دائماً playback. هذه الفئة تسمح بتشغيل الصوت مع قفل الشاشة، ومع إيقاف تشغيل مفتاح كتم الصوت (الزر الفعلي على iPhone)، وعندما يكون التطبيق في الخلفية. بدون فئة playback، يتم إلغاء تنشيط الجلسة عند قفل الشاشة أو تصغير التطبيق.
الفئة ambient مناسبة للألعاب والتطبيقات ذات الأصوات الخلفية — تسمح للتطبيقات الأخرى بمواصلة التشغيل. على سبيل المثال، إذا كان المستخدم يستمع إلى الموسيقى ويفتح لعبة بجلسة ambient، تستمر الموسيقى في التشغيل فوق أصوات اللعبة. هذا اختلاف جوهري عن Android، حيث يتطلب مثل هذا السيناريو إذناً صريحاً لـ duck.
يجب إعداد Audio Session قبل بدء أي تشغيل. يُوصى بتكوين الجلسة في طريقة application(_:didFinishLaunchingWithOptions:) أو في مُهيئ المشغل. بعد تحديد الفئة، يجب تنشيط الجلسة.
import AVFAudio
let session = AVAudioSession.sharedInstance
do {
try session.setCategory(
playback,
mode: default,
options: [allowBluetooth, defaultToSpeaker]
)
try session.setActive(true)
} catch {
print("فشل إعداد Audio Session: \(error.localizedDescription)")
}
المعامل options يتضمن allowBluetooth (الإخراج إلى سماعة Bluetooth) وdefaultToSpeaker (التشغيل عبر مكبر الصوت بدلاً من السماعة). خيار allowBluetooth إلزامي للتطبيقات التي تدعم سماعات Bluetooth — بدونه، قد يتم توجيه الصوت إلى مكبر الصوت المدمج حتى عند توصيل سماعة.
let session = AVAudioSession.sharedInstance
try session.setCategory(
playAndRecord,
mode: voiceChat,
options: [allowBluetooth, allowBluetoothA2DP]
)
try session.overrideOutputAudioPort(speaker)
try session.setActive(true)
فئة playAndRecord مع وضع voiceChat تحسن مسار الصوت للاتصال الصوتي: تمكن إلغاء الصدى، التحكم التلقائي في الكسب (AGC)، وتحديد برنامج الترميز الأمثل. OverrideOutputAudioPort(.speaker) يفرض الإخراج عبر مكبر الصوت حتى عند توصيل سماعة — مفيد لمكبر الصوت.
استدعاء setActive(true) ينشط الجلسة ويخطر النظام أن التطبيق سيستخدم الصوت. عند إيقاف التشغيل مؤقتاً، يُوصى بإلغاء تنشيط الجلسة حتى تتمكن التطبيقات الأخرى من الحصول على تدفق الصوت. الاستثناء هو التطبيقات ذات التشغيل الطويل في الخلفية (الموسيقى، البودكاست)، حيث تبقى الجلسة نشطة طوال المسار بأكمله.
من المهم معالجة الأخطاء عند استدعاء setActive. إذا كانت جلسة أخرى ذات أولوية عالية نشطة (مثل الهاتف أثناء مكالمة)، قد يرمي setActive خطأ. في هذه الحالة، يجب انتظار إشعار AudioSessionInterruptionType.ended وإعادة محاولة التنشيط.
الوضع يحسن الفئة ويحسن مسار الصوت لحالة استخدام محددة. كل وضع يغير سلوك AGC وإلغاء الصدى وبرامج الترميز. الأوضاع لا تستبدل الفئة بل تكملها — فئة واحدة يمكن أن تعمل مع أوضاع مختلفة.
الخيارات توفر ضبطاً دقيقاً لسلوك الجلسة. كل خيار هو علامة يمكن دمجها مع أخرى في مصفوفة. على سبيل المثال، [.allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMix] يسمح بإخراج الصوت إلى سماعة Bluetooth، ويستخدم مكبر الصوت افتراضياً، ويختلط مع الكتب الصوتية.
في iOS 17+ ظهر خيار spatialAudio، الذي يفعل الصوت المكاني المخصص لـ AirPods عبر AVAudioSessionSpatialPreferences. وفقاً لـ WWDC 2024، الصوت المكاني يزيد من تفاعل المستخدمين في تطبيقات الموسيقى بنسبة 25% في اختبارات Apple.
الانقطاعات هي فرق رئيسي بين Audio Session و Android Audio Focus. في iOS، تتم معالجة الانقطاعات عبر NotificationCenter بالاشتراك في AVAudioSession.interruptionNotification. يحتوي الإشعار على قاموس بنوع الانقطاع: began أو ended.
override func viewDidLoad() {
super.viewDidLoad()
let center = NotificationCenter.default
center.addObserver(
self,
selector: #selector(handleInterruption),
name: AVAudioSession.interruptionNotification,
object: nil
)
}
@objc func handleInterruption(_ notification: Notification) {
guard let userInfo = notification.userInfo,
let type = userInfo[AVAudioSession.interruptionTypeKey]
as? AVAudioSessionInterruptionType
else { return }
switch type {
case began:
pausePlayback()
case ended:
guard let options = userInfo[AVAudioSession.interruptionOptionKey]
as? AVAudioSessionInterruptionOptions
else { return }
if options.contains(shouldResume) {
resumePlayback()
}
}
عند استلام interruptionType.began، يجب على المشغل إيقاف التشغيل مؤقتاً. عند استلام interruptionType.ended، تشير خاصية interruptionOptionKey إلى ما إذا كان المشغل يمكنه الاستئناف تلقائياً (shouldResume). إذا رفض المستخدم المكالمة، shouldResume = true. إذا انتهت المكالمة بانتهاء الوقت — shouldResume = false، لا يُسمح بالاستئناف.
عندما يقوم تطبيق آخر بتنشيط Audio Session الخاص به مع فئة playback، تتلقى الجلسة الحالية إشعار انقطاع. إذا استخدم تطبيق آخر ambient، لا يحدث انقطاع — تختلط الأصوات. هذا السلوك مختلف جذرياً عن Android، حيث أي تنشيط لـ Audio Focus يؤدي إلى حدث LOSS.
للتطبيقات التي تحتاج إلى مواصلة التشغيل عند تنشيط جلسات أخرى (مثل الملاحة أثناء تشغيل الموسيقى)، استخدم الخيار .mixWithOthers. هذا الخيار يسمح بخلط الصوت مع التطبيقات الأخرى، ولا يتم إرسال انقطاعات. MixWithOthers هو المكافئ في iOS لوضع duck في Android.
Audio Session يدير تلقائياً توجيه الصوت بين مكبرات الصوت المدمجة، السماعات، سماعات Bluetooth، وأجهزة AirPlay. يمكن للتطبيق مراقبة المسار الحالي من خلال الخاصية currentRoute وتلقي إشعارات حول التغييرات عبر AVAudioSession.routeChangeNotification.
عند توصيل سماعات Bluetooth، يقوم iOS تلقائياً بتحويل إخراج الصوت إليها إذا كانت الجلسة مهيأة بخيار allowBluetooth. بدون هذا الخيار، يستمر الصوت عبر مكبر الصوت المدمج. ابتداءً من iOS 16، عند توصيل AirPods Pro، يقوم النظام تلقائياً بتمكين مزامنة ProMotion لتقليل زمن الوصول.
الاشتراك في routeChangeNotification يسمح بالاستجابة لتوصيل وفصل السماعات. عند فصل سماعة Bluetooth، يجب على المشغل إيقاف التشغيل مؤقتاً — قد لا يتوقع المستخدم أن يبدأ الصوت من مكبر صوت الهاتف. وفقاً لـ Apple HIG (2026)، هذا سلوك إلزامي لتطبيقات الموسيقى.
الخاصيتان availableInputs و availableOutputs ترجعان قائمة بأجهزة الصوت المتاحة مع أنواعها (builtInSpeaker, headphones, bluetoothA2DP, hdmi). يمكن للمطور تحديد جهاز معين برمجياً من خلال overrideOutputAudioPort لسيناريوهات التوجيه المخصصة.
الأسئلة المتداولة
الفرق الرئيسي هو الهندسة. Audio Session هي جلسة واحدة مركزية لكل تطبيق يتم تكوينها مرة واحدة. Audio Focus في Android يتطلب طلب التركيز يدوياً في كل مرة تشغيل. بالإضافة إلى ذلك، iOS يدعم الخلط عبر خيار mixWithOthers، بينما في Android duck هو البديل الوحيد للإيقاف الكامل.
السبب الأكثر شيوعاً هو فئة Audio Session غير صحيحة. إذا تم تحديد ambient أو soloAmbient، يتوقف الصوت عند قفل الشاشة. بدّل الفئة إلى playback وتأكد من إضافة Background Modes — Audio, AirPlay, and Picture in Picture في Info.plist.
أضف الخيار .mixWithOthers إلى setCategory. سيسمح هذا بخلط صوت تطبيقك مع الجلسات النشطة الأخرى. بدون هذا الخيار، يقاطع التطبيق الجديد التطبيق الحالي. MixWithOthers هو مماثل لوضع duck في Android، ولكن مع الحفاظ الكامل على مستوى الصوت.
استخدم overrideOutputAudioPort بقيمة nil للاختيار التلقائي. للإخراج القسري إلى Bluetooth: احصل على AVAudioSessionRouteDescription من availableOutputs، حدد منفذاً بنوع .bluetoothA2DP ومرره إلى overrideOutputAudioPort. تأكد من أن الجلسة مهيأة بـ allowBluetooth.
معظم التطبيقات — نعم. إلغاء تنشيط الجلسة عند الإيقاف المؤقت يسمح للتطبيقات الأخرى بالحصول على تركيز الصوت. الاستثناء هو مشغلات الموسيقى ذات التشغيل الطويل في الخلفية. إذا كان الإيقاف قصيراً (أقل من 5 ثوانٍ)، من الأفضل إبقاء الجلسة نشطة للاستئناف السريع.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا