我正在创建一个具有远程触发警报的应用程序。本质上,当远程推送通知到达特定的有效负载时,我试图触发循环播放的MP3文件(当应用程序处于后台时)。
我尝试使用didReceiveRemoteNotification: fetchCompletionHandler:
,以便可以通过接收带有特定userInfo
有效负载的远程通知来运行代码。
这是我从AppDelegate.m尝试的didReceiveRemoteNotification: fetchCompletionHandler:
:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
NSString *command = [userInfo valueForKeyPath:@"custom.a.command"];
if (command) {
UIApplicationState applicationState = [[UIApplication sharedApplication] applicationState];
if ([command isEqualToString:@"alarm"] && applicationState != UIApplicationStateActive) {
// Play alarm sound on loop until app is opened by user
NSLog(@"playing alarm.mp3");
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"alarm" ofType:@"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
NSError *error;
self.player = nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:&error];
self.player.numberOfLoops = -1; // Infinitely loop while self.player is playing
self.player.delegate = self;
[self.player play];
}
}
completionHandler(UIBackgroundFetchResultNewData);
}
我希望推送通知到达时(应用处于非活动状态或后台),循环音频文件将立即开始播放,但是没有。相反,当我随后将应用程序置于前台时,音频播放意外开始。
此方法缺少什么,和/或其他方法能否更好地工作?
答案 0 :(得分:0)
您无法在后台启动该应用程序的音频会话。当应用程序处于前台状态时,必须初始化/启动音频会话。如果将应用程序推送到后台,并且前台的另一个应用程序不会中断音频会话,则音频会话可以正确初始化并继续运行。
基于此信息,我想说,您的应用程序可能必须在您处于控制状态和前台时启动音频会话,而在后台运行音频会话。收到推送通知后,使用现有的打开的音频会话将音频输出。
这有严重的局限性,因为其他任何使用专用音频会话的应用程序(例如Netflix)都可能会中断您应用程序的音频会话,并使其无法在播放MP3时播放。
您可能需要考虑预先打包和/或下载MP3,并在推送通知的Sound
参数中直接引用它们。
您可以按照本教程来了解如何使用推送通知播放自定义声音:https://medium.com/@dmennis/the-3-ps-to-custom-alert-sounds-in-ios-push-notifications-9ea2a2956c11
func pushNotificationHandler(userInfo: Dictionary<AnyHashable,Any>) {
// Parse the aps payload
let apsPayload = userInfo["aps"] as! [String: AnyObject]
// Play custom push notification sound (if exists) by parsing out the "sound" key and playing the audio file specified
// For example, if the incoming payload is: { "sound":"tarzanwut.aiff" } the app will look for the tarzanwut.aiff file in the app bundle and play it
if let mySoundFile : String = apsPayload["sound"] as? String {
playSound(fileName: mySoundFile)
}
}
// Play the specified audio file with extension
func playSound(fileName: String) {
var sound: SystemSoundID = 0
if let soundURL = Bundle.main.url(forAuxiliaryExecutable: fileName) {
AudioServicesCreateSystemSoundID(soundURL as CFURL, &sound)
AudioServicesPlaySystemSound(sound)
}
}