La forma correcta de salir de la aplicación de iPhone?

Estoy progtwigndo una aplicación para iPhone, y necesito forzarlo a salir debido a ciertas acciones de usuario. Después de limpiar la memoria de la aplicación asignada, ¿cuál es el método apropiado para llamar para finalizar la aplicación?

¿Has probado la exit(0) ?

Alternativamente, [[NSThread mainThread] exit] , aunque no lo he intentado, parece ser la solución más adecuada.

En el iPhone no existe el concepto de abandonar una aplicación. La única acción que debe hacer que una aplicación se cierre es presionar el botón Inicio en el teléfono, y eso no es algo a lo que los desarrolladores tienen acceso.

Según Apple, tu aplicación no debería terminar por sí sola. Como el usuario no presionó el botón de Inicio, cualquier retorno a la pantalla de Inicio le da al usuario la impresión de que su aplicación se colgó. Esto es un comportamiento confuso y no estándar, y debe evitarse.

La salida (0) le aparece a un usuario como un locking, así que muestre un mensaje de confirmación al usuario. Después de la confirmación, suspenda (presione el botón de inicio de forma programática) y espere 2 segundos mientras la aplicación va a fondo con animación y luego salga detrás de la vista del usuario.

 -(IBAction)doExit { //show confirmation message to user UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Confirmation" message:@"Do you want to exit?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; [alert show]; } -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex != 0) // 0 == the cancel button { //home button press programmatically UIApplication *app = [UIApplication sharedApplication]; [app performSelector:@selector(suspend)]; //wait 2 seconds while app is going background [NSThread sleepForTimeInterval:2.0]; //exit app when app is in background exit(0); } } 

No es realmente una manera de abandonar el progtwig, sino una forma de obligar a la gente a dejarlo.

 UIAlertView *anAlert = [[UIAlertView alloc] initWithTitle:@"Hit Home Button to Exit" message:@"Tell em why they're quiting" delegate:self cancelButtonTitle:nil otherButtonTitles:nil]; [anAlert show]; 

Vaya a su info.plist y verifique la clave “La aplicación no se ejecuta en segundo plano”. Esta vez, cuando el usuario hace clic en el botón de inicio, la aplicación sale por completo.

Consulte las preguntas y respuestas aquí: https://developer.apple.com/library/content/qa/qa1561/_index.html

P: ¿Cómo cierro programáticamente mi aplicación de iOS?

No hay una API provista para terminar elegantemente una aplicación de iOS.

En iOS, el usuario presiona el botón Inicio para cerrar las aplicaciones. Si su aplicación tiene condiciones en las que no puede proporcionar su función prevista, el enfoque recomendado es mostrar una alerta para el usuario que indique la naturaleza del problema y las posibles acciones que el usuario podría tomar: encender WiFi, habilitar Servicios de ubicación, etc. Permitir que el usuario rescinda la aplicación a su propia discreción.

ADVERTENCIA: No llame a la función de exit . Las aplicaciones que llaman a la exit aparecerán para que el usuario se bloquee, en lugar de realizar una terminación elegante y volver a animar a la pantalla de inicio.

Además, es posible que los datos no se guarden, ya que -applicationWillTerminate: y métodos UIApplicationDelegate similares no se invocarán si llama a exit.

Si durante el desarrollo o la prueba es necesario finalizar su aplicación, se recomienda la función abort o macro assert

agregar la propiedad UIApplicationExitsOnSuspend en application-info.plist a true

Después de algunas pruebas, puedo decir lo siguiente:

  • utilizando la interfaz privada: [UIApplication sharedApplication] causará que la aplicación parezca que se bloqueó, PERO llamará a la - (void)applicationWillTerminate:(UIApplication *)application antes de hacerlo;
  • usando la exit(0); también terminará la aplicación, pero se verá “normal” (los íconos del trampolín aparecen como se esperaba, con el efecto de - (void)applicationWillTerminate:(UIApplication *)application ), PERO no llamará al - (void)applicationWillTerminate:(UIApplication *)application método de delegado de la - (void)applicationWillTerminate:(UIApplication *)application .

Mi consejo:

  1. Llame manualmente a la aplicación - (void)applicationWillTerminate:(UIApplication *)application en el delegado.
  2. exit(0); llamada exit(0); .

Su ApplicationDelegate recibe una notificación de abandono intencional por parte del usuario:

 - (void)applicationWillResignActive:(UIApplication *)application { 

Cuando recibo esta notificación, solo llamo

  exit(0); 

Lo cual hace todo el trabajo. Y lo mejor es que el propósito es dejar de fumar, por lo que no debería ser un problema llamarlo allí.

En mi aplicación de audio fue necesario salir de la aplicación después de que la gente sincronizara su dispositivo mientras la música todavía se estaba reproduciendo. Tan pronto como se completa la sincronización, recibo una notificación. Pero salir de la aplicación justo después de eso realmente se vería como un locking.

Entonces, en su lugar, establecí una bandera para REALMENTE salir de la aplicación en la siguiente acción de fondo. Lo cual está bien para actualizar la aplicación después de una sincronización.

Mi aplicación ha sido rechazada recientemente. He usado un método no documentado. Literalmente:

“Desafortunadamente no se puede agregar a la tienda de aplicaciones porque está utilizando una API privada. Se prohíbe el uso de API no públicas, que como se describe en la sección 3.3.1 del Acuerdo de licencia del progtwig para desarrolladores de iPhone:

“3.3.1 Las aplicaciones solo pueden usar API documentadas de la manera prescrita por Apple y no deben usar ni invocar ninguna API privada”.

La API no pública que se incluye en su aplicación es terminateWithSuccess ”

Apple dice:

“Advertencia: no llame a la función de salida. Las aplicaciones que llaman a la salida aparecerán para que el usuario se bloquee, en lugar de realizar una terminación elegante y volver a animar a la pantalla de inicio”.

Creo que esta es una mala suposición. Si el usuario toca un botón para salir y aparece un mensaje que dice algo así como: “La aplicación se cerrará”, no parece estar bloqueado. Apple debe proporcionar una forma válida para salir de una aplicación (no salir (0)).

Esto obtuvo una buena respuesta, pero decidió expandirse un poco:

No puede obtener su aplicación aceptada en AppStore sin leer bien las Pautas de interfaz humana de iOS de Apple. (conservan el derecho de rechazarlo por hacer algo en su contra) La sección “No salir programáticamente” http://developer.apple.com/library/ios/#DOCUMENTATION/UserExperience/Conceptual/MobileHIG/UEBestPractices/UEBestPractices. html es una guía exacta de cómo debe tratar en este caso.

Si alguna vez tiene un problema con la plataforma Apple y no puede encontrar fácilmente una solución, consulte a HIG. Es posible que Apple simplemente no quiera que lo hagas y usualmente (no soy Apple, así que no puedo garantizarlo siempre) lo dices en su documentación.

No podemos salir de la aplicación usando las funciones exit(0) , abort() , ya que Apple desaconseja firmemente el uso de estas funciones. Aunque puede usar estas funciones para fines de desarrollo o prueba.

Si durante el desarrollo o la prueba es necesario finalizar su aplicación, se recomienda la función abortar o macro assert

Encuentre este hilo de preguntas y respuestas de Apple para obtener más información.

Como uso de esta función, cree una impresión, ya que la aplicación se bloquea. Así que recibí una sugerencia como que podemos mostrar Alert con mensaje de finalización para el usuario consciente sobre el cierre de la aplicación, debido a la falta de disponibilidad de cierta funcionalidad.

Pero la guía de la interfaz humana de iOS para iniciar y detener la aplicación sugiere que nunca use el botón para cerrar o cerrar para finalizar la aplicación. En lugar de eso, están sugiriendo que muestren el mensaje adecuado para explicar la situación.

Una aplicación iOS nunca muestra una opción Cerrar o Salir. Las personas dejan de usar una aplicación cuando cambian a otra aplicación, regresan a la pantalla de inicio o ponen sus dispositivos en modo de suspensión.

Nunca abandone una aplicación iOS programáticamente. La gente tiende a interpretar esto como un choque. Si algo impide que su aplicación funcione de la manera prevista, debe informar a los usuarios sobre la situación y explicarles qué pueden hacer al respecto.

Además de la respuesta anterior, buena, solo quería agregar, piense en limpiar su memoria.

Después de que la aplicación finalice, el sistema operativo del iPhone limpiará automáticamente cualquier cosa que haya dejado su aplicación, por lo que liberar toda la memoria manualmente puede boost la cantidad de tiempo que le toma a la aplicación salir.

Hm, puede ‘tener que’ salir de la aplicación si, por ejemplo, su aplicación requiere una conexión a Internet. Puede mostrar una alerta y luego hacer algo como esto:

 if ([[UIApplication sharedApplication] respondsToSelector:@selector(terminate)]) { [[UIApplication sharedApplication] performSelector:@selector(terminate)]; } else { kill(getpid(), SIGINT); } 
 - (IBAction)logOutButton:(id)sender { //show confirmation message to user CustomAlert* alert = [[CustomAlert alloc] initWithTitle:@"Confirmation" message:@"Do you want to exit?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil]; alert.style = AlertStyleWhite; [alert setFontName:@"Helvetica" fontColor:[UIColor blackColor] fontShadowColor:[UIColor clearColor]]; [alert show]; } - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex != 0) // 0 == the cancel button { //home button press programmatically UIApplication *app = [UIApplication sharedApplication]; [app performSelector:@selector(suspend)]; //wait 2 seconds while app is going background [NSThread sleepForTimeInterval:2.0]; //exit app when app is in background NSLog(@"exit(0)"); exit(0); } } 

Usé el enfoque [[NSMutableArray new] addObject: nil] mencionado anteriormente para forzar (cerrar) la aplicación sin realizar una llamada a la función tell-exit (0).

¿Por qué? Debido a que mi aplicación utiliza la fijación de certificados en todas las llamadas de API de la red para evitar los ataques de hombre en el medio. Estos incluyen las llamadas de inicialización que realiza mi aplicación financiera al inicio.

Si la autenticación del certificado falla, toda mi inicialización llama al error y deja mi aplicación en un estado indeterminado. Permitir que el usuario vaya a su casa y luego a la aplicación no ayuda, ya que a menos que la aplicación haya sido purgada por el sistema operativo, aún no está inicializada y no es confiable.

Por lo tanto, en este caso, consideramos que es mejor hacer una alerta que informe al usuario que la aplicación está funcionando en un entorno inseguro y luego, cuando presionen “Cerrar”, fuerce a salir de la aplicación utilizando el método mencionado anteriormente.

Salir de una aplicación de otra manera que el botón de inicio es realmente un enfoque que no es iOS-esque .

Hice esta ayuda, sin embargo, que no use cosas privadas:

 void crash() { [[NSMutableArray new] addObject:NSStringFromClass(nil)]; } 

Pero todavía no está destinado a la producción en mi caso. Es para probar los informes de fallos o para reiniciar rápidamente después de un reinicio de los datos centrales. Simplemente hice que fuera seguro no ser rechazado si la función quedaba en el código de producción.

El usuario debe decidir cuándo sale una aplicación. No creo que sea una buena interacción del usuario cuando se cierra una aplicación. Por lo tanto, no hay una buena API para ello, solo el botón de inicio tiene uno.

Si hay un error: Implementarlo mejor o Notificar al usuario. Si tiene que haber un reinicio: Implementarlo mejor de Notificar al usuario.

Suena tonto, pero es una mala práctica salir de la aplicación sin dejar que el usuario decida y no lo notifique. Y como Apple tiene un botón de inicio para la interacción del usuario, no debería haber dos cosas para la misma función (salir de una aplicación).

Salir de una aplicación de otra manera

Hice esta ayuda, sin embargo, que no use cosas privadas:

Salida (0);

Puede ser apropiado salir de una aplicación si es una aplicación de larga duración que también se ejecuta en segundo plano, por ejemplo, para obtener actualizaciones de ubicación (usando la capacidad de fondo de actualizaciones de ubicación para eso).

Por ejemplo, supongamos que el usuario cierra sesión en su aplicación basada en la ubicación y empuja la aplicación hacia el fondo utilizando el botón de inicio. En este caso, su aplicación puede seguir ejecutándose, pero podría tener sentido salir por completo. Sería bueno para el usuario (libera memoria y otros recursos que no necesitan ser utilizados), y bueno para la estabilidad de la aplicación (es decir, asegurarse de que la aplicación se reinicie periódicamente cuando sea posible es una red de seguridad contra memory leaks y otra poca memoria) cuestiones).

Esto podría (aunque probablemente no debería, ver a continuación 🙂 lograrse con algo como:

 - (void)applicationDidEnterBackground:(UIApplication *)application { if (/* logged out */) { exit(0); } else { // normal handling. } } 

Como la aplicación saldrá de segundo plano , no se verá mal para el usuario, y no se parecerá a un locking, siempre que la interfaz de usuario se restaure la próxima vez que ejecute la aplicación. En otras palabras, para el usuario no se vería diferente a una terminación iniciada por el sistema de la aplicación cuando la aplicación está en segundo plano.

Aún así, sería preferible utilizar un enfoque más estándar para que el sistema sepa que la aplicación puede ser cancelada. Por ejemplo, en este caso, asegurándose de que el GPS no esté en uso al detener la solicitud de actualizaciones de ubicación, incluida la desactivación, muestre la ubicación actual en una vista de mapa, si está presente. De esta forma, el sistema se encargará de terminar la aplicación unos minutos (es decir, [[UIApplication sharedApplication] backgroundTimeRemaining] ) después de que la aplicación entre en el fondo. Esto obtendría los mismos beneficios sin tener que usar código para finalizar la aplicación.

 - (void)applicationDidEnterBackground:(UIApplication *)application { if (/* logged out */) { // stop requesting location updates if not already done so // tidy up as app will soon be terminated (run a background task using beginBackgroundTaskWithExpirationHandler if needed). } else { // normal handling. } } 

Y, por supuesto, usar la exit(0) nunca sería apropiado para la aplicación de producción promedio que se ejecuta en primer plano, según otras respuestas que hacen referencia a http://developer.apple.com/iphone/library/qa/qa2008/qa1561. html

 [[UIApplication sharedApplication] terminateWithSuccess]; 

Funcionó bien y llama automáticamente

 - (void)applicationWillTerminateUIApplication *)application delegate. 

para eliminar la advertencia de tiempo de comstackción, agregue este código

 @interface UIApplication(MyExtras) - (void)terminateWithSuccess; @end