Forzar la aplicación iphone para reiniciar programáticamente

Estoy intentando que mi aplicación de iPhone se reinicie mediante progtwigción cuando se presiona el botón Cerrar sesión.

¿Alguien ha recibido una muestra de código para compartir? He leído que es posible modificando el archivo main.m pero no pude encontrar ningún código relacionado con esto.

Cualquier ayuda sería apreciada.

En primer lugar, aunque es posible forzar el cierre de su aplicación, Apple no permite esto y será rechazado. Incluso si no fue rechazado, no hay forma de reiniciar su aplicación una vez que se haya eliminado. Solo necesitas encontrar la forma de restablecer tu aplicación a través de tu código, como dijo Jason Coco . Podría ser más trabajo, pero vale la pena no ser rechazado por Apple.

Nota:

Aunque esto ha sido respondido como ‘no posible’, creo que es una pregunta válida para un desarrollador de iOS nuevo y hay algo que pueden hacer, que es probablemente lo que quieren.

Hay una manera de ‘reiniciar’ tu aplicación desde la perspectiva del usuario que técnicamente no se reinicia o sale de la aplicación de iOS. Como se señala en otras respuestas, una aplicación de iOS nunca debe cerrarse explícitamente porque no está permitida en iOS.

Mi respuesta:

Si desea que su aplicación regrese al estado en el que se encontraba en el momento del lanzamiento, no es posible al 100%, pero le explicaré la forma de lograr la mayor parte del camino que debería ser suficiente para todos los propósitos válidos.

Lo primero que debe hacer es volver a crear su controlador de vista raíz. Recomiendo hacer esto desde un método en el delegado de aplicaciones como este:

 - (void)resetAppToFirstController { self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil]; } 

En muchos casos, esto será suficiente, pero cualquier aplicación-estado que tengas también debe reiniciarse con este método. Por ejemplo, cierre la sesión de un usuario, restablezca cualquier estado no persistente y anule (suelte) todos los objetos que pueda. Este método también se puede usar para crear inicialmente su primer controlador de vista desde la application:didFinishLaunchingWithOptions .

Clases de Framework y Singletons:

No podrá restablecer por completo el estado de ninguno de los marcos individuales o instancias por aplicación, como estas:

 [UIApplication sharedApplication]; [NSNotificationCenter defaultCenter]; [NSUserDefaults standardUserDefaults]; [UIScreen screens]; // etc... 

Probablemente esté bien ya que no debería almacenar ningún estado no persistente en estos de todos modos (excepto NSNotificationCenter , pero todos los observadores registrados deberían haber sido eliminados cuando se liberaron los objetos). Si desea inicializar o restablecer cualquier estado del marco, puede hacerlo en el mismo método resetAppToFirstController . De todos modos, no debería haber necesidad de volver a crear estos, o el objeto window .

Si tiene uno de sus propios singletons, puede volver a crearlos almacenándolos en una clase de titular único (que es en sí mismo un singleton real). Conceptualmente, esta es una clase singleton simple con propiedades para cada uno de sus otros singletons y un método de reset para anularlos y liberarlos todos. Sus otros singletons deberían usar esta clase (en lugar de una variable estática o global) para almacenar instancias singleton. Tenga cuidado si usa bibliotecas de terceros, ya que también pueden emplear singletons y deberá asegurarse de que también utilicen su único titular para que pueda restablecerlas según sea necesario. Creo que esta técnica es una buena práctica de todos modos, porque en algunos casos (por ejemplo, pruebas unitarias) desea que los objetos que normalmente son únicos se vayan y se reinicien a un estado prístino. Sin embargo, no desea acoplar las implementaciones de singleton con su propietario de singleton, por lo que una buena forma de implementar esto es usar un NSMutableDictionary como un objeto asociado en [UIApplication sharedApplication] con los nombres de clase singleton como claves. Sin embargo, me estoy saliendo un poco del tema, ya que esta es una técnica más avanzada más allá del scope de esta pregunta.


Lo anterior debería ser suficiente para ‘reiniciar’ su aplicación en lo que respecta al usuario. Incluso puede mostrar la pantalla de presentación de nuevo si lo desea como su primer controlador de visualización.

prueba esto, funciona para mí.

 -(void)restart { MyAppDelegate *appDelegate = (MyAppDelegate *)([UIApplication sharedApplication].delegate); [appDelegate.navigationController popToRootViewControllerAnimated:NO]; UIViewController *topViewController = appDelegate.navigationController.topViewController; Class class = [topViewController class]; NSString *nibName = topViewController.nibName; UIViewController *rootViewcontroller = (UIViewController *)([[class alloc] initWithNibName:nibName bundle:nil]); [appDelegate.navigationController.view removeFromSuperview]; appDelegate.navigationController.viewControllers = [NSArray arrayWithObject:rootViewcontroller]; [appDelegate.window addSubview:appDelegate.navigationController.view]; [appDelegate.window makeKeyAndVisible]; } 

C objective:

 exit(0); 

Rápido:

 exit(0) 

Tengo esto en 2 aplicaciones en vivo y no han sido rechazadas. Una de mis aplicaciones incluso tiene esta línea de código como característica en la página de inicio de mi aplicación. Está ubicado en la esquina superior derecha, donde el botón twittear está en Twitter. Así que no te preocupes por el rechazo de Apple a menos que parezca un locking inesperado.

enter image description here

Aquí es cómo puedes hacer esto en un simulador usando una API privada:

  NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@://%@", scheme, endpointString]]; Class pClass = NSClassFromString(@"BKSSystemService"); id service = [[pClass alloc] init]; SEL pSelector = NSSelectorFromString(@"openURL:application:options:clientPort:withResult:"); NSMethodSignature *signature = [service methodSignatureForSelector:pSelector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; invocation.target = service; NSString *app = @"com.apple.mobilesafari"; [invocation setSelector:pSelector]; [invocation setArgument:&URL atIndex:2]; [invocation setArgument:&app atIndex:3]; unsigned int i = [service performSelector:NSSelectorFromString(@"createClientPort")]; [invocation setArgument:&i atIndex:5]; [invocation invoke]; exit(0); 

Esto también debería funcionar en aplicaciones jailbreak con los derechos adecuados.

Para otras aplicaciones, se puede usar una página html simple:

  NSString *format = @"https://dl.dropboxusercontent.com/s/rawt1ov4nbqh4yd/launchApp.html?scheme=%@&URL=%@"; NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:format, scheme, endpointString]]; [[UIApplication sharedApplication] openURL:URL]; exit(0); 

Desafortunadamente, la conexión a internet es necesaria en este caso.

Salgo durante -applicationWillResignActive: si la aplicación está en la pantalla de inicio y Apple la ha aceptado durante años. Para el usuario, no se verá como un locking. La próxima vez que el usuario inicie la aplicación desde el ícono. Un control adicional que no salga de la aplicación si se lanzó hoy podría ser útil para la experiencia del usuario en algunos casos.

 - (void)applicationWillResignActive:(UIApplication *)application { // called if phone-call comes in! if([gameController isGameFinished]) exit(0); }