9

I implemented local notification in my app but I am just wondering is there a way to play a sound that is not part of the main bundle of iPhone App. Basically in my app, I want user to record a sound that gets played when the local notification is generated instead of playing a pre-recorded or default sound. As far as i know this can be implementable because i have seen 2-3 App in app store which is doing the same thing which i want to do

- (void)alertSelector:(NSString *)AlertTitle WithFiringTime:(NSDate *)date
{ 

UILocalNotification *localNotification = [[[UILocalNotification alloc] init] autorelease];
   [localNotification setFireDate:date];
   [localNotification setTimeZone:[NSTimeZone defaultTimeZone]];
   NSDictionary *data = [NSDictionary dictionaryWithObject:date forKey:@"payload"];       
   [localNotification setUserInfo:data];[localNotification setAlertBody:AlertTitle];   
   [localNotification setAlertAction:@"View"]; [localNotification setHasAction:YES]; 
   localNotification.soundName=@"voice.aif"; 

   if (!localNotification)
          return;

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; 
}
Akshay
  • 5,747
  • 3
  • 23
  • 35
Muhammad Saqib
  • 993
  • 2
  • 15
  • 37
  • Could you link to one of the apps that's doing this? Thanks. – Art Gillespie Feb 03 '12 at 19:31
  • @ArtGillespie Here is the one of many apps that allows to set recorded sound for UILocalNotification. http://itunes.apple.com/in/app/record-alarm-free/id418511936?mt=8 – necixy Feb 08 '12 at 05:20
  • for me the issue was because we had multiple targets, and the audio file I added was only added to 1 target. Basically I had to add it to all of our targets... – mfaani Feb 21 '17 at 20:38

6 Answers6

3

My guess is your sound isn't formatted appropriately to play by the OS. Make sure your sound is formatted in IMA4 format. Also, make sure your file is in your application bundle, and you should be good to go.

For more reference and similar question, see this SO question.

Choose custom sound for Local Notifications

Here is a link for Apple's Local and Push Notification Guide. It explains the sounds in detail and the default sounds that can be used.

Community
  • 1
  • 1
Bill Burgess
  • 14,054
  • 6
  • 49
  • 86
  • Any code for playing the recorded sound from "Documents" directory for UILocalNotification as asked? – necixy Feb 03 '12 at 19:34
  • I believe you just need to replace the name of your sound with UILocalNotificaionDefaultSoundName – Bill Burgess Feb 03 '12 at 19:37
  • I have updated my answer with another link to Apple documentation that should help you. – Bill Burgess Feb 03 '12 at 19:40
  • As it's been mentioned in question "Basically in my app, I want user to record a sound that gets played when the local notification is generated instead of playing a pre-recorded or default sound. As far as i know this can be implementable because i have seen 2-3 App in app store which is doing the same thing which i want to do" The pages you mentioned, doesn't have any example of setting the recorded sound. Since a few of apps do that hence we are sure there must be a work around. – necixy Feb 03 '12 at 19:42
  • Some good information here. http://www.tuaw.com/2007/08/06/iphone-coding-recording-audio/ – Bill Burgess Feb 03 '12 at 20:22
  • I don't see there how to set the recorded sound to UILocalNotification as asked. If you search the page for a keyword "notification" there are no match. Any idea about how to set the recorded sound as notification sound? – necixy Feb 07 '12 at 06:40
  • To all future StackOverflow researchers, the bounty is given automatically by the system and this method doesn't solves the problem. At least not yet. – necixy Aug 20 '12 at 09:58
0
notif.soundName = @"sound.caf";

That should work. Make sure the sound is actually in your app’s bundle, is in the correct format (linear PCM or IMA4—pretty much anywhere that explains how to convert sounds for iOS will tell you how to do that), and is under 30 seconds.

You can convert from wav and mp3 using terminal :

afconvert -f caff -d LEI16@44100 -c 1 in.wav sound.caf

'in.wav' is input sound which u want to convert and 'sound.caf' is output file ,change directory to where u want to have the out put file

Suraj K Thomas
  • 5,773
  • 4
  • 52
  • 64
0

Make sure your sound file is added to the "Copy Bundle Resources" list under Project Settings->(Target)->Build Phases. This fixed the issue for me. At first I only got the default sound, even though I specified a custom file name (and the file was added to the project). But after I manually added the file to this list it started working.

I used a system sound from my mac to test with. I converted it using this command in a console:

afconvert /System/Library/Sounds/Basso.aiff ~/Downloads/alert2.caf -d ima4 -f caff -v
Peterd
  • 13
  • 4
0

