tarda - Forzar la aplicación de iPhone para reiniciar programáticamente
itunes esta descargando el software para el iphone cuanto tarda (6)
Estoy intentando que mi aplicación de iPhone se reinicie programáticamente cuando se presiona el botón Cerrar sesión.
¿Alguien tiene un ejemplo 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.
Aquí es cómo puedes hacer esto en el simulador usando la 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 con jailbreak con los derechos adecuados.
Para otras aplicaciones se puede utilizar la 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, en este caso se necesita conexión a internet.
C objetivo:
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 una característica en la página de inicio de mi aplicación. Está ubicado en la esquina superior derecha, donde el botón de tweet está en Twitter. Así que no te preocupes por el rechazo de Apple a menos que parezca una caída inesperada.
prueba esto, funciona para mi
-(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];
}
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 crash. La próxima vez que el usuario inicie la aplicación desde el icono. Una verificación adicional que no cierre 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);
}
Nota:
Aunque esto se ha respondido como "no es posible", creo que es una pregunta válida para un nuevo desarrollador de iOS y hay algo que pueden hacer que es probablemente lo que quieren.
Hay una manera de "reiniciar" su aplicación desde la perspectiva del usuario que no está técnicamente reiniciando o saliendo de la aplicación iOS. Como se señaló en otras respuestas, una aplicación de iOS nunca debería cerrarse explícitamente porque esto no está permitido en iOS.
Mi respuesta:
Si desea que su aplicación regrese al estado en el que se encontraba en el lanzamiento, esto no es 100% posible, pero le explicaré una forma de obtener la mayor parte del camino que debería ser suficiente para todos los fines 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 la aplicación como este:
- (void)resetAppToFirstController
{
self.window.rootViewController = [[MyMainViewController alloc] initWithNibName:nil bundle:nil];
}
En muchos casos, esto será suficiente, pero cualquier estado de aplicación que tenga también debería restablecerse en este método. Por ejemplo, cierre la sesión de un usuario, restablezca cualquier estado no persistente y anule (libere) 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 marco y singletons:
No podrá restablecer completamente el estado de cualquier instancia de marco o instancia por aplicación, como estas:
[UIApplication sharedApplication];
[NSNotificationCenter defaultCenter];
[NSUserDefaults standardUserDefaults];
[UIScreen screens];
// etc...
Probablemente esté bien, ya que de todos modos no debería estar almacenando ningún estado no persistente (excepto NSNotificationCenter
, pero todos los observadores registrados deberían haberse eliminado 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 de la window
.
Si tiene alguno de sus propios singletons, puede recrearlos almacenándolos en una clase de titular de singleton (que en sí mismo es un singleton real). Conceptualmente, esta es una clase simple de singleton con propiedades para cada uno de sus otros singletons y un método de reset
para anularlos y liberarlos a todos. Sus otros singletons deben usar esta clase (en lugar de una variable estática o global) para almacenar instancias de singleton. Tenga cuidado si utiliza bibliotecas de terceros, ya que también pueden emplear singletons y tendrá que asegurarse de que también usen su titular de singleton para poder 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 de unidad) usted desea que los objetos que normalmente son singletes desaparezcan y se reinicialicen a un estado prístino. Sin embargo, no desea unir las implementaciones de singleton con su titular de singleton, por lo que una buena manera de implementar esto es mediante el uso de un NSMutableDictionary
como objeto asociado en [UIApplication sharedApplication]
con los nombres de las clases de singleton como claves. Sin embargo, me voy al tema un poco, ya que esta es una técnica más avanzada que va más allá del alcance de esta pregunta.
Lo anterior debería ser suficiente para "reiniciar" su aplicación en lo que concierne al usuario. Incluso puede volver a mostrar la pantalla de inicio si desea que sea su primer controlador de visualización.
En primer lugar, aunque es posible forzar la eliminación de su aplicación, Apple no lo permite y será rechazado. Incluso si no fue rechazado, no hay manera de reiniciar tu aplicación una vez que se ha eliminado. Solo necesita encontrar una manera de restablecer su aplicación a través de su código, como dijo Jason Coco
. Podría ser más trabajo, pero vale la pena no ser rechazado por Apple.