Error "Se espera que las ventanas de la aplicación tengan un controlador de vista raíz al final del inicio de la aplicación" al ejecutar un proyecto con Xcode 7, iOS 9

89

Después de ejecutar la función

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

hay un accidente:

 Assertion failure in 
-[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-

 *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', `enter code here`reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000109377885 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000108df0df1 objc_exception_throw + 48
    2   CoreFoundation                      0x00000001093776ea +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x0000000108a42bb1 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
    4   UIKit                               0x000000010760e350 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2875
    5   UIKit                               0x000000010760b73f -[UIApplication workspaceDidEndTransaction:] + 188
    6   FrontBoardServices                  0x000000010b87fd7b FrontBoardServices + 163195
    7   FrontBoardServices                  0x000000010b880118 FrontBoardServices + 164120
    8   CoreFoundation                      0x00000001092a20f1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    9   CoreFoundation                      0x0000000109297eac __CFRunLoopDoSources0 + 556
    10  CoreFoundation                      0x0000000109297363 __CFRunLoopRun + 867
    11  CoreFoundation                      0x0000000109296d78 CFRunLoopRunSpecific + 488
    12  UIKit                               0x000000010760b091 -[UIApplication _run] + 402
    13  UIKit                               0x000000010760f79b UIApplicationMain + 171
    14  bbwc                                0x00000001037a9998 main + 344
    15  libdyld.dylib                       0x000000010a45ca05 libdyld.dylib + 10757
    16  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Este proyecto es un proyecto antiguo, ¿qué debo hacer para que se compile y se ejecute con Xcode 7 e iOS 9?

andrew wang
fuente
Dado que Xcode 7 es una versión beta, probablemente debería volver a Xcode 6 para cualquier trabajo de desarrollo serio.
Paul R
hola, estoy recibiendo este eroor: - *** Error de afirmación en - [UIApplication _runWithMainScene: transiciónContext: finalización:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 cómo resolver esto
Akash Raghani

Respuestas:

175

De su mensaje de error:

Se espera que las ventanas de la aplicación tengan un controlador de vista raíz al final del inicio de la aplicación

¿Qué edad tiene este proyecto "antiguo"? Si son más de unos pocos años, todavía tiene:

[window addSubview:viewController.view];

En su lugar, debería reemplazarlo con:

[window setRootViewController:viewController];
James Webster
fuente
1
Tengo el mismo problema y creo que es un problema de iOS 9. Mi proyecto funciona en iOS 7 y 8. Por alguna razón, la vista del guión gráfico no está configurada correctamente.
David Snabel-Caunt
3
Muchas gracias . la respuesta está en el mensaje de error: "Ventanas de la aplicación". Encuentro que hay dos ventanas en mi proyecto, una es ventana normal, la otra es un modual de terceros llamado
andrew wang
3
MTStatusBarOverlay y no tiene un RootViewController, iOS9 requiere que todas las ventanas tengan un rootViewController.
Andrew Wang
1
Sí, finalmente encontré el mismo problema. Mi aplicación tiene una ventana adicional que no tiene un controlador de vista raíz.
David Snabel-Caunt
1
Encontré la solución que me funciona: stackoverflow.com/a/32719949/1881895
barrast
37

Si ya ha configurado el rootViewController de su self.window en el delegado de su aplicación y sigue recibiendo este error en tiempo de ejecución, entonces probablemente tenga más de una ventana en su UIApplication, una de las cuales puede no tener un rootViewController asociado. Puede recorrer las ventanas de su aplicación y asociar un viewController vacío a su rootViewController para corregir el error que está recibiendo.

Aquí hay un código que recorre las ventanas de la aplicación y asocia un ViewController vacío al rootViewController si falta una ventana.

NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows) {
    NSLog(@"window: %@",window.description);
    if(window.rootViewController == nil){
        UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
        window.rootViewController = vc;
    }
}

Actualización: Aparentemente, hay una ventana dedicada a la barra de estado que generalmente causa este problema. El código anterior debería corregir este error.

Bms270
fuente
2
¡¡Gracias!! Este resultó ser el problema para mí. Había configurado el controlador de vista principal, pero la aplicación tenía una segunda ventana que no conocía.
n13
Tan sólido ... no soy un novato y este me atrapó al actualizar a Xcode 7.1 con iOS 9.1 ... la barra de estado tiene una ventana dedicada ... ¡¿por supuesto ?! Oculto la barra de estado si eso significa algo para alguien.
whyoz
Vaya, 2 de cada 12 de mis aplicaciones se bloquearon para la revisión de la aplicación y esto parece solucionarlo.
Andrew Smith
Funcionó muy bien !! Me encanta "Aparentemente, hay una ventana dedicada a la barra de estado que generalmente causa este problema". NO lo vi venir.
eGanges
1
Este método puede hacer que viewDidLoad y viewWillAppear sean llamados dos veces en su rootViewController. Si tiene una ventana de inicio manual, verifique su plist y asegúrese de NO tener Window.xib definido como el "Nombre base del archivo de nib principal" si ve cosas llamadas dos veces después de usar esta solución. Entonces solo necesita eliminar este código y establecerRootViewController como lo haría normalmente.
whyoz
21

XCODE 7 requiere que todos los Windows deben tener un rootViewController. Puede usarlo fácilmente:

UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
self.window.rootViewController = vc;

¡Funciona bien si solo necesita usar UIWindow (para ejemplos sencillos de cualquier tutorial, antes de Xcode 7)!

Enviado
fuente
¡Bienvenido a Stack Overflow! Considere editar su publicación para agregar más explicaciones sobre lo que hace su código y por qué resolverá el problema. Una respuesta que en su mayoría solo contiene código (incluso si está funcionando) generalmente no ayudará al OP a comprender su problema.
SuperBiasedMan
Gracias, eso evitó mi advertencia de iOS ~ 3–8 => falla de iOS 9, pero dio una advertencia al analizador estático sobre una fuga. Así que moví la declaración a la interfaz en el encabezado, con la asignación en applicationDidFinishLaunching. Luego agregué [vc release] a dealloc.
Flash Sheridan
13

Parece que desde iOS 9.1 (?) O Xcode 7.1, cualquier UIWindowinstanciado durante application(_:didFinishLaunchingWithOptions:)necesita tener un rootViewControllerconjunto antes de abandonar ese método.

Anteriormente, era suficiente que solo la ventana principal tuviera un rootViewControllerconjunto durante ese método. Ahora, cualquier UIWindowinstancia debe tener una rootViewControllerpropiedad válida .

El culpable aquí podría ser su propio código si utiliza UIWindowy también cualquier otra biblioteca de terceros que intente inicializar una nueva UIWindowinstancia durante este tiempo (como superposiciones de mensajes de la barra de estado, etc.).

NOTA : También obtiene el mismo error si no configura el rootViewControleren su ventana principal o si su guión gráfico no está configurado correctamente. Mencionar esto como una nota al margen, ya que esos casos son bastante obvios y fáciles de solucionar.

lipka
fuente
Eres brillante: D, gracias hombre, acabo de comentar la inicialización de la ventana y todo está bien ahora
mohammad alabid
3

Esto también me ha mordido hoy, y me costó algunas horas arreglarlo: mi aplicación tiene la ventana en un "MainWindow.xib", completo con el controlador de navegación y el controlador de vista raíz que lo acompaña, que se instanciaron automáticamente en el orden correcto , con Xcode 6 y iOS8.

En iOS9, esa aplicación aún funciona bien cuando se descarga de la AppStore, pero no cuando se crea nuevamente con Xcode 7 y se ejecuta en iOS 9. En el momento en que el delegado de la aplicación está ejecutando su método applicationDidBecomeActive: el controlador de vista raíz ahora no lo está cargado, ya que solía ser antes! Eso hizo que el controlador de vista raíz perdiera la llamada a mi código de estado de restauración.

Solucioné esto creando una instancia del controlador de vista raíz yo mismo, en código, y restaurando su estado desde viewDidLoad, explícitamente.

RickJansen
fuente
2

Debe configurar la propiedad rootviewcontroller de cada ventana en su aplicación

alla
fuente
Tu respuesta me ayudó
Aznix
2

Tengo un proyecto anterior que funcionó en iOS 8 pero no en iOS 9. Si su interfaz principal está configurada en MainWindow.xib, actualícela a un guión gráfico. Esto me lo arregló:

  1. Cree un nuevo proyecto, la aplicación de vista única está bien.
  2. Copie el archivo Main.storyboard a su proyecto, o puede crear el suyo propio.
  3. Abra la configuración del proyecto y configure su interfaz principal en Main.storyboard Configure su interfaz principal en Main.storyboard
Adrian
fuente
1

Simplemente configure su rootViewController en navigationController, que es su UIViewController en el app-delegate.rb como mi código a continuación. Soy nuevo en ruby ​​pero espero que esto ayude ...

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController
BigPun86
fuente
1

Entré en este problema con una aplicación que heredé más o menos. Después de verificar que el guión gráfico estaba configurado correctamente como la interfaz principal de la aplicación y que el guión gráfico tenía un RootViewController, todavía recibía el bloqueo.

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'

Lo que descubrí después de investigar más a fondo que el bloqueo estaba siendo causado por alguna lógica de vista (SVProgressHud) - (void)applicationDidBecomeActive:(UIApplication *)application. Este parece ser un comportamiento nuevo en Xcode7, pero por lo que puedo decir, SVProgressHud estaba haciendo referencia al controlador rootview antes de que lo estableciera el guión gráfico. En última instancia, la actualización de SVProgressHud a 2.0 solucionó el error.

Bueno
fuente
0

Solución Swift 2 que funcionó para mí:

Inserte el código siguiente en AppDelegate -> didFinishLaunchingWithOptions

self.window!.rootViewController = storyboard.instantiateViewControllerWithIdentifier("YourRootViewController") as? YourRootViewControllerClass

Fox5150
fuente