Настройка приложения iOS VoIP для работы в спящем / фоновом режиме

Я разрабатываю приложение на основе VoIP iOS (7.1). Это базовое программирование сокетов написано на C++, а не на objective C. приложение отлично работает на переднем плане, но при вводе в спящий/фоновый режим оно не может получать никаких сообщений от сервера. Согласно документу apple, мы должны настроить один из сокетов приложения для использования VoIP. Я не могу понять, как настроить сокеты c++ (потому что есть много сокетов; т. е. SSL, SIP, RESTful).

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

2 ответов


Edit: начните с iOS8, apple представляет PushKit framework, чтобы освободить работу, которую нам нужно сделать, чтобы настроить приложение VoIP, а также снижает потребление энергии. Вам действительно нужно перейти на него

есть советы по разработке приложения VoIP, ссылка из Яблоко

приложение Voice over Internet Protocol (VoIP) позволяет пользователю совершать телефонные звонки, используя подключение к интернету вместо сотовой связи устройства. Такое приложение должно поддерживать постоянное сетевое подключение к соответствующей службе, чтобы получать входящие вызовы и другие соответствующие данные. Вместо того, чтобы держать VoIP приложения бодрствуют все время, система позволяет им быть приостановлены и предоставляет средства для мониторинга их сокетов для них. При обнаружении входящего трафика система пробуждает приложение VoIP и возвращает ему управление своими сокетами.

существует несколько требований для реализации VoIP app:

  1. включите фоновый режим Voice over IP для вашего приложения. (Поскольку VoIP-приложения включают аудиоконтент, рекомендуется также включить фоновый режим аудио и AirPlay.) Вы включаете фоновые режимы на вкладке возможности вашего проекта Xcode.
  2. настройте один из сокетов приложения для использования VoIP.
  3. перед переходом в фоновый режим вызовите метод setKeepAliveTimeout: handler:, чтобы установить обработчик для выполнения периодически. Приложение может использовать этот обработчик для поддержания подключения к службе.
  4. настройте аудиосессию для обработки переходов в и из активное использование.
  5. чтобы обеспечить лучший пользовательский интерфейс на iPhone, используйте основную телефонию рамки для настройки вашего поведения по отношению к сотовому телефону звонков; см. ядро телефонии рамки ссылкой.
  6. чтобы обеспечить хорошую производительность для вашего приложения VoIP, используйте систему Платформа конфигурации для обнаружения сети изменения и разрешить приложение спать как можно больше.

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


код ниже показывает, как настроить сокет приложения для использования VoIP.

Шаг 1: Подключение к серверу

uint16_t port ;
NSString *strIp ;
char ip[20] = {0} ;
memset(ip, 0, sizeof(ip)) ;
memcpy(ip, [strIp UTF8String], [strIp length]) ;

clientSocket = socket(AF_INET, SOCK_STREAM, 0) ;
struct sockaddr_in server_addr ;
bzero(&server_addr, sizeof(server_addr)) ;
server_addr.sin_port = htons(port) ;
server_addr.sin_addr.s_addr = inet_addr(ip) ;
server_addr.sin_family = AF_INET ;

int i = connect(clientSocket, (const struct sockaddr *)&server_addr, sizeof(server_addr)) ;
if (i >= 0) {
}

код на стороне сервера может быть в среде C++, но вы можете передать clientSocket для экземпляра Objective-C это int значение.

Шаг 2: Создание и настройка потока чтения и записи

после подключения к серверу необходимо создать чтение & записать поток на основе clientSocket используя CFStreamCreatePairWithSocket() и установите свойство streams с NSStreamNetworkServiceTypeVoIP.

определите потоки чтения и записи и сохраните сильную ссылку на них. Закройте и отпустите их, когда соединение потеряно.

@property (nonatomic, strong) NSInputStream *inputStream ;
@property (nonatomic, strong) NSOutputStream *outputStream ;

затем config streams:

CFReadStreamRef readStreamRef = nil ;
CFWriteStreamRef writeStreamRef = nil ;
CFStreamCreatePairWithSocket(NULL, clientSocket, &readStreamRef, &writeStreamRef) ; // the socket must have already been connected.
_inputStream = (__bridge_transfer NSInputStream *)readStreamRef ;
_outputStream = (__bridge_transfer NSOutputStream *)writeStreamRef ;
[_inputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType] ;
[_outputStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType] ;
[_inputStream open] ;
[_outputStream open] ;

перед подключением к потоку чтения и записи убедитесь, что сокет уже подключен.

Шаг 3:Держите связи

[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{
    // the code to check if the socket is connected to server
    // if not, reconnect to server 
    // and re-set the read stream and write stream in step2
}] ;

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

потому что VoIP-приложения должны оставаться запущенными для приема входящих вызовов Система автоматически перезапускает приложение, если оно выходит с ненулевым кодом выхода. (Этот тип выхода может произойти, когда есть давление памяти и ваше приложение прекращается в результате.) Однако завершение приложения также освобождает все его сокеты, в том числе тот, который используется для поддержания подключения к службе VoIP. Поэтому, когда приложение запускается, ему всегда нужно создавать свои сокеты с нуля.

Я создал пример проекта здесь, соответствующий код на стороне сервера здесь.


поверх настройки сокета вам нужно внести некоторые изменения в информацию о приложении iOS.файл plist, где вы должны указать voip фоновый режим.

более подробную информацию можно найти здесь: Документация Apple Dev