4

General problem / application background / purpose:

I have a Timer app and I would like to play a custom sound when the App is in BACKGROUND state and receives a UILocalNotification.

I utilize UILocalNotification to trigger the timer (its the only way as an App cannot run a process in the background for longer than 10 minutes).

Issues:

  • Is there a way to play a different UILocalNotification sound? If so how can I do it? (In other words: when the app receives the UILocalNotification the custom sound is played - which is not loud enough.. I would like to get a proper alarm sound)

This is how I set my sound when I send my UILocalNotification:

_localNotif.soundName = UILocalNotificationDefaultSoundName;

I then create the notification and post it. Once the app receives it I handle it in the following method (please read the code comments for added information):

- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification {
    NSLog(@"received notification");

    // Here I try to play a custom sound created in a custom object 
    // however the sound does NOT get played when the APP is in BACKGROUND mode (but I still see the NSLog message in console "received notification" 
    SoundManager* audio = [SoundManager sharedInstance];
    [audio playSound:Standard];
}
mm24
  • 9,280
  • 12
  • 75
  • 170

3 Answers3

0

Try changing your line

_localNotif.soundName = UILocalNotificationDefaultSoundName;

To something like this:

_localNotif.soundName = "customSoundFileName.customSoundFileExtension";

As it states in official docs you have to specify the filename of a sound resource in your app’s main bundle. I have a working example that I can share with you if you need it.
Good luck!

aldoram5
  • 1,556
  • 3
  • 18
  • 18
0

In the view controller where you fire the local notification:

.h

#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController <AVAudioPlayerDelegate>

@property (nonatomic, strong) AVAudioPlayer *notificationSound;

You don't have to fire a local notification if it enters the background in the app delegate, a local notification will fire regardless if they are in the background or not. didReceiveLocalNotification is how you handle it when the app is active : From the docs here :

Sent to the delegate when a running app receives a local notification.

.m

-(void)startTimer {
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(runTimerTasks:) userInfo:nil repeats:YES];
    [self fireLocalNotification];
}

-(void)fireLocalNotification {
 UILocalNotification *timerDoneNotification = [[UILocalNotification alloc] init];
 timerDoneNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:secondsLeft];
 timerDoneNotification.alertBody = @"Time Up!";
 timerDoneNotification.alertAction = @"OK";
 timerDoneNotification.timeZone = [NSTimeZone defaultTimeZone];
 timerDoneNotification.soundName = @"alarm.aif"; 
 [[UIApplication sharedApplication] scheduleLocalNotification:timerDoneNotification];
}

And then if you just want to play/stop the sound elsewhere like if the secondsLeft is 0 when the app is active you call it as follows :

[self playAlarm];

-(void)playAlarm {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:@"alarm" ofType:@"aif"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSError *error = nil;
self.notificationSound = [[AVAudioPlayer alloc] initWithData:fileData error:&error];
self.notificationSound.numberOfLoops = -1;
[self.notificationSound play];
}

And to stop it:

[self.notificationSound stop]; 

Downside to this is UILocalNotification sounds can not be longer than 30 seconds but it answers the question at hand.


Reference : UILocalNotification Docs

Points of interest :

When the system delivers a local notification, several things can happen, depending on the app state and the type of notification. If the app is not frontmost and visible, the system displays the alert message, badges the app, and plays a sound—whatever is specified in the notification. If the notification is an alert and the user taps the action button (or, if the device is locked, drags open the action slider), the app is woken up or launched. (If the user taps one of the custom actions you specify using the additionalActions property, the app is woken up or launched into the background.) In its application:didFinishLaunchingWithOptions: method, the app delegate can obtain the UILocalNotification object from the launch options dictionary using the UIApplicationLaunchOptionsLocalNotificationKey key. The delegate can inspect the properties of the notification and, if the notification includes custom data in its userInfo dictionary, it can access that data and process it accordingly. On the other hand, if the local notification only badges the app icon, and the user in response launches the app, the application:didFinishLaunchingWithOptions: method is called, but no UILocalNotification object is included in the options dictionary. When the user selects a custom action, the app delegate’s application:handleActionWithIdentifier:forLocalNotification:completionHandler: method is called to handle the action.

If the app is foremost and visible when the system delivers the notification, the app delegate’s application:didReceiveLocalNotification: is called to process the notification. Use the information in the provided UILocalNotification object to decide what action to take. The system does not display any alerts, badge the app’s icon, or play any sounds when the app is already frontmost.

Community
  • 1
  • 1
soulshined
  • 9,612
  • 5
  • 44
  • 79
  • Side note. alarm.aiff is a custom sound that you can make with GarageBand and increase the master volume as you see fit, to circumvent the 'not loud enough' issue your having – soulshined Jan 23 '15 at 03:06
0
UILocalNotification *notification = [UILocalNotification new];
notification.fireDate = [NSDate date]; //
notification.alertBody = @"This is custom alarm";
notification.soundName = @"YourCustomAudioFile.aiff";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];

BUT

Your custom audio files must conforms two conditions:

  1. Audio length less than 30 seconds
  2. Audio file format should be: raw PCM, or MA4, or uLaw, or aLaw (wav, aiff or caf file containers)

So if you have MP3 custom alarm sound, you should convert it... Here is Apple documentation (lookup for Preparing Custom Alert Sounds section) link

Vitalii Gozhenko
  • 9,220
  • 2
  • 48
  • 66