Audio Session — مکانیزم مرکزی iOS برای مدیریت رفتار صوتی برنامه: تعامل با سیستم، پردازش وقفهها و مسیریابی صدا. هر برنامه iOS یک جلسه صوتی واحد دریافت میکند که تعیین میکند صدا هنگام قفل صفحه، تماسها و اتصال بلوتوث چگونه رفتار کند. طبق Apple Developer Documentation, 2026، Audio Session از طریق دستهبندی و حالت تنظیم میشود — بدون پیکربندی صحیح، برنامه ممکن است صدا را در پسزمینه پخش نکند.
نکات اصلی
Audio Session — یک نمونه واحد AVAudioSession است که توسط سیستم هنگام راهاندازی برنامه ایجاد میشود و در تمام چرخه حیات آن وجود دارد. این به عنوان واسط بین برنامه و سیستم صوتی iOS عمل میکند: تنظیم دستهبندی تعیین میکند که آیا برنامه مجاز به پخش صدا در پسزمینه است، آیا صدا در هنگام تماس کاهش مییابد و صدا به کدام دستگاهها خروجی داده میشود.
برخلاف Android Audio Focus، که در آن هر برنامه به طور مستقل فوکوس را درخواست و آزاد میکند، iOS Audio Session به صورت متمرکز از طریق یک جلسه در هر برنامه مدیریت میشود. هنگام فعالسازی جلسه، سیستم به طور خودکار جلسه برنامه قبلی را غیرفعال میکند و اعلان وقفه به آن ارسال میکند. این تفاوت معماری، رویکرد متفاوتی را برای پردازش صدا در دو پلتفرم تعیین میکند.
طبق WWDC 2024 Session 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 (خروجی به هدست بلوتوث) و defaultToSpeaker (پخش از طریق بلندگو به جای گوشی) است. گزینه allowBluetooth برای برنامههای پشتیبانیکننده از هدفون بلوتوث الزامی است — بدون آن صدا ممکن است حتی با هدست متصل به بلندگوی داخلی خروجی دهد.
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 بمانید و فعالسازی را تکرار کنید.
حالت (mode) دستهبندی را دقیقتر میکند و مسیر صوتی را برای نوع خاصی از استفاده بهینه میکند. هر حالت رفتار AGC، حذف پژواک و کدکها را تغییر میدهد. حالتها جایگزین دستهبندی نمیشوند، بلکه آن را تکمیل میکنند — یک دستهبندی میتواند با حالتهای مختلف کار کند.
گزینهها تنظیم دقیق رفتار جلسه را فراهم میکنند. هر گزینه یک پرچم است که با سایرین در آرایه ترکیب میشود. به عنوان مثال، [.allowBluetooth, .defaultToSpeaker, .interruptSpokenAudioAndMix] امکان خروجی صدا به هدست بلوتوث، استفاده از بلندگو به طور پیشفرض و میکس با کتابهای صوتی را فراهم میکند.
در iOS 17+ گزینه spatialAudio ظاهر شد که صدای فضایی شخصیسازیشده را برای AirPods از طریق AVAudioSessionSpatialPreferences فعال میکند. طبق WWDC 2024، صدای فضایی تعامل کاربران برنامههای موسیقی را در آزمایشهای Apple تا 25٪ افزایش میدهد.
وقفهها (interruptions) — تفاوت کلیدی 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 به طور خودکار مسیریابی صدا را بین بلندگوهای داخلی، هدفونها، هدستهای بلوتوث و دستگاههای AirPlay مدیریت میکند. برنامه میتواند مسیر جاری را از طریق ویژگی currentRoute پیگیری کند و اعلانهای تغییرات را از طریق AVAudioSession.routeChangeNotification دریافت کند.
هنگام اتصال هدفون بلوتوث، iOS به طور خودکار خروجی صدا را به آنها تغییر میدهد اگر جلسه با گزینه allowBluetooth پیکربندی شده باشد. بدون این گزینه، صدا همچنان از بلندگوی داخلی پخش میشود. از iOS 16، هنگام اتصال AirPods Pro، سیستم به طور خودکار همگامسازی ProMotion را برای کاهش تأخیر فعال میکند.
اشتراک در routeChangeNotification امکان واکنش به اتصال و قطع هدفون را فراهم میکند. هنگام قطع هدست بلوتوث، پخشکننده باید پخش را متوقف کند — کاربر ممکن است انتظار نداشته باشد صدا از بلندگوی تلفن پخش شود. طبق Apple HIG (2026)، این رفتار الزامی برای برنامههای موسیقی است.
ویژگیهای availableInputs و availableOutputs لیست دستگاههای صوتی موجود را با انواع آنها برمیگردانند (builtInSpeaker, headphones, bluetoothA2DP, hdmi). توسعهدهنده میتواند به صورت برنامهریزی دستگاه خاصی را از طریق overrideOutputAudioPort برای سناریوهای مسیریابی سفارشی انتخاب کند.
سوالات متداول
تفاوت اصلی — معماری. Audio Session یک جلسه متمرکز در هر برنامه است که یک بار پیکربندی میشود. Audio Focus در Android نیاز به درخواست دستی فوکوس در هر بار پخش دارد. علاوه بر این، iOS میکسینگ را از طریق گزینه mixWithOthers پشتیبانی میکند، در حالی که در Android duck تنها جایگزین برای توقف کامل است.
رایجترین علت — دستهبندی نادرست Audio Session. اگر ambient یا soloAmbient انتخاب شده باشد، صدا هنگام قفل صفحه متوقف میشود. دستهبندی را به playback تغییر دهید و مطمئن شوید که در Info.plist Background Modes — Audio, AirPlay, and Picture in Picture اضافه شده است.
گزینه .mixWithOthers را در setCategory اضافه کنید. این امکان میکس صدای برنامه شما با سایر جلسات فعال را فراهم میکند. بدون این گزینه، برنامه جدید برنامه جاری را قطع میکند. MixWithOthers — معادل حالت duck در Android، اما با حفظ کامل حجم صدا.
برای انتخاب خودکار از overrideOutputAudioPort با nil استفاده کنید. برای خروجی اجباری به بلوتوث: AVAudioSessionRouteDescription را از availableOutputs دریافت کنید، پورت با نوع .bluetoothA2DP را انتخاب کرده و به overrideOutputAudioPort ارسال کنید. مطمئن شوید جلسه با allowBluetooth پیکربندی شده است.
برای اکثر برنامهها — بله. غیرفعالسازی جلسه هنگام توقف به سایر برنامهها اجازه میدهد فوکوس صوتی دریافت کنند. استثنا — پخشکنندههای موسیقی با پخش طولانی در پسزمینه. اگر مکث کوتاه است (کمتر از ۵ ثانیه)، بهتر است جلسه را برای ادامه سریع فعال نگه دارید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید