Erreur "Les fenêtres d'application devraient avoir un contrôleur de vue racine à la fin du lancement de l'application" lors de l'exécution d'un projet avec Xcode 7, iOS 9

89

Après avoir exécuté la fonction

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

il y a un crash:

 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

Ce projet est un ancien projet, que dois-je faire pour le faire construire et fonctionner avec Xcode 7 et iOS 9?

andrew wang
la source
Puisque Xcode 7 est une version bêta, vous devriez probablement revenir à Xcode 6 pour tout travail de développement sérieux.
Paul R
bonjour je reçois cette erreur: - *** Échec d'assertion dans - [UIApplication _runWithMainScene: transitionContext: completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 comment résoudre ce problème
Akash Raghani

Réponses:

175

De votre message d'erreur:

Les fenêtres d'application doivent avoir un contrôleur de vue racine à la fin du lancement de l'application

Quel âge a ce "vieux" projet? Si c'est plus de quelques années, avez-vous toujours:

[window addSubview:viewController.view];

Vous devriez plutôt le remplacer par:

[window setRootViewController:viewController];
James Webster
la source
1
J'ai le même problème et je pense que c'est un problème iOS 9. Mon projet fonctionne sous iOS 7 et 8. Pour une raison quelconque, la vue du storyboard n'est pas définie correctement.
David Snabel-Caunt
3
Merci beaucoup . la réponse est dans le message d'erreur: "Fenêtres d'application" Je trouve qu'il y a deux fenêtres dans mon projet, l'une est normale widdow, l'autre est un modual tiers appelé
andrew wang
3
MTStatusBarOverlay et il n'a pas de RootViewController, iOS9 nécessite que toute la fenêtre doit avoir un rootViewController.
andrew wang
1
Oui, j'ai finalement trouvé le même problème. Mon application a une fenêtre supplémentaire qui n'a pas de contrôleur de vue racine.
David Snabel-Caunt
1
J'ai trouvé la solution qui fonctionne pour moi: stackoverflow.com/a/32719949/1881895
barrast
37

Si vous avez déjà défini le rootViewController de votre self.window dans votre délégué d'application et que vous obtenez toujours cette erreur au moment de l'exécution, vous avez probablement plus d'une fenêtre dans votre UIApplication dont l'une peut ne pas avoir de rootViewController associé. Vous pouvez parcourir les fenêtres de votre application et associer un viewController vide à son rootViewController pour corriger l'erreur que vous obtenez.

Voici un code qui parcourt les fenêtres de l'application et associe un ViewController vide au rootViewController s'il manque une fenêtre.

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

Mise à jour: Apparemment, il existe une fenêtre dédiée à la barre d'état qui provoque généralement ce problème. Le code ci-dessus devrait corriger cette erreur.

Bms270
la source
2
Merci!! Cela s'est avéré être le problème pour moi. J'avais défini le contrôleur de vue principal, mais l'application avait une deuxième fenêtre dont je n'étais pas au courant.
n13
Tellement solide ... Je ne suis pas un rookie et celui-ci m'a obtenu lors de la mise à jour vers Xcode 7.1 sous iOS 9.1 ... la barre d'état a une fenêtre dédiée ... bien sûr ?! Je cache la barre d'état si cela signifie quelque chose pour quelqu'un.
whyoz
Wow, j'ai eu 2 de mes applications sur 12 en panne pour la révision de l'application et cela semble résoudre le problème.
Andrew Smith
A très bien fonctionné !! Gotta love "Apparemment, il y a une fenêtre dédiée à la barre d'état qui cause généralement ce problème." Je n'ai PAS vu cela venir.
eGanges
1
Cette méthode peut entraîner l'appel de viewDidLoad et viewWillAppear deux fois sur votre rootViewController. Si vous avez une fenêtre d'initialisation manuelle, vérifiez votre plist et assurez-vous que le fichier Window.xib n'est pas défini comme "Nom de base du fichier nib principal" si vous voyez des choses appelées deux fois après avoir utilisé cette solution de contournement. Ensuite, il vous suffit de supprimer ce code et de définirRootViewController comme vous le feriez normalement.
whyoz
21

XCODE 7 nécessite que tous les Windows doivent avoir un rootViewController Vous pouvez utiliser easy:

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

Cela fonctionne bien si vous devez utiliser uniquement UIWindow (pour des exemples simples de tous les tutoriels - avant Xcode 7)!

