“Espera-se que as janelas do aplicativo tenham um controlador de visualização raiz no final da inicialização do aplicativo” erro ao executar um projeto com Xcode 7, iOS 9

89

Depois de executar a função

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

há um acidente:

 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 projeto é um projeto antigo, o que devo fazer para torná-lo compilado e executado com Xcode 7 e iOS 9?

Andrew Wang
fonte
Já que o Xcode 7 é um beta, você provavelmente deveria voltar ao Xcode 6 para qualquer trabalho sério de desenvolvimento.
Paul R de
Olá, estou recebendo este erro: - *** Falha de declaração em - [UIApplication _runWithMainScene: transiçãoContext: conclusão:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294 como resolver isso
Akash Raghani

Respostas:

175

Da sua mensagem de erro:

Espera-se que as janelas do aplicativo tenham um controlador de visualização raiz no final da inicialização do aplicativo

Quantos anos tem esse projeto "antigo"? Se for mais do que alguns anos, você ainda tem:

[window addSubview:viewController.view];

Você deve substituí-lo por:

[window setRootViewController:viewController];
James Webster
fonte
1
Eu tenho o mesmo problema e acho que é um problema do iOS 9. Meu projeto funciona no iOS 7 e 8. Por algum motivo, a visualização do storyboard não está configurada corretamente.
David Snabel-Caunt
3
Muito obrigado . a resposta está na mensagem de erro: "Janelas do aplicativo" Descobri que há duas janelas em meu projeto, uma é uma janela normal e a outra é um modual de terceiros chamado
andrew wang
3
MTStatusBarOverlay e não possui um RootViewController, o iOS9 exige que todas as janelas tenham um rootViewController.
andrew wang
1
Sim, encontrei o mesmo problema, eventualmente. Meu aplicativo tem uma janela adicional que não possui um controlador de visualização raiz.
David Snabel-Caunt
1
Eu encontrei a solução que funciona para mim: stackoverflow.com/a/32719949/1881895
barrast
37

Se você já definiu o rootViewController de seu self.window em seu delegado de aplicativo e ainda está recebendo este erro em tempo de execução, então provavelmente você tem mais de uma janela em seu UIApplication, uma das quais pode não ter um rootViewController associado. Você pode percorrer as janelas do seu aplicativo e associar um viewController vazio a seu rootViewController para corrigir o erro que está obtendo.

Aqui está um código que percorre as janelas do aplicativo e associa um ViewController vazio ao rootViewController se uma janela estiver faltando.

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

Atualização: Aparentemente, há uma janela dedicada à barra de status que normalmente causa esse problema. O código acima deve corrigir esse erro.

Bms270
fonte
2
Obrigado!! Este acabou sendo o problema para mim. Eu tinha definido o controlador de visualização principal, mas o aplicativo tinha uma segunda janela da qual eu não sabia.
n13
Tão sólido ... Não sou nenhum novato e este me pegou ao atualizar para o Xcode 7.1 rodando iOS 9.1 ... a barra de status tem uma janela dedicada ... claro que tem ?! Estou escondendo a barra de status, se isso significar alguma coisa para alguém.
whyoz
Uau, 2 de 12 meus aplicativos travaram para análise do aplicativo e isso parece corrigir o problema.
Andrew Smith
Funcionou muito bem !! Tenho que amar "Aparentemente, há uma janela dedicada à barra de status que normalmente causa esse problema." NÃO vi isso chegando.
eGanges
1
Este método pode resultar em viewDidLoad e viewWillAppear sendo chamados duas vezes em seu rootViewController. Se você tiver uma janela de inicialização manual, verifique seu plist e certifique-se de NÃO ter o Window.xib definido como o "nome base do arquivo nib principal" se você estiver vendo coisas chamadas duas vezes após usar esta solução alternativa. Então você só precisa remover este código e setRootViewController como faria normalmente.
whyoz
21

O XCODE 7 requer que todo o Windows tenha um rootViewController. Você pode usar facilmente:

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

Está funcionando bem se você precisar usar apenas UIWindow (para exemplos fáceis de quaisquer Tutoriais - antes do Xcode 7)!

Enviado
fonte
Bem-vindo ao Stack Overflow! Considere editar sua postagem para adicionar mais explicações sobre o que seu código faz e por que ele resolverá o problema. Uma resposta que em sua maioria contém apenas código (mesmo que esteja funcionando) geralmente não ajudará o OP a entender o problema.
SuperBisedMan
Obrigado, isso evitou meu aviso do iOS ~ 3-8 => travamento do iOS 9, mas deu um aviso do analisador estático sobre um vazamento. Então, movi a declaração para a interface no cabeçalho, com a atribuição em applicationDidFinishLaunching. Em seguida, adicionei [vc release] para desalocar.
Flash Sheridan de
13

Parece que desde o iOS 9.1 (?) Ou Xcode 7.1, qualquer UIWindowinstanciado durante application(_:didFinishLaunchingWithOptions:)precisa ter um rootViewControllerconjunto antes de deixar esse método.

Anteriormente, era suficiente que apenas a janela principal tivesse um rootViewControllerconjunto durante esse método. Agora, qualquer UIWindowinstância precisa ter uma rootViewControllerpropriedade válida .

O culpado aqui pode ser o seu próprio código se você usar UIWindowe também qualquer outra biblioteca de terceiros que tente inicializar uma nova UIWindowinstância durante esse tempo (como sobreposições de mensagens da barra de status, etc.).

NOTA : Você também obterá o mesmo erro se não definir o rootViewControlerna janela principal ou se o storyboard não estiver configurado corretamente. Mencionando isso como uma observação lateral, uma vez que esses casos são bastante óbvios e simples de corrigir.

Lipka
fonte
Você é brilhante: D, obrigado cara, acabei de comentar a inicialização da janela e está tudo bem agora
mohammad alabid
3

Isso também me incomodou hoje, e me custou algumas horas para corrigi-lo: meu aplicativo tem a janela em um "MainWindow.xib", completo com controlador de navegação e controlador de visualização raiz que o acompanha, que foram todos instanciados automaticamente na ordem adequada , com Xcode 6 e iOS8.

No iOS9, esse aplicativo ainda funciona bem quando baixado da AppStore, mas não quando recém-construído com o Xcode 7 e executado no iOS 9. No momento em que o delegado do aplicativo está executando seu método applicationDidBecomeActive: o controlador de visualização raiz não está carregado, pois costumava ser antes! Isso fez com que o controlador de visualização raiz perdesse a chamada para o meu código de estado de restauração.

Corrigi isso instanciando o controlador de visualização raiz sozinho, no código, e restaurando seu estado de viewDidLoad, explicitamente.

RickJansen
fonte
2

Você deve definir a propriedade rootviewcontroller de cada janela em seu aplicativo

alla
fonte
Sua resposta me ajudou
Aznix,
2

Tenho um projeto mais antigo que funcionava no iOS 8, mas não no iOS 9. Se sua interface principal estiver definida como MainWindow.xib, atualize-o para um storyboard. Isso resolveu para mim:

  1. Crie um novo projeto, Single View Application está bem.
  2. Copie o arquivo Main.storyboard para o seu projeto ou você pode apenas criar o seu próprio.
  3. Abra as configurações do projeto e defina a interface principal como Main.storyboard Defina sua interface principal como Main.storyboard
Adrian
fonte
1

Apenas configure seu rootViewController para navigationController que é seu UIViewController no app-delegate.rb como meu código abaixo. Sou novo em rubi, mas espero que tenha ajudado ...

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController
BigPun86
fonte
1

Tive esse problema com um aplicativo que herdei mais ou menos. Depois de verificar se o storyboard estava configurado corretamente como a interface principal do aplicativo e se o storyboard tinha um RootViewController, ainda estava travando.

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

O que descobri depois de mais investigações é que o travamento estava sendo causado por alguma lógica de exibição (SVProgressHud) sendo chamada - (void)applicationDidBecomeActive:(UIApplication *)application. Este parece ser um novo comportamento no Xcode7, mas, pelo que posso dizer, SVProgressHud fazia referência ao rootviewcontroller antes de ser definido pelo storyboard. Por fim, a atualização do SVProgressHud para 2.0 corrigiu o bug.

Bueno
fonte
0

Solução Swift 2 que funcionou para mim:

Insira o código abaixo em AppDelegate -> didFinishLaunchingWithOptions

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

Fox5150
fonte