播放自定义声音的UILocalNotifications

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

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

我的猜测是你的声音没有适当地格式化,以操作系统播放。 确保你的声音格式为IMA4格式。 另外,确保你的文件在你的应用程序包中,你应该很好。

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

select本地通知的自定义声音

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

soundName属性的描述 –

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

似乎没有其他的声音可以使用。 你确定应用程序正在使用本地通知与自定义的声音? 也许他们正在用警报或类似的东西播放声音。

HTH,

阿克沙伊

 notif.soundName = @"sound.caf"; 

这应该工作。 确保声音实际上在您的应用程序包中,格式正确(线性PCM或IMA4 – 几乎任何地方,说明如何转换iOS的声音将告诉你如何做到这一点),是在30秒以下。

你可以使用terminal从WAV和MP3转换:

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

'in.wav'是你要转换的input声音,'sound.caf'是输出文件,改变目录到你想要的输出文件

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

我用我的Mac系统声音来testing。 我在控制台中使用这个命令转换它:

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

那么我遇到了同样的问题,这听起来像这是不支持之前或不能播放本地通知自定义声音不包含在应用程序包中。 但是后来这个支持,你可以专门在库/声音目录中从App容器分配自定义声音。 它和我一起工作。 你可以从服务器上下载声音到这个目录,或者通过复制一个.caf文件(苹果公司表示其他的扩展可能工作)从bundle到Library / sounds目录来testing它,然后删除这个文件的引用,这样就可以确保如果播放的声音是来自捆绑目录。 这一切工作得很好,如果用户强制引用应用程序停止工作本地通知,但它仍然与推送工具包通知,我即时调度本地一个虽然当推套件推到达时,我的主要问题。 这里是testing从目录播放声音的代码:

  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属性,就像文件捆绑一样。

你是否正在清理旧的通知?

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

否则你可以,从手机上删除应用程序(也许需要重新启动)它应该工作:-)

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

除此之外,苹果文件说:

持续超过30秒的声音不被支持。 如果您指定播放超过30秒的声音的文件,则会播放默认声音。

希望它现在有所帮助:-)