如何使用远程推送通知触发 AVAudioPlayer 播放?

Posted

技术标签:

【中文标题】如何使用远程推送通知触发 AVAudioPlayer 播放?【英文标题】:How to trigger AVAudioPlayer playback using a remote push notification? 【发布时间】:2019-06-15 00:22:21 【问题描述】:

我正在创建一个具有远程触发警报的应用。本质上,我试图在带有特定负载的远程推送通知到达时触发循环播放的 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);

我希望在推送通知到达后(应用程序处于非活动状态或后台运行)立即开始播放循环音频文件,但事实并非如此。相反,当我将应用程序带到前台时,音频播放出人意料地开始了。

这种方法缺少什么,和/或其他方法可以更好地工作吗?

【问题讨论】:

【参考方案1】:

您无法在后台启动应用程序的音频会话。音频会话必须在应用程序处于前台时初始化/启动。如果应用程序被推送到后台,只要前台的另一个应用程序不中断它,正确初始化并运行的音频会话可以继续。

根据这些信息,我会说您的应用程序可能必须在您处于控制和前台时启动音频会话,在后台保持音频会话处于活动状态。收到推送通知后,使用现有打开的音频会话将音频输出。

这有严重的限制,因为任何其他应用(例如 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)
    

【讨论】:

以上是关于如何使用远程推送通知触发 AVAudioPlayer 播放?的主要内容,如果未能解决你的问题,请参考以下文章

如何清除 iOS 的远程推送通知?

收到推送通知后如何触发操作[关闭]

BuildFire - 如何使用 SDK 从管理面板触发推送通知?

当应用程序在前台时,如何使远程通知出现在通知中心?

在后台模式下接收远程推送通知是不是可以多次振动?

应用在前台时如何触发苹果推送通知事件?