Envoyé
la source
Bienvenue dans Stack Overflow! Veuillez envisager de modifier votre message pour ajouter plus d'explications sur ce que fait votre code et pourquoi il résoudra le problème. Une réponse qui contient principalement du code (même si cela fonctionne) n'aidera généralement pas l'OP à comprendre son problème.
SuperBeasedMan
Merci, cela a évité mon avertissement iOS ~ 3-8 => crash iOS 9, mais a donné un avertissement à l'analyseur statique sur une fuite. J'ai donc déplacé la déclaration vers l'interface dans l'en-tête, avec l'affectation dans applicationDidFinishLaunching. J'ai ensuite ajouté [vc release] à dealloc.
Flash Sheridan
13

Il semble que depuis iOS 9.1 (?) Ou Xcode 7.1, tout UIWindowinstancié pendant application(_:didFinishLaunchingWithOptions:)doit avoir un rootViewControllerensemble avant de quitter cette méthode.

Auparavant, il suffisait que seule la fenêtre principale ait un rootViewControllerensemble pendant cette méthode. Désormais, toute UIWindowinstance doit avoir une rootViewControllerpropriété valide .

Le coupable ici pourrait être votre propre code si vous utilisez UIWindowet également toute autre bibliothèque tierce qui tente d'initialiser une nouvelle UIWindowinstance pendant ce temps (comme les superpositions de messages de la barre d'état, etc.).

REMARQUE : vous obtenez également la même erreur si vous ne définissez pas le rootViewControlersur votre fenêtre principale ou si votre storyboard n'est pas configuré correctement. Mentionner cela comme une note secondaire, car ces cas sont assez évidents et faciles à corriger.

lipka
la source
Vous êtes génial: D, merci mec je viens de commenter l'initialisation de la fenêtre et tout va bien maintenant
mohammad alabid
3

Cela m'a mordu aujourd'hui aussi, et cela m'a coûté quelques heures pour le réparer: mon application a la fenêtre dans un "MainWindow.xib", avec le contrôleur de navigation et le contrôleur de vue racine associé, qui ont tous été automatiquement instanciés dans le bon ordre , avec Xcode 6 et iOS8.

Sur iOS9, cette application fonctionne toujours bien lorsqu'elle est téléchargée à partir de l'AppStore, mais pas lorsqu'elle est nouvellement construite avec Xcode 7 et exécutée sur iOS 9. Au moment où le délégué de l'application exécute son applicationDidBecomeActive: méthode, le contrôleur de vue racine n'est plus chargé, car il c'était avant! Cela a fait que le contrôleur de vue racine a raté l'appel à mon code d'état de restauration.

J'ai résolu cela en instanciant moi-même le contrôleur de vue racine, dans le code, et en restaurant son état à partir de viewDidLoad, explicitement.

RickJansen
la source
2

Vous devez définir la propriété rootviewcontroller de chaque fenêtre dans votre application

alla
la source
Votre réponse m'a aidé
Aznix
2

J'ai un projet plus ancien qui fonctionnait sous iOS 8 mais pas sous iOS 9. Si votre interface principale est définie sur MainWindow.xib, mettez-la à jour en storyboard. Cela a résolu le problème pour moi:

  1. Créez un nouveau projet, l'application Single View est très bien.
  2. Copiez le fichier Main.storyboard dans votre projet ou créez simplement le vôtre.
  3. Ouvrez les paramètres de votre projet et définissez votre interface principale sur Main.storyboard Réglez votre interface principale sur Main.storyboard
Adrian
la source
1

Réglez simplement votre rootViewController sur navigationController qui est votre UIViewController dans le fichier app-delegate.rb comme mon code ci-dessous. Je suis nouveau dans le rubis mais j'espère que cela a aidé ...

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController
BigPun86
la source
1

J'ai rencontré ce problème avec une application dont j'ai plus ou moins hérité. Après avoir vérifié que le storyboard était correctement configuré en tant qu'interface principale de l'application et que le storyboard avait un RootViewController, je recevais toujours le 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'

Ce que j'ai découvert après une enquête plus approfondie que le crash était causé par l'appel d'une logique de vue (SVProgressHud) - (void)applicationDidBecomeActive:(UIApplication *)application. Cela semble être un nouveau comportement dans Xcode7 mais pour autant que je sache, SVProgressHud faisait référence au rootviewcontroller avant qu'il ne soit défini par le storyboard. Finalement, la mise à jour de SVProgressHud vers 2.0 a corrigé le bogue.

Bueno
la source
0

Solution Swift 2 qui a fonctionné pour moi:

Insérez le code ci-dessous dans AppDelegate -> didFinishLaunchingWithOptions

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

Fox5150
la source