Есть ли способ продлить кольцо навсегда при входящем звонке в приложении VoIP?

Я работаю над VoIP-приложением IOS.

Существует два способа воспроизвести звук, чтобы уведомить пользователя, когда приходит вызов:

  1. Отправьте UILocalNotification со звуком. Звук будет длиться не более 30 секунд;
  2. Воспроизведение локального музыкального актива в setKeepAliveTimeout:handler: функция. Но система просто дает мне 10 секунд, чтобы выполнить операцию.

Есть ли способ воспроизвести звук навсегда, как родное приложение для телефона?

2 Solutions collect form web for “Есть ли способ продлить кольцо навсегда при входящем звонке в приложении VoIP?”

Боюсь, что @ Dan2552 прав.

Вот что говорит Apple:

Звуки, длившиеся более 30 секунд, не поддерживаются. Если вы укажете файл со звуком, который воспроизводится более 30 секунд, вместо него воспроизводится звук по умолчанию.


РЕДАКТИРОВАТЬ:

Воспроизведение аудиофайла более 30 секунд (или навсегда для этого) может быть достигнуто с помощью AVAudioPlayer от AVFoundation

 @import AVFoundation; // module -> no need to link the framework // #import <AVFoundation/AVFoundation.h> // old style - (void)playAudio { NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp3"]; NSError *error = nil; AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error]; if (!error) { player.numberOfLoops = -1; // infinite loop [player play]; } else { NSLog(@"Audio player init error: %@", error.localizedDescription); } } 

Затем вместо установки свойства soundName локального уведомления вы должны вызвать этот метод в основном потоке :

 [self performSelectorOnMainThread:@selector(playAudio) withObject:nil waitUntilDone:NO]; 

Проблема с ответом Ислама Q заключается в том, что AVAudioPlayer не будет работать для уведомления, поскольку приложение будет отключено, если вы не используете приложение. Только UILocalNotification может позволить вашему приложению воспроизводить звук, когда он неактивен. 30-секундный предел реальный. Это необходимо сделать, повторив уведомление с уведомлением за 30 секунд. Я не знаю, как долго другие приложения VOIP будут звонить, но даже с традиционным телефоном есть предел, как правило, что-то вроде минуты.

Моя стратегия:

  • Отправьте начальное уведомление с 29-секундным сигналом тревоги, с которым кто-то пытается связаться
  • Отправьте второе уведомление с другим 29-секундным сигналом тревоги через 40 секунд, что вы собираетесь пропустить звонок
  • Отправьте третье уведомление о том, что вы пропустили вызов через 100 секунд

Это позволит пользователю 1:40 времени ответить на вызов.

Ваш код будет выглядеть примерно так:

 UILocalNotification* notification = [[UILocalNotification alloc] init]; notification.alertBody = NSLocalizedString(@"FIRST_CALL", @"%@ is calling you!"); notification.soundName = @"normal_ring.mp3"; [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(40 * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ if (!phone.isRinging) { // Somebody picked it up already in the mean time return; } UILocalNotification* notification = [[UILocalNotification alloc] init]; notification.alertBody = NSLocalizedString(@"HURRY_CALL", @"Hurry, you are about to miss a call from %@!"); notification.soundName = @"hurry_ring.mp3"; [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ if (!phone.isRinging) { // Somebody picked it up already in the mean time return; } UILocalNotification* notification = [[UILocalNotification alloc] init]; notification.alertBody = NSLocalizedString(@"MISSED_CALL", @"You've just missed a call from %@"); notification.soundName = @"missed_call.mp3"; [[UIApplication sharedApplication] presentLocalNotificationNow:notification]; }); }); 

Если вы используете код, имейте в виду, что вам сначала нужно убедиться, что приложение находится в фоновом режиме, поэтому UILocalNotification будет единственным вариантом, который у вас есть. Используйте обычный AVAudioPlayer, когда он находится на переднем плане, гораздо более гибкий. Во-вторых, приложение становится передним, когда пользователь отвечает на вызов, поэтому он должен отключить оповещение и позволить AVAudioPlayer взять верх.

Вы хотите более или менее плавный переход между предупреждением и звуком в приложении, чтобы иметь полностью отполированный опыт для ваших пользователей, поэтому лучше всего было бы измерить время между кольцами, и пусть AVAudioPlayer начнет точно в нужное время на начало нового цикла.

Вторая проблема заключается в том, что приложение остается в фоновом режиме. Этот простой код будет просто продолжать опрос приложения каждый раз, чтобы сохранить его в живых. Он поступает прямо из рабочего приложения, которое делает именно это, этот код опроса, если таймер все еще работает и спит в течение пяти секунд, когда он:

 UIBackgroundTaskIdentifier backgroundTask = [application beginBackgroundTaskWithExpirationHandler:^{ }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [timerExecuted timerUpdate]; while (!timerExecuted.isStopped) { [NSThread sleepForTimeInterval:5]; } [application endBackgroundTask:backgroundTask]; }); 
  • PJSIP: сбой на pj_sockaddr_get_port при перемещении приложения iOS в фоновом режиме, а затем на переднем плане
  • Приложение iOS VOIP не принимает новые сокеты в фоновом режиме
  • Внедрение VOIP в iPhone и iPad
  • Разница между voip push и регулярным нажатием при пробуждении приложения из фона
  • Лучший способ реализовать «пользовательский пользователь» VoIP на iOS
  • Приложение VOIP не пробуждается вовремя, если установить 15 минут для метода setKeepAliveTimeout
  • Включить датчик приближения в фоновом режиме
  • Отмена уведомления о баннерах в iOS8 не работает
  • Вызов не удалось в iPhone Linphone
  • Возможно ли, что VOIP-нажатие задерживается или теряется?
  • Как изменить учетную запись реестра pjsip во время перерегистрации?
  • Interesting Posts

    Показать версию приложения на экране запуска с помощью Swift

    ipatool не удается построить с помощью битового кода (xcode 7.1.1)

    Как вы используете проверку ключевых значений?

    Загрузка MKMapview в фоновом режиме, чтобы избежать проблем с задержкой

    Альтернативы моделирования классов для цели C

    Ошибка AdMob Ios: не удалось принять объявление с ошибкой: Ошибка запроса: нет объявления для показа

    Почему «pod update» производит «stty: stdin не является терминалом» на Hudson?

    Как я могу обнаружить взаимодействие где-либо вне UIControl, неинвазивно?

    Swift делает NSDate из строки неработоспособной, как ожидалось

    Установка iOS OTA не регистрирует настраиваемую схему URL

    Поиск того, что приводит к сбою Xcode 8.2 при индексировании старого проекта

    Выход из приложения iOS 4.0

    MediaFile.getFormatData () недавно записанного видео содержит плохую информацию

    значение «Приложение не работает в фоновом режиме»

    Набор кнопок выбран через BOOL

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.