UILocalNotifications 播放自定义声音

发布于 2024-11-29 22:44:51 字数 918 浏览 1 评论 0 原文

我在我的应用程序中实现了本地通知,但我只是想知道是否有一种方法可以播放不属于 iPhone 应用程序主包的一部分的声音。 基本上在我的应用程序中,我希望用户录制生成本地通知时播放的声音,而不是播放预先录制的或默认的声音。 据我所知,这是可以实现的,因为我在应用程序商店中看到了 2-3 个应用程序正在做与我想做的事情相同的事情

- (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]; 
}

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]; 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

甜警司 2024-12-06 22:44:51

我的猜测是您的声音格式不适合操作系统播放。确保您的声音格式为 IMA4 格式。另外,请确保您的文件位于应用程序包中,这样您就可以开始了。

有关更多参考和类似问题,请参阅此 SO 问题。

为本地通知选择自定义声音

这是 Apple 的本地和推送通知指南。它详细解释了声音以及可以使用的默认声音。

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.

北方的巷 2024-12-06 22:44:51

根据 soundName 属性的描述 -

对于此属性,指定文件名(包括扩展名)
应用程序主包中的声音资源或
UILocalNotificationDefaultSoundName 请求默认系统
声音。

除了捆绑包中存在的声音之外,似乎无法使用其他声音。您确定应用程序正在使用带有自定义声音的本地通知吗?也许他们正在播放带有警报的声音或类似的东西。

HTH,

阿克谢

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

薯片软お妹 2024-12-06 22:44:51
notif.soundName = @"sound.caf";

这应该有效。确保声音实际上在您的应用程序包中,格式正确(线性 PCM 或 IMA4 - 几乎任何解释如何转换 iOS 声音的地方都会告诉您如何执行此操作),并且时间少于 30 秒。

您可以使用终端从 wav 和 mp3 进行转换:

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

“in.wav”是您想要转换的输入声音,“sound.caf”是输出文件,将目录更改为您想要输出文件的位置

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

天邊彩虹 2024-12-06 22:44:51

确保您的声音文件已添加到“项目设置”->(目标)->“构建阶段”下的“复制捆绑资源”列表中。
这为我解决了这个问题。起初,即使我指定了自定义文件名(并且该文件已添加到项目中),我也只获得了默认声音。但在我手动将文件添加到此列表后,它开始工作。

我使用 Mac 上的系统声音进行测试。我在控制台中使用以下命令对其进行了转换:

afconvert /System/Library/Sounds/Basso.aiff ~/Downloads/alert2.caf -d ima4 -f caff -v

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
凡尘雨 2024-12-06 22:44:51

好吧,我遇到了同样的问题,听起来以前不支持此功能,或者无法为应用程序包中未包含的本地通知播放自定义声音。但后来支持了这一点,您可以从应用程序容器中专门分配自定义声音,特别是在 Library/Sounds 目录中。这对我很有用。您可以将声音从服务器下载到此目录,也可以通过将 .caf(Apple 表示其他扩展名可能有效)文件从捆绑包复制到 Library/sounds 目录来测试它,然后从捆绑包中删除该文件的引用,以便您可以确保如果播放声音,则它来自包之外的目录。这一切都工作得很好,我的主要问题是,如果用户强制引用该应用程序,它会停止为本地通知工作,但仍然可以使用推送套件通知,但当推送套件推送到达时,我会安排本地通知。
以下是测试从目录播放声音的代码:

 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)
    }

}

确保 .caf 文件位于 Library/Sounds 目录下后。您所要做的只是将带有扩展名的文件名分配给本地通知 soundName 属性,就像文件位于捆绑包中一样。

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.

一笔一画续写前缘 2024-12-06 22:44:51

您正在清理旧通知吗?

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

否则,您可以从手机中删除该应用程序(可能还需要重新启动)
它应该可以工作:-)

除了上面提到的代码应该是正确的。
此行 localNotification.soundName=@"voice.aif"; 应该足以播放自定义声音。
但如果您首先测试了通知而没有添加声音文件,则默认声音文件 (UILocalNotificationDefaultSoundName) 会被注册!要重新注册,您必须取消以前的通知(cancelAllLocalNotifications)或删除该应用程序,才能“重新”注册您的通知,

除此之外,苹果文档说:

不支持持续时间超过 30 秒的声音。如果你
指定声音播放超过 30 秒的文件,默认
而是播放声音。

希望现在有帮助:-)

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 :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文