iOS 8,在后台播放声音,闹钟应用程序

13

我知道 SOF 上有很多问题,但这是“最新”的一个。事实上,我正在尝试创建一个闹钟应用程序,并且我知道已经有一些完美运行的闹钟应用(不知何故),即使该应用程序未运行且在后台中。

我的问题是:如何在您的应用程序已经在后台运行之后开始播放声音?

UILocalNotification 很棒,但只有在用户已经单击通知后才会得到 application:(_:didReceiveLocalNotification:),因此使用 AVAudioPlayer 播放声音没有用,我想无论用户是否单击它都要播放声音。当然,在 info.plist 中设置了 Required background modes: App plays audio or streams audio/video using AirPlay。一旦开始播放音乐,即使我进入后台,它仍将继续播放。

我不想使用 UILocalNotificaation 声音,因为它限制为 30 秒,并且只能播放与应用程序捆绑的声音。

有什么见解吗?想法?

示例代码:

    var notif = UILocalNotification()
    notif.fireDate = self.datePicker.date
    notif.alertBody = "test"
    UIApplication.sharedApplication().scheduleLocalNotification(notif)

当用户选择并点击保存时,上述代码将被调用。

以下是AppDelegate中正在发生的情况:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    NSLog("launched")
    application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Alert |
        UIUserNotificationType.Badge, categories: nil
        ))
    AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
    AVAudioSession.sharedInstance().setActive(true, error: nil)

    self.sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sound", ofType: "caf"))
    self.audioPlayer = AVAudioPlayer(contentsOfURL: sound, error: nil)

    return true
}

func application(application: UIApplication!, didReceiveLocalNotification notification: UILocalNotification!){
    audioPlayer.play()
    NSLog("received local notif")


}

需要持有AVAudioPlayer的强引用,这样它就不会被释放了,audioplayer.play()才会起作用...


如果您的应用程序在后台运行,通知触发后应调用“didreceivelocalnotification”。也许您可以在那里放置代码以播放声音。 - Chris
我尝试了很多次,它不起作用,只有在用户实际点击通知后才会触发。无论如何,我还是会编辑我的问题。 - Nour Helmi
1个回答

9

最终,我通过 NSTimer 成功实现了它。

func applicationWillResignActive(application: UIApplication) {
    var timer = NSTimer(fireDate: NSDate(timeIntervalSinceNow: 20), interval: 60.0, target: self, selector: Selector("playAlarm"), userInfo: nil, repeats: false)
    NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
}
func playAlarm() {
    self.sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sound", ofType: "caf"))
    self.audioPlayer = AVAudioPlayer(contentsOfURL: sound, error: nil)
    audioPlayer.play()
}

还有一个地方与此定时器同步的是 UILocalNotification,这样可以提供良好的用户体验。

虽然我不能确定这是否会通过苹果审核,但我没有找到任何理由不通过 :\<


8
我不明白为什么它会起作用。如果应用程序在后台运行,通常几分钟后就会被挂起。因此,如果应用程序处于挂起状态,定时器不会触发播放警报声(playAlarm())。 - somedev
这个技巧管用吗?你成功地发布了你的应用到应用商店吗? - Souandios
@Nour1991 你批准了吗? - Eric
1
有人尝试过并且已经被苹果批准了吗? - Muhammad Umair
1
我相信你的应用程序有180秒的时间来完成任务,否则它会终止你的应用程序。这个计时器在期限到期之前就会触发,所以它可以工作。我不认为在那个时间段之后它会起作用。 - pwcremin
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接