“Le windows dell’applicazione dovrebbero avere un controller di visualizzazione root al termine dell’avvio dell’applicazione” errore durante l’esecuzione di un progetto con Xcode 7, iOS 9

Dopo aver eseguito la funzione

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

c’è un incidente:

  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 

Questo progetto è un vecchio progetto, cosa dovrei fare per farlo build ed eseguire con Xcode 7 e iOS 9?

Dal tuo messaggio di errore:

Si prevede che le windows dell’applicazione abbiano un controller di visualizzazione radice al termine dell’avvio dell’applicazione

Quanti anni ha questo “vecchio” progetto? Se è più di qualche anno, hai ancora:

 [window addSubview:viewController.view]; 

Dovresti invece sostituirlo con:

 [window setRootViewController:viewController]; 

Se hai già impostato rootViewController della tua self.window nel tuo app delegato e ricevi ancora questo errore in fase di esecuzione, probabilmente hai più di una finestra nella tua UIApplication, una delle quali potrebbe non avere un rootViewController associato. È ansible scorrere le windows dell’app e associare una viewController vuota al suo rootViewController per correggere l’errore che si sta verificando.

Ecco un codice che scorre attraverso le windows dell’app e associa un ViewController vuoto a rootViewController se manca una finestra.

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

Aggiornamento: Apparentemente c’è una finestra dedicata alla barra di stato che in genere causa questo problema. Il codice sopra dovrebbe correggere questo errore.

XCODE 7 richiede che tutti i Windows debbano avere un rootViewController Puoi usare facilmente:

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

Funziona bene se hai bisogno di usare solo UIWindow (per esempi facili da qualsiasi tutorial – prima di Xcode 7)!

Sembra che da iOS 9.1 (?) O Xcode 7.1 qualsiasi UIWindow istanziato durante l’ application(_:didFinishLaunchingWithOptions:) bisogno di avere un set rootViewController prima di uscire da quel metodo.

In precedenza era sufficiente che solo la finestra principale avesse un set di rootViewController durante quel metodo. Ora qualsiasi istanza di UIWindow deve avere una proprietà rootViewController valida.

Il colpevole potrebbe essere il tuo codice personale se usi UIWindow e qualsiasi altra libreria di terze parti che tenta di inizializzare una nuova istanza UIWindow durante questo periodo (come gli overlay dei messaggi della barra di stato, ecc.).

NOTA : si ottiene lo stesso errore anche se non si imposta rootViewControler nella finestra principale o se lo storyboard non è impostato correttamente. Menzionando questo come una nota a margine dal momento che questi casi sono abbastanza ovvi e semplici da risolvere.

Questo mi ha morso anche oggi e mi è costato un paio d’ore per ripararlo: la mia App ha la finestra in un “MainWindow.xib”, completo di controller di navigazione e controller di visualizzazione root, che sono stati tutti istanziati automaticamente nell’ordine corretto , con Xcode 6 e iOS8.

Su iOS9, l’app funziona ancora correttamente quando scaricata dall’App Store, ma non quando è stata creata di recente con Xcode 7 ed è in esecuzione su iOS 9. Nel momento in cui il delegato dell’app esegue il suo applicationDidBecomeActive: metodo il controller della vista radice ora non è caricato, poiché era prima! Ciò ha fatto sì che il controller della vista radice non rispondesse alla chiamata al mio codice di stato di ripristino.

Ho risolto questo problema istanziando il controller della vista radice da solo, nel codice, e ripristinando il suo stato da viewDidLoad, in modo esplicito.

Devi impostare la proprietà rootviewcontroller di ogni finestra nella tua app

Basta impostare rootViewController su navigationController che è il tuo UIViewController in app-delegate.rb come il mio codice qui sotto. Sono nuovo nel ruby ma spero che questo abbia aiutato …

 rootViewController = UIViewController.alloc.init @window.rootViewController = navigationController 

Sono arrivato a questo problema con un’app che ho ereditato di più. Dopo aver verificato che lo storyboard fosse configurato correttamente come interfaccia principale dell’app e che lo storyboard avesse un RootViewController, stavo ancora ottenendo il crash.

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

Quello che ho scoperto dopo alcune ulteriori indagini è che il crash è stato causato da qualche logica di visualizzazione (SVProgressHud) chiamata in - (void)applicationDidBecomeActive:(UIApplication *)application . Questo sembra essere un nuovo comportamento in Xcode7, ma per quanto posso dire SVProgressHud stava facendo riferimento a rootviewcontroller prima che fosse impostato dallo storyboard. In definitiva l’aggiornamento di SVProgressHud a 2.0 ha risolto il bug.

Ho un progetto precedente che funzionava su iOS 8 ma non su iOS 9. Se l’interfaccia principale è impostata su MainWindow.xib, aggiornala a uno storyboard. Questo lo ha risolto per me:

  1. Crea un nuovo progetto, l’applicazione Single View va bene.
  2. Copia il file Main.storyboard nel tuo progetto, oppure puoi semplicemente crearne uno tuo.
  3. Apri le impostazioni del progetto e imposta l’interfaccia principale su Main.storyboard Imposta la tua interfaccia principale su Main.storyboard

Soluzione Swift 2 che ha funzionato per me:

Inserisci il codice qui sotto in AppDelegate -> didFinishLaunchingWithOptions

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