Как запустить воспроизведение AVAudioPlayer с помощью удаленного push-уведомления? - PullRequest
0 голосов
/ 15 июня 2019

Я создаю приложение, которое имеет удаленно сработавший будильник. По сути, я пытаюсь запустить зацикленный MP3-файл для воспроизведения (когда приложение установлено на заднем плане), когда приходит удаленное push-уведомление с определенной полезной нагрузкой.

Я пытался использовать didReceiveRemoteNotification: fetchCompletionHandler:, чтобы можно было запустить код в результате получения удаленного уведомления с определенной userInfo полезной нагрузкой.

Вот моя попытка didReceiveRemoteNotification: fetchCompletionHandler: из моего AppDelegate.m:

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

Я ожидал, что зацикленный аудиофайл начнет воспроизводиться, как только придет push-уведомление (приложение неактивное или фоновое), но это не так. Вместо этого неожиданно началось воспроизведение звука, когда я вывел приложение на передний план.

Чего не хватает в этом подходе и / или может ли другой способ работать лучше?

1 Ответ

0 голосов
/ 15 июня 2019

Вы не можете начать аудио сеанс с приложением в фоновом режиме.Аудио сеансы должны быть инициализированы / запущены, пока приложение находится на переднем плане.Аудиосеанс, должным образом инициализированный и запущенный, может продолжаться, если приложение перемещается в фоновый режим, если другое приложение на переднем плане не прерывает его.

На основании этой информации я бы сказал, что вашему приложению, скорее всего, нужно запустить аудиосеанспока вы находитесь под контролем и на переднем плане, поддерживайте аудио сеанс в фоновом режиме.Получив push-уведомление, используйте существующий открытый аудио-сеанс для доставки аудио.

Это имеет серьезные ограничения, поскольку любое другое приложение, такое как Netflix, которое использует выделенный аудио-сеанс, может прерывать аудио-сеанс вашего приложения и предотвращать его.от возможности воспроизведения MP3, когда он прибудет.

Вы можете заранее подумать о предварительной упаковке и / или загрузке MP3, и обращаться к ним прямо в параметрах Sound вашего push-уведомления..

Вы можете следовать этому руководству, чтобы увидеть, как можно воспроизводить пользовательские звуки с помощью push-уведомлений: 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)
    }
}
...