Well I was experiencing same Issue , It sounds like this was not supported before or not doable to play custom sound for local notification that is not included in App Bundle. But later this is supported and you can assign custom sounds from App container specifically in Library/Sounds directory . And it worked with me . you can either download sounds from server to this directory or test it by copying a .caf(Apple said other extensions may work) file from bundle to Library/sounds directory and then remove reference for the file from bundle so that you can make sure that if sounds played it is from directory out of bundle . This all works very well , the main issue with me if user force quoted the app it stops working for local notification while it still works with push kit notifications , Im scheduling local one though when push kit push arrives. Here is the code for testing playing sound from directory :

 func copyFileToDirectoryFromBundle()
{
    // get reference to library directory
    let LibraryDirectoryPaths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)

    // see what is in there 
    for path in LibraryDirectoryPaths
    {
        print("di=\(path)")
    }

    // prepare for sound directory
    let libraryDirectoryPath: AnyObject = LibraryDirectoryPaths[0]
    let soundsDirectoryPath = libraryDirectoryPath.stringByAppendingPathComponent("Sounds")

    // create sounds directory under library if not there already
    if !NSFileManager.defaultManager().fileExistsAtPath(soundsDirectoryPath)
    {
    do {
        try NSFileManager.defaultManager().createDirectoryAtPath(soundsDirectoryPath, withIntermediateDirectories: false, attributes: nil)
        print("sounds library created,,,")
    } catch let error as NSError {
        print("creating sounds directory error = \(error.localizedDescription)");
    }
    }
    else
    {
        print("Sounds directory is there already under Library")
    }

    do {
        // sounds directory should have been added under library
        let directoryContents = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( NSURL(string: libraryDirectoryPath as! String)!, includingPropertiesForKeys: nil, options: [])
        print("Library directs=\(directoryContents)")


        // prepare for adding subdirectory with file name from bundle
        // here is where you should save files if downloaded from server 
        // here im just moving one from bundle 

        let subDirectoryPath = directoryContents.last!

        if let pathFromBundle = NSBundle.mainBundle().pathForResource("notification", ofType:"caf") {
            let myFilePathUnderSounds = "\(subDirectoryPath.path!)\("/notification.caf")"
            if !NSFileManager.defaultManager().fileExistsAtPath(myFilePathUnderSounds)
            {
            do {
                print("bundle path=\(pathFromBundle)and datacontainer path=\(subDirectoryPath.path!)")
                try NSFileManager.defaultManager().copyItemAtPath(pathFromBundle, toPath:myFilePathUnderSounds )
                print("item copied")
            } catch let error as NSError {
                print(error.localizedDescription);
            }
            }
            else
            {
                print("Your file from bundle path = \(pathFromBundle) is already there under Sounds")
            }
        }
        else
        {
            print("Item not found in bundle")
        }

        // see item there after you add it
        let subDirectories = try NSFileManager.defaultManager().contentsOfDirectoryAtURL( subDirectoryPath, includingPropertiesForKeys: nil, options: [])

        print("files under sounds")
        for fileDirectory in subDirectories
        {
            print(fileDirectory)
        }

    } catch let error as NSError {
        print(error.localizedDescription)
    }

}

After making sure .caf file is under Library/Sounds directory . All you have to do is merely assigning file name with extension to local notification soundName property like if the file is in bundle.

IsPha
  • 389
  • 4
  • 9
0

From the description of the soundName property -

For this property, specify the filename (including extension) of a sound resource in the application’s main bundle or UILocalNotificationDefaultSoundName to request the default system sound.

It doesn't seem that sounds other than those present in the bundle can be used. Are you sure that the apps are using local notifications with their custom sounds? Maybe they are playing sounds with alerts or something like that.

HTH,

Akshay

Akshay
  • 5,747
  • 3
  • 23
  • 35
  • Hi Akshay Thank you for your response , yeah i am sure they are using UIlocalnotification should i give u the links of those App? They are free App and doing the the same thing which i want to do. I think stack overflow would not allow the sharing of those link ? – Muhammad Saqib Aug 20 '11 at 04:17
  • Are you scheduling the notification or displaying it immediately? – Akshay Aug 21 '11 at 13:03
  • I am scheduling it using NSLocalnotification. – Muhammad Saqib Aug 22 '11 at 05:04
  • Can you add the code you are using to display the notifications? – Akshay Aug 22 '11 at 08:21
  • - (void)alertSelector:(NSString *)AlertTitle WithFiringTime:(NSDate *)date{ UILocalNotification *localNotification = [[[UILocalNotification alloc] init] autorelease];[localNotification setFireDate:date]; [localNotification setTimeZone:[NSTimeZone defaultTimeZone]];NSDictionary *data = [NSDictionary dictionaryWithObject:date forKey:@"payload"]; [localNotification setUserInfo:data];[localNotification setAlertBody:AlertTitle]; [localNotification setAlertAction:@"View"]; [localNotification setHasAction:YES]; localNotification.soundName=@"voice.aif"; if (!localNotification) return; – Muhammad Saqib Aug 22 '11 at 09:36
  • [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; } [here voice.aif is the sound which is present in my mainbundle i want to play the sound which is present in my Document folder] – Muhammad Saqib Aug 22 '11 at 09:37
  • Does your app execute in the background? I am sorry, but the only way i can think of is, playing the sound from your background code at the same time when the notification fires. – Akshay Aug 23 '11 at 04:59
  • yeah my App execute in background because as i am developing it for iPhone 4 or above ios it support multitasking. but how can we play the sound in background can you plz explain me in more detail .I will be vert thank full to you because i am working on this issue scene last 15 days – Muhammad Saqib Aug 23 '11 at 08:25
-2

are you cleaning the old notifications with?

UIApplication* app = [UIApplication sharedApplication];
NSArray*  oldNotifications = [app scheduledLocalNotifications];
if ([oldNotifications count] > 0) {
    [app cancelAllLocalNotifications];
}

else you can, delete the app from the phone (maybe need a reboot too) the it should work :-)

beside that the code mentioned above should be correct. and this line localNotification.soundName=@"voice.aif"; should be enough to play custom sounds. but if you had notification tested first with no sound-file added, the default sound file (UILocalNotificationDefaultSoundName) is registered! and to re-register you have to cancel the previous notification (cancelAllLocalNotifications) or delete the app, to be able to "re"-register your notfication,

beside that, the apple doc says:

Sounds that last longer than 30 seconds are not supported. If you specify a file with a sound that plays over 30 seconds, the default sound is played instead.

hope it helps now :-)

Flori
  • 2,453
  • 1
  • 21
  • 31
  • Not relevant—question is about how to get a UILocalNotification to play with a custom sound. – yuji Feb 10 '12 at 14:57