You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:19:21