tutorial gratis español curso aprende objective-c ios4 voip background-process cfreadstream

objective-c - gratis - swift 4 tutorial español



iOS Voip Socket no se ejecutará en segundo plano (5)

Estoy obteniendo un socket VOIP para ejecutarse en segundo plano en una aplicación iOS.

Mi conexión funciona bien, pero no se activará cuando mi aplicación pase al fondo. Sin embargo, si abro la copia de seguridad de la aplicación, responde a los mensajes que recibió mientras estaba dormida.

Configuré mi flujo de esta manera:

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef) @"test.iusealocaltestserver.com", 5060, &myReadStream, &myWriteStream); CFReadStreamSetProperty ( myReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP ); CFSocketNativeHandle native; CFDataRef nativeProp = CFReadStreamCopyProperty(myReadStream, kCFStreamPropertySocketNativeHandle); CFDataGetBytes(nativeProp, CFRangeMake(0, CFDataGetLength(nativeProp)), (UInt8 *)&native); CFRelease(nativeProp); CFSocketRef theSocket = CFSocketCreateWithNative(kCFAllocatorDefault, native, 0, NULL, NULL); CFSocketGetContext(theSocket,&theContext); CFOptionFlags readStreamEvents = kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered | kCFStreamEventOpenCompleted; CFReadStreamSetClient(myReadStream, readStreamEvents, (CFReadStreamClientCallBack)&MyCFReadStreamCallback, (CFStreamClientContext *)(&theContext)); CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

Entonces mi devolución de llamada se configura así:

static void MyCFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void *pInfo); static void MyCFReadStreamCallback (CFReadStreamRef stream, CFStreamEventType type, void *pInfo) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSLog(@"Callback Happened"); [pool release]; }

Se recibe una llamada de "Devolución de llamada" cuando recibo datos y la aplicación está abierta, pero no lo hace si la aplicación está minimizada. Sin embargo, cuando la aplicación vuelve a funcionar, procesa los datos que recibió al minimizarlos.

He añadido la etiqueta voip a la info.plist. Mi CFReadStreamSetProperty devuelve true. Estoy ejecutando en un dispositivo no un simulador. Todavía no funciona, así que no sé cuál podría ser mi problema. Probablemente solo hice algo tonto, pero casi no hay nada en línea para verificar mi código.

EDITAR: No puedo probar ninguna de las respuestas porque ya no estoy trabajando en este proyecto y no tengo acceso a un mac / iOs sdk. Si alguien con un problema similar encontró útil alguna de las respuestas a continuación, hágamelo saber y votaré por la mejor respuesta.


¿Tiene un ''applicationDidEnterBackground:'' en su delegado de aplicación? Estoy bastante seguro de que he leído en algún lugar (que no puedo encontrar), que necesita tenerlo definido para que ios reconozca que admite los modos de fondo. No necesitas implementar nada en él.

p.ej

- (void)applicationDidEnterBackground:(UIApplication *)application { }


Es posible que deba configurar <key>UIBackgroundModes</key><array><string>audio</string></array> en Info.plist, y debe asegurarse de que la sesión de audio esté activa / en ejecución / lo que sea antes cambia de aplicación (se supone que no comenzará a grabar / reproducir música repentinamente / lo que sea cuando su aplicación esté en segundo plano).

Los documentos dicen que "audio" le permite reproducir audio en segundo plano, pero presumiblemente esto también se aplica a la grabación de audio. Si no funciona, hay algunas cosas que puedes probar:

  • Establecer tanto "voip" y "audio".
  • Reproducir silencio (esto podría ser más fácil de hacer con la API de cola de audio).

Si desea que su aplicación VOIP se ejecute en segundo plano, excepto las configuraciones básicas en el archivo plist, necesita un socket TCP cuya propiedad esté configurada para VOIP, de lo que el sistema iOS se encargará de este zócalo, cuando su aplicación ingrese el fondo. cada cosa era ''dormir'' excepto ese zócalo del tcp. y si el servidor VOIP envía algunos datos pensando en el socket TCP, su aplicación se activará durante 10 segundos. Durante este tiempo, puede publicar una notificación local.

Sólo el zócalo de Tcp se puede establecer como zócalo de VOIP. Pero por lo que sé, la mayoría de las aplicaciones VOIP se basan en el socket UDP. si no desea separar el zócalo de control del zócalo de datos. Debería crear otro zócalo TCP que se centre en "despertar" su aplicación, y desde mi experiencia personal, es muy difícil mantener esta señal de "vigilia" y la señal de control de sip real se sincroniza, la aplicación siempre pierde la solicitud de invitación de sip.

Por lo tanto, la mejor manera es separar el control SIP del zócalo de datos UDP, conviértalo en un zócalo tcp, esta es la mejor solución, pero nunca use el zócalo tcp para transferir datos de voz.

Otra forma sucia: mantener la aplicación despierta todo el tiempo. Como dije, cada TCP que la aplicación recibió pensó que el socket tcp ''VOIP'' mantendrá la aplicación activa durante 10 segundos, por lo que al final de esta duración (después de 9 segundos), puede enviar una respuesta al servidor para solicitar otra señal, cuando la siguiente señal llegó, la aplicación volverá a estar activa, luego de 9 segundos, enviará la respuesta nuevamente. sigue haciendo esto, tu aplicación se despertará para siempre.


También estoy enfrentando el mismo problema. pero en mi caso todo funciona bien, a menos que ocurran cambios en la red. Utilicé la clase de "accesibilidad" de Apple para detectar cambios en la red. si la aplicación está en segundo plano hasta que mi zócalo esté funcionando, incluso si cambié manualmente mi red por lo siguiente.

  1. wifi -> 3g
  2. 3g -> wifi

Después de algún tiempo, digamos otra vez que estoy intentando cambiar de red manualmente. nada está bien, parece que mi aplicación no está detectando cambios en la red. Leí el siguiente documento de Apple. Estoy seguro de hacer mal (o) malinterpretado los pasos 3 y 6.

Hay varios requisitos para implementar una aplicación VoIP:

1. Agregue la clave UIBackgroundModes al archivo Info.plist de su aplicación. Establezca el valor de esta clave en una matriz que incluya la cadena voip.

  1. Configure uno de los sockets de la aplicación para el uso de VoIP.

  2. Antes de pasar al segundo plano, llame al método setKeepAliveTimeout: handler: para instalar un controlador que se ejecute periódicamente. Su aplicación puede usar este controlador para mantener su conexión de servicio.

  3. Configure su sesión de audio para manejar las transiciones hacia y desde el uso activo.

5. Para garantizar una mejor experiencia de usuario en el iPhone, use el marco de Telefonía Central para ajustar su comportamiento en relación con las llamadas telefónicas basadas en celulares; Ver Referencia del Marco de Telefonía Core.

  1. Para garantizar un buen rendimiento de su aplicación VoIP, use el marco de configuración del sistema para detectar cambios en la red y permita que su aplicación se duerma lo más posible.

Yo estaba atrapado con el mismo escenario exacto.
Mi problema fue que configuré más de un socket como un socket Voip .

Puedes ver en la documentación de Apple sobre voip que dicen:
"Configure uno de los sockets de la aplicación para el uso de VoIP"

Supongo que solo están despertando tu aplicación de acuerdo con un solo zócalo.

todas las demás cosas mencionadas siguen siendo correctas:

  • kCFStreamNetworkServiceTypeVoIP
  • ''info.plist'' UIBackgroundModes: voip, audio
  • ''info.plist'' UIRequiresPersistentWifi clave
  • NO funcionará sobre el simulador