2011-07-06 8 views
21

Estoy obteniendo un socket VOIP para ejecutar en segundo plano en una aplicación de iOS.iOS Voip Socket no se ejecutará en el fondo

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

puedo configurar mi cuenta de la siguiente 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 está configurado de esta manera:

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]; 
} 

"devolución de llamada sucedido" está recibiendo llamadas cuando recibo de datos y la aplicación es abierto, pero no si la aplicación está minimizada. Sin embargo, cuando la aplicación vuelve a subir, procesa cualquier información que recibió mientras se minimiza.

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

EDIT: No puedo probar ninguna de las respuestas porque ya no estoy trabajando en este proyecto y no tengo acceso a mac/iOs sdk. Si alguien con un problema similar encontró útil una de las siguientes respuestas, avíseme y la votaré con la mejor respuesta.

+0

+1: ¿también agregó la etiqueta "audio" en la lista? Acabo de leer la guía de programación de aplicaciones sobre la multitarea, pero parece que es algo que es irregular. Espero que tengas una respuesta. buena pregunta. –

+0

No estoy reproduciendo ningún audio (todavía), así que eso no debería marcar la diferencia. Pero lo intenté de todos modos y no funcionó. Gracias por al menos darme algo para probar, solo he estado rompiéndome la cabeza por horas. – Joel

+0

¿puedes publicar el código en tu controlador de tiempo de espera keep alive? –

Respuesta

28

Si desea que su ejecución de la aplicación de VoIP en el fondo, a excepción de los ajustes de la base en el archivo plist, necesita un socket TCP, que es propiedad se establece en VOIP, que el sistema IOS se encargará esta toma para ti , cuando su aplicación ingresa en segundo plano, todo estaba 'en reposo' excepto ese socket tcp. y si el servidor VOIP envía algunos datos pensados ​​en el socket TCP, su aplicación estará activa durante 10 segundos. durante este tiempo, puede publicar una notificación local.

Solo el zócalo Tcp puede configurarse como zócalo VOIP. Pero, como sé, la mayoría de las aplicaciones VOIP se basan en el socket UDP. si no desea separar el socket de control del socket de datos. Deberías crear otro socket tcp que se enfoque en 'despertar' tu aplicación, y por mi experiencia personal, es muy difícil mantener esta señal 'despierta' y la señal de control sip real se sincroniza, la aplicación siempre pierde la solicitud de invitación sip.

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

Otra manera sucia: mantener la aplicación despierta todo el tiempo. Como dije, cada TCP sola que la aplicación recibió pensó que el zócalo'cOP 'tcp mantendría la aplicación despierta durante 10 segundos, de modo que al final de esta duración (después de 9 segundos), puede enviar una respuesta al servidor para preguntar para otra señal, cuando llegue la siguiente señal, la aplicación estará despierta nuevamente, después de 9 segundos, envíe la respuesta nuevamente. sigue haciendo esto, tu aplicación se despertará para siempre.

+11

conocimiento dorado –

+0

@Joel: ¿Puede recibir datos de voz mientras la aplicación se ejecuta en un entorno cerrado? und. Si esta publicación es útil, actualice aquí y acepte cualquier publicación. – User97693321

+0

No estoy seguro de lo que quiere decir 'en segundo plano', si la aplicación está totalmente en segundo plano (no en llamada), solo se pueden recibir datos de tcp. –

0

Puede necesitar establecer <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 de cambiar de aplicación (la suposición es que no comenzará a grabar/reproducir música de repente)/lo que sea cuando tu aplicación esté en segundo plano).

The docs 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 puede intentar:

  • Ajuste tanto "voip" como "audio".
  • Reproducir silencio (esto podría ser más fácil de hacer con la API Audio Queue).
+0

reproducir el silencio es un truco detectado por Apple que impide que la aplicación se publique en la tienda (a menos que la aplicación proporcione la función de audio real) – Albrecht

+0

Un zócalo VIOP sería una característica de audio real, ¿o no? de este rechazo? Nunca he visto nada de eso. – Sneakyness

+0

De la primera respuesta en este hilo http://stackoverflow.com/questions/5840365/how-can-an-ios-app-keep-a-tcp-connection -alive-indefinidamente-while-in-the-backgro está la historia de una aplicación rechazada por Apple por reproducir audio silencioso: https://web.archive.org/web/20140806111426/http://tapbots.com/blog/pastebot/pastebot-music-in-background – RenniePet

5

Me quedé atrapado en el mismo escenario.
Mi problema es que he configurado más de un socket como un socket Voip.

se puede ver en Apple's documentations about voip que dicen:
"Configurar uno de tomas de la aplicación para el uso de VoIP"

supongo que sólo están despertando su aplicación de acuerdo con un solo zócalo.

todas las demás cosas mencionado sigue siendo correcta:

  • kCFStreamNetworkServiceTypeVoIP
  • '' info.plist UIBackgroundModes: VoIP, audio
  • 'información.plist' UIRequiresPersistentWifi clave
  • no funcionará durante simulador
0

¿Tiene una 'applicationDidEnterBackground:' delegado en su 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 modos de fondo. No necesita implementar nada en él.

p. Ej.

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

Este es solo un método del protocolo UIApplicationDelegate. Es opcional y no está relacionado con esta pregunta. – gurooj

3

También estoy enfrentando el mismo problema. pero en mi caso todo está funcionando 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, mi socket funciona incluso si cambio manualmente mi red para lo siguiente.

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

Después de un tiempo, dejar que decir una vez más im tratando conmutador de red de forma manual. no hay nada, parece que mi aplicación no detecta cambios en la red. Leí el siguiente documento de Apple. Estoy seguro de hacer el mal (o) disunderstood el paso 3 y 6.

Hay varios requisitos para implementar una aplicación de VoIP:

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

  1. Configure uno de los enchufes 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 ejecutará periódicamente.Su aplicación puede usar este controlador para mantener su conexión de servicio.

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

5. Para asegurar una mejor experiencia de usuario en el iPhone, utilice el marco básico de telefonía para ajustar su comportamiento en relación a las llamadas telefónicas basadas en células; vea Referencia del Marco de Telefonía Básica.

  1. para asegurar un buen rendimiento para su aplicación VoIP, utilizar el marco de configuración del sistema para detectar cambios en la red y permitir su aplicación a dormir tanto como sea posible.
+0

Estoy enfrentando el mismo problema. ¿Recibió alguna razón para no recibir una devolución de llamada en el cambio de red? Creo que cuando la aplicación entra en segundo plano, ios pone la aplicación en estado Suspendido, es por eso que la aplicación no puede detectar cambios en la red. –

Cuestiones relacionadas