13

I know there are many questions on SOF, but this is the "newest" one. The thing is, I'm trying to create and alarm app, and I know for a fact that there are alarm apps out there that works perfectly ( somehow ), even if the app is not running and is in the background.

My question is: how do you start playing sound after your app is already in the background ??

UILocalNotification is great, but you'll only get application:(_:didReceiveLocalNotification:) after the user has already clicked on your notification, so playing sound using AVAudioPlayer didn't work, i want to play sound regardless weather the user clicks on it or doesn't. Of course with Required background modes: App plays audio or streams audio/video using AirPlay in info.plist already set. Once the music starts playing, it keeps playing even if i go to the background.

I don't want to use UILocalNotificaation sound coz it's limited to 30 secs and only the able to play the sounds that are bundled with the application.

Any insights ? thoughts ??

Sample code:

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

the above code gets called when the user selects and alarm and clicks save.

and here's what's happening in 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")


}

You need to hold a strong reference to the AVAudioPlayer btw, so it won't get released, and the audioplayer.play() won't do anything...

rmaddy
  • 298,130
  • 40
  • 468
  • 517
Nour1991
  • 697
  • 1
  • 6
  • 17
  • if your app is in background, `didreceivelocalnotification` should be called after the notification fired. Maybe you can place your code over there to play sound. – Chris Jul 15 '14 at 03:09
  • i tried it many times, it doesn't, it only gets fired after the user actually clicks on the notification. I'll edit my question anyway. – Nour1991 Jul 15 '14 at 03:12

1 Answers1

10

Finally, I managed to do it with 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()
}

and somewhere else a UILocalNotification is synced with this timer, for a good user experience.

Although I'm not sure if this would go through apple, but I don't see any reason why it wouldn't :\

Nour1991
  • 697
  • 1
  • 6
  • 17
  • So, you can start playing sound when app is in background via this code? – somedev Oct 30 '14 at 13:13
  • yeah you can, try it out, it worked for me... didn't publish app to store yet, would love to know if someone can confirm this.. – Nour1991 Oct 31 '14 at 02:20
  • 8
    I can't figure out why does it works. If app running in the background, it usually become suspended after few minutes. So, the timer won't fire playAlarm() if app is in suspended state. – somedev Oct 31 '14 at 06:08
  • hey friend have you got any github repo with your alarm? Thanks! – pekpon Jan 27 '15 at 00:26
  • Did this technic work. Were you able to publish you app in app store – Souandios Mar 25 '15 at 06:49
  • @Nour1991 Did you get this approved? – Eric Mar 25 '15 at 22:41
  • I'm extremely sorry guys.. but the development of that app stopped and I didn't publish it, so I can't give you an exact answer :\ a piece of advice, try it out in a small app with like very minimal features which you can finish it in a week, and publish it, see if that works.. then you continue development or stop it ;) – Nour1991 Mar 26 '15 at 02:50
  • Will this get rejected by the store ? Can anyone comment on this ? – Joel Dean Feb 24 '16 at 00:25
  • Have anybody tried it yet and gets approved by Apple? – Muhammad Umair Apr 13 '16 at 21:17
  • I believe your app has 180s to complete tasks before it kills your app. This timer is firing before that period is up so it works. I do not believe it would work after that time period. – pwcremin Oct 26 '16 at 20:42