我正在尝试做类似于Tile.app的事情。当它显示通知时,它会播放声音。这似乎很简单 - 使用UILocalNotification
并包含声音文件名。但是本地通知将声音限制在不超过30秒,并且Tile的声音持续播放的时间比这长得多。我希望它能够循环播放,并且一直持续到我再也无法忍受噪音了。
即使手机的静音开关打开,声音也会播放,但本地通知不会发生这种情况。出于这些原因,UILocalNotification
似乎已经出局了。
我想也许我可以发布纯文本本地通知,让我的应用播放声音。但是使用AVAudioPlayer
时,play
方法会返回NO
并且声音不会播放。
Other questions已经建议这是设计的,应用程序不应该能够从后台播放声音 - 只能继续播放已经播放的声音。我接受这个推理,除了Tile这样做,所以它显然是可能的。一个suggested workaround违反Apple的指导方针,我非常肯定苹果现在会检查。
可能相关的一些细节:
audio
后台模式
AVAudioSessionCategoryPlayback
,会话应该处于活动状态(至少setActive:error:
声称成功)。bluetooth-central
后台模式。答案 0 :(得分:2)
实际上,您可以使用AudioServices...
个功能之一
AudioServicesPlaySystemSound
AudioServicesPlayAlertSound
AudioServicesPlaySystemSoundWithCompletion
开始在后台播放声音。
我不确定可以提交给AudioServicesCreateSystemSoundID
的声音长度,因为我只是通过短循环声音进行检查以响铃,但此API与通知无关,因此可能超过30第二个限制。
修改强>
应用仍然需要audio
中的UIBackgroundModes
才能在后台播放
从我的测试项目appDelegate,iOS 9.3.1剪切
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// test sound in foreground.
registerAndPlaySound()
return true
}
func applicationDidEnterBackground(application: UIApplication) {
var task = UIBackgroundTaskInvalid
task = application.beginBackgroundTaskWithName("time for music") {
application.endBackgroundTask(task)
}
// dispatch not required, it's just to simulate "deeper" background
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(5 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.registerAndPlaySound()
}
}
func registerAndPlaySound() {
var soundId: SystemSoundID = 0
let bundle = NSBundle.mainBundle()
guard let soundUrl = bundle.URLForResource("InboundCallRing", withExtension: "wav") else {
return
}
AudioServicesCreateSystemSoundID(soundUrl, &soundId)
AudioServicesPlayAlertSound(soundId)
}
<强>更新强>
我使用beginBackgroundTask
启动声音只是在另一个项目中在后台执行代码的最简单方法registerAndPlaySound
的类似代码是在没有后台任务的情况下从PushKit
回调调用的。
答案 1 :(得分:1)
来自官方Apple documentation:
&#34;播放时自定义声音必须低于30秒。如果是自定义声音 超过该限制,而是播放默认的系统声音。&#34;
您无法让UILocalNotication
循环播放声音。您可以使用30秒的时间间隔再次安排它,但那个将是另一个警报的调度。
设置自定义通知声音:
notif.soundName = @"sound.caf";
确保声音实际上在您的应用程序包中,格式正确(线性PCM或IMA4 - 几乎任何解释如何转换iOS声音的地方都会告诉您如何操作),并且不到30秒