„Oczekuje się, że okna aplikacji będą miały główny kontroler widoku pod koniec uruchamiania aplikacji” podczas uruchamiania projektu z Xcode 7, iOS 9

89

Po uruchomieniu funkcji

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

jest awaria:

 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

Ten projekt jest starym projektem, co powinienem zrobić, aby skompilował się i działał z Xcode 7 i iOS 9?

andrew wang
źródło
Ponieważ Xcode 7 jest wersją beta, prawdopodobnie powinieneś wrócić do Xcode 6, aby wykonać poważne prace programistyczne.
Paul R
witam otrzymuję ten błąd: - *** Błąd potwierdzenia w - [UIApplication _runWithMainScene: przejścieContext: Complete:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UIApplication.m: 3294, jak rozwiązać ten problem
Akash Raghani

Odpowiedzi:

175

Z komunikatu o błędzie:

Oczekuje się, że okna aplikacji będą miały główny kontroler widoku pod koniec uruchamiania aplikacji

Ile lat ma ten „stary” projekt? Jeśli minęło więcej niż kilka lat, czy nadal masz:

[window addSubview:viewController.view];

Zamiast tego powinieneś zamienić go na:

[window setRootViewController:viewController];
James Webster
źródło
1
Mam ten sam problem i myślę, że jest to problem z iOS 9. Mój projekt działa na iOS 7 i 8. Z jakiegoś powodu widok ze scenorysu nie jest ustawiony poprawnie.
David Snabel-Caunt
3
Dziękuję Ci bardzo . odpowiedź znajduje się w komunikacie o błędzie: „Okna aplikacji”. W moim projekcie są dwa okna, jedno to normalne okno, drugie to moduł innej firmy o nazwie
andrew wang
3
MTStatusBarOverlay i nie ma RootViewController, iOS9 wymaga, aby wszystkie okna musiały mieć rootViewController.
andrew wang
1
Tak, w końcu znalazłem ten sam problem. Moja aplikacja ma dodatkowe okno, które nie ma głównego kontrolera widoku.
David Snabel-Caunt
1
Znalazłem rozwiązanie, które działa dla mnie: stackoverflow.com/a/32719949/1881895
barrast
37

Jeśli ustawiłeś już rootViewController swojego self.window w delegacie aplikacji i nadal otrzymujesz ten błąd w czasie wykonywania, prawdopodobnie masz więcej niż jedno okno w swojej aplikacji UIApplication, z których jedno może nie mieć skojarzonego elementu rootViewController. Możesz zapętlić okna aplikacji i skojarzyć pusty element viewController z jego rootViewController, aby naprawić otrzymywany błąd.

Oto kod, który zapętla okna aplikacji i kojarzy pusty ViewController z rootViewController, jeśli w oknie go brakuje.

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

Aktualizacja: Najwyraźniej istnieje okno poświęcone paskowi stanu, które zwykle powoduje ten problem. Powyższy kod powinien naprawić ten błąd.

Bms270
źródło
2
Dzięki!! To okazało się dla mnie problemem. Ustawiłem główny kontroler widoku, ale aplikacja miała drugie okno, którego nie byłem świadomy.
n13
Tak solidny ... Nie jestem debiutantem i ten mnie dopadł podczas aktualizacji do Xcode 7.1 z systemem iOS 9.1 ... pasek stanu ma dedykowane okno ... oczywiście, że tak ?! Ukrywam pasek stanu, jeśli to coś dla kogoś znaczy.
Whyoz
Wow, 2 z 12 moich aplikacji uległo awarii w celu sprawdzenia aplikacji i wydaje się, że to rozwiązuje.
Andrew Smith
Działało świetnie !! Muszę kochać „Najwyraźniej istnieje okno poświęcone paskowi stanu, które zwykle powoduje ten problem.” NIE spodziewałem się, że nadchodzi.
eGanges
1
Ta metoda może spowodować dwukrotne wywołanie viewDidLoad i viewWillAppear w Twoim rootViewController. Jeśli masz ręcznie uruchamiane okno, sprawdź swój plik plist i upewnij się, że NIE masz zdefiniowanego pliku Window.xib jako „Nazwa bazowa głównego pliku nib”, jeśli po zastosowaniu tego obejścia widzisz elementy wywoływane dwukrotnie. Następnie wystarczy usunąć ten kod i ustawićRootViewController w normalny sposób.
whyoz
21

XCODE 7 wymaga, aby wszystkie systemy Windows miały rootViewController Możesz użyć łatwego:

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

Działa dobrze, jeśli musisz używać tylko UIWindow (dla łatwych przykładów z dowolnych samouczków - przed Xcode 7)!

Wysłannik
źródło
Witamy w Stack Overflow! Rozważ edycję swojego posta, aby dodać więcej wyjaśnień o tym, co robi Twój kod i dlaczego rozwiąże problem. Odpowiedź, która w większości zawiera tylko kod (nawet jeśli działa), zwykle nie pomoże OP w zrozumieniu problemu.
SuperBiasedMan
Dzięki, to uniknęło mojego ostrzeżenia w iOS ~ 3–8 => awarii iOS 9, ale dało statyczne ostrzeżenie analizatora o wycieku. Więc przeniosłem deklarację do interfejsu w nagłówku, z przypisaniem w applicationDidFinishLaunching. Następnie dodałem [vc release] do dealloc.
Flash Sheridan
13

Wygląda na to, że od iOS 9.1 (?) Lub Xcode 7.1 każda UIWindowinstancja tworzona podczas application(_:didFinishLaunchingWithOptions:)musi mieć rootViewControllerzestaw przed opuszczeniem tej metody.

Wcześniej wystarczyło, aby tylko okno główne miało rootViewControllerzestaw podczas tej metody. Teraz każda UIWindowinstancja musi mieć prawidłową rootViewControllerwłaściwość.

Winowajcą może być tutaj twój własny kod, jeśli korzystasz z, UIWindowa także dowolnej innej biblioteki innej firmy, która próbuje zainicjować nową UIWindowinstancję w tym czasie (np. Nakładki komunikatów paska stanu itp.).

UWAGA : Ten sam błąd rootViewControlerpojawia się również, jeśli nie ustawisz w głównym oknie lub jeśli scenorys nie jest poprawnie skonfigurowany. Wspominając o tym na marginesie, ponieważ te przypadki są dość oczywiste i łatwe do naprawienia.

lipka
źródło
Jesteś genialny: D, dzięki stary, tylko skomentuję inicjalizację okna i teraz wszystko jest w porządku
mohammad alabid
3

Ugryzło mnie to również dzisiaj i kosztowało mnie kilka godzin, aby to naprawić: moja aplikacja ma okno w pliku „MainWindow.xib”, wraz z kontrolerem nawigacji i towarzyszącym mu głównym kontrolerem widoku, które zostały automatycznie utworzone we właściwej kolejności , z Xcode 6 i iOS8.

W systemie iOS9 ta aplikacja nadal działa dobrze po pobraniu z AppStore, ale nie w przypadku nowej kompilacji z Xcode 7 i uruchomienia w systemie iOS 9. W czasie, gdy delegat aplikacji wykonuje swoją metodę applicationDidBecomeActive:, główny kontroler widoku nie jest teraz ładowany, ponieważ kiedyś! To sprawiło, że główny kontroler widoku przegapił wywołanie mojego kodu stanu przywracania.

Naprawiłem to, tworząc samodzielnie wystąpienie głównego kontrolera widoku w kodzie i jawnie przywracając jego stan z właściwości viewDidLoad.

RickJansen
źródło
2

W aplikacji należy ustawić właściwość rootviewcontroller każdego okna

alla
źródło
Twoja odpowiedź pomogła mi
Aznix
2

Mam starszy projekt, który działał w systemie iOS 8, ale nie w iOS 9. Jeśli główny interfejs jest ustawiony na MainWindow.xib, zaktualizuj go do serii ujęć. To naprawiło to dla mnie:

  1. Utwórz nowy projekt, aplikacja pojedynczego widoku jest w porządku.
  2. Skopiuj plik Main.storyboard do swojego projektu lub możesz po prostu stworzyć własny.
  3. Otwórz ustawienia projektu i ustaw główny interfejs na Main.storyboard Ustaw główny interfejs na Main.storyboard
Adrian
źródło
1

Po prostu ustaw swój rootViewController na navigationController, który jest twoim UIViewController w app-delegate.rb, tak jak mój kod poniżej. Jestem nowy w Ruby, ale mam nadzieję, że to pomogło ...

rootViewController = UIViewController.alloc.init

@window.rootViewController = navigationController
BigPun86
źródło
1

Wpadłem na ten problem z aplikacją, którą bardziej lub mniej odziedziczyłem. Po sprawdzeniu, że storyboard został poprawnie skonfigurowany jako główny interfejs aplikacji i że scenorys miał RootViewController, nadal otrzymywałem awarię.

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

Co odkryłem po dalszych badaniach, że awaria była spowodowana wywołaniem jakiejś logiki widoku (SVProgressHud) - (void)applicationDidBecomeActive:(UIApplication *)application. Wydaje się, że jest to nowe zachowanie w Xcode7, ale o ile mogę powiedzieć, SVProgressHud odwoływał się do rootviewcontroller, zanim został ustawiony przez storyboard. Ostatecznie aktualizacja SVProgressHud do wersji 2.0 naprawiła błąd.

Bueno
źródło
0

Rozwiązanie Swift 2, które zadziałało dla mnie:

Wstaw poniższy kod w AppDelegate -> didFinishLaunchingWithOptions

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

Fox5150
źródło