Swift开发Radio应用:local notification触发iOS stream audio及定时自动播放问询
嘿,针对你开发Swift电台应用的两个需求,我给你整理了具体的实现方案,都是实际项目里验证过的思路:
一、实现带定时自动播放的Playlist功能
这个功能核心是把用户选择的电台和定时规则绑定,通过本地通知触发播放,分三步来做:
1. 设计定时播放的数据模型
首先得存下电台信息和定时规则,用Codable结构体方便序列化存储,比如:
import Foundation struct ScheduledRadio: Codable { let radioID: String // 电台唯一标识 let radioName: String // 电台名称 let scheduleTime: Date // 首次播放时间 let repeatWeekday: Int? // 重复的星期几(iOS里1=周日,2=周一…7=周六,nil表示只播放一次) }
可以用UserDefaults做轻量存储,或者用Core Data存大量数据,看你的需求。
2. 做选择电台+设置定时的UI交互
用户从电台列表点击「添加到定时播放」后,弹出一个包含日期选择器和重复选项的弹窗:
- 用
UIDatePicker让用户选择具体的时分,日期可以固定或者让用户选(不过你需求是每周固定时间,所以主要选时分) - 加一个分段控件或者复选框,让用户选择重复规则(比如「仅一次」「每周一」「每周二」等)
- 确认后,把用户选择的参数封装成
ScheduledRadio实例,存起来同时注册定时通知。
3. 注册本地定时通知
用UserNotifications框架创建定时触发的通知,把电台信息塞进通知的userInfo里,方便触发时识别要播放的电台:
import UserNotifications func scheduleRadioPlay(_ scheduledRadio: ScheduledRadio) { let center = UNUserNotificationCenter.current() // 1. 创建通知内容 let content = UNMutableNotificationContent() content.title = "电台提醒" content.body = "\(scheduledRadio.radioName) 即将开始播放!" content.sound = .default // 后台触发时需要sound唤醒应用 // 把电台数据转成Data存入userInfo if let data = try? JSONEncoder().encode(scheduledRadio) { content.userInfo["scheduledRadio"] = data } // 2. 设置触发规则 var dateComponents = Calendar.current.dateComponents([.hour, .minute], from: scheduledRadio.scheduleTime) if let weekday = scheduledRadio.repeatWeekday { dateComponents.weekday = weekday // 设置重复的星期几 } // repeats设为true表示重复触发,false表示仅一次 let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: scheduledRadio.repeatWeekday != nil) // 3. 创建并添加通知请求 let requestID = "\(scheduledRadio.radioID)_\(scheduledRadio.scheduleTime.timeIntervalSince1970)" let request = UNNotificationRequest(identifier: requestID, content: content, trigger: trigger) center.add(request) { error in if let error = error { print("定时播放任务添加失败:\(error.localizedDescription)") } else { // 这里可以把scheduledRadio存入本地存储 saveScheduledRadio(scheduledRadio) } } }
二、解决Local Notification触发时的后台音频播放问题
iOS后台播放音频需要配置权限和正确的会话设置,还要处理通知触发时的唤醒逻辑:
1. 配置后台播放权限
在Info.plist里添加后台模式:
- 右键Info.plist → Add Row → 选择
Required background modes - 添加子项
App plays audio or streams audio/video using AirPlay(对应键值audio)
2. 初始化音频会话
在App启动时(比如AppDelegate的didFinishLaunchingWithOptions或者SceneDelegate的scene(_:willConnectTo:options:))配置音频会话,确保后台能播放:
import AVFoundation func setupAudioSession() { let session = AVAudioSession.sharedInstance() do { // 设置类别为playback,支持后台播放 try session.setCategory(.playback, mode: .default, options: [.mixWithOthers]) try session.setActive(true) } catch { print("音频会话初始化失败:\(error.localizedDescription)") } }
3. 处理通知触发的回调
实现UNUserNotificationCenterDelegate,在通知触发时(不管App在前台还是后台/挂起)启动音频播放:
// 在AppDelegate或者SceneDelegate里设置代理 UNUserNotificationCenter.current().delegate = self extension AppDelegate: UNUserNotificationCenterDelegate { // 通知被用户点击或者后台自动触发时调用 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 解析userInfo里的电台数据 guard let data = response.notification.request.content.userInfo["scheduledRadio"] as? Data, let scheduledRadio = try? JSONDecoder().decode(ScheduledRadio.self, from: data) else { completionHandler() return } // 启动音频播放(这里假设你有一个单例的音频管理类) RadioPlayerManager.shared.playRadio(with: scheduledRadio.radioID) completionHandler() } // 前台收到通知时的展示设置 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.banner, .sound]) } }
关键注意点
- 必须提前请求用户的通知权限:在App启动时调用
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound])获取授权 - 音频播放器要做成单例,避免被销毁,确保后台播放时实例存活
- 后台触发通知时,系统会唤醒App几秒钟处理回调,要确保播放逻辑在这段时间内完成
- 如果是网络流音频,要确保后台网络请求权限(在Info.plist里添加
App uses HTTP或者配置ATS例外)
内容的提问来源于stack exchange,提问作者Ekta Padaliya
相关产品推荐
相关产品推荐

