Zrezygnuj z UISceneDelegate / SwiftUI na iOS


119

Obecnie używam Xcode 11 Beta 5. W mojej aplikacji działa dobrze na iOS 12 i niższych. Jednak na iOS 13 wygląda na to, że UIScenedomyślnie używa . To powoduje, że moja aplikacja nic nie robi.

Gdy aplikacja uruchamia się przy nowej instalacji, użytkownik musi zaakceptować warunki, które musi zaakceptować. Po wyrażeniu zgody przechodzą do ekranu ładowania, który następnie kieruje ich do głównego widoku. Na zamieszczonym przeze mnie zrzucie ekranu widok za bieżącym na pierwszym planie to powitalny ekran ładowania.

Wkrótce zajmiemy się dodaniem obsługi wielu widoków w całej aplikacji, ale w tej chwili mamy rzeczy o wyższym priorytecie, nad którymi musimy popracować.

https://imgur.com/i0qLhAL

Opcja „Obsługa wielu okien” jest już wyłączona w ustawieniach ogólnych celu aplikacji. Mam również opcję Enable Multiple Windows ustawioną na NO w pliku info.plist.

Jak dotąd nic tak naprawdę nie zadziałało. Zasadniczo chcę zrezygnować / wyłączyć wiele okien i UIScene / SwiftUI, aby przywrócić oryginalne zachowanie w iOS 10-12. Czy to możliwe w iOS 13, czy musimy to zaktualizować?

Aktualizacja:

Oto zrzut ekranu hierarchii debugowania widoku. Lewa strona to iOS 12, prawa strona to iOS 13. Bez dodawania czegokolwiek do Info.plist ani żadnych klas lub metod delegata sceny, dlaczego jest inaczej? Prawie po prostu uruchomiłem go w istniejącym gotowym do produkcji kodzie na Xcode 11.

https://imgur.com/C3aLsDo


Czy potrzebujesz obsługiwać tylko iOS 13 i nowsze, czy potrzebujesz obsługi iOS 13 i iOS 12?
rmaddy

Obsługa @rmaddy między iOS 11-13 + (przyszłe wersje).
DavidA

Czy Twój główny interfejs użytkownika zawiera kod lub scenorys?
rmaddy

@rmaddy to zrobione w scenorysach, ma wypływ do odwołań do kontrolerów xib ViewControllers.
David A

Bez szczegółowych informacji o tym, co robi Twoja aplikacja i kiedy, trudno powiedzieć. Zwróć uwagę, że metody kontrolera widoku, takie jak, viewWill|DidAppearnie są tak samo nazywane w iOS 13 podczas odrzucania prezentowanych kontrolerów widoku, na przykład. Dodaj wiele komunikatów debugowania cyklu życia i punktów przerwania i porównaj przepływ między iOS 12 i 13 i zobacz, gdzie jest inny.
rmaddy

Odpowiedzi:


334

Chociaż powinieneś korzystać ze scen, gdy Twoja aplikacja jest uruchomiona w systemie iOS 13 lub nowszym, możesz w pełni zrezygnować z obsługi systemu iOS 12 lub wcześniejszego.

  • Całkowicie usuń wpis „Manifest sceny aplikacji” z Info.plist.

  • Jeśli istnieje klasa delegata sceny, usuń ją.

  • Jeśli w delegacie aplikacji istnieją metody związane ze scenami, usuń te metody.

  • Jeśli go nie ma, dodaj właściwość var window: UIWindow?do delegata aplikacji.

Twoja aplikacja powinna teraz używać tylko delegata aplikacji, a pod iOS 13 powinna mieć taki sam cykl życia jak iOS 12.

Uwaga: nic z tego nie jest specyficzne dla Swift lub SwiftUI.


W tym samym czasie zamieściliśmy odpowiedzi. :-) Jedno pytanie - ta brakująca linijka w AppDelegatektórej się odezwałem. Czy to automatycznie powraca w opisanym przez ciebie procesie? (
Trochę

1
To samo dzieje się ze mną i nie mam wpisu manifestu w moim Info.plist ani żadnych metod AppDelegate ani klasy SceneDelegate. Ustawiam mój kontroler jako „warunki” dla Davida jako rootViewController i wygląda tak samo, jak pokazano w powyższym pytaniu. Proszę o pomoc, ponieważ utknąłem z tą usterką interfejsu użytkownika i nie mogę iść do przodu ... ugh!
Mohsin Khubaib Ahmed

1
@MohsinKhubaibAhmed Pytasz o zupełnie inny problem. Zobacz stackoverflow.com/questions/56435510/…
rmaddy

1
Cześć! Postępowałem zgodnie z instrukcją w 3 krokach, ale po pojawieniu się ekranu startowego pojawił się czarny ekran. Wybrano główną scenorys, a także początkowy kontroler widoku. Masz jakieś sugestie?
user3191334

1
@ user3191334 Mam też czarny ekran. W moim przypadku był to tryb ciemny dający domyślne czarne tło. Dodaj zawartość do swojej podstawowej serii ujęć, a wszystko się pojawi.
Gordon Dove

42

Miejmy nadzieję, że wykorzystując odpowiedź do lepszego sformatowania rzeczy niż komentarz. (Zapraszam do komentowania, a ja edytuję.)

To jest coś, z czym też się zmierzyłem, a tutaj jest kilka scenariuszy:

  • Jeśli chcesz pracować nad istniejącąUIKit aplikacją w Xcode 11, po prostu ją otwórz i powinno działać dobrze. Wszystkie moje aplikacje mają, bez SceneDelegate pliku, żadnych zmian AppDelegateani scenorysów.
  • Jeśli chcesz utworzyć nową UIKITaplikację na iOS 13 , po prostu utwórz ją, upewniając się, że pole wyboru „Użyj SwiftUI” nie jest zaznaczone.

Ale zastanawiam się, czy masz do czynienia z trzecim scenariuszem - tym, który zrobiłem około tydzień temu. Stworzenie nowej aplikacji ʻUIKit przeznaczonej dla czegoś wcześniejszego niż iOS 13 . (Właściwie celowałem w iOS 9!)

Tak, Twój szablon wyświetli 15 błędów (od wersji beta 5) wraz z SceneDelegateplikiem / klasą. Na szczęście Xcode pomoże Ci automatycznie poprawić wszystkie oprócz jednego.

Ostatnim jest dodanie jednej linii, która jest częścią SceneDelegateklasy, ale niestety Apple pominęła ją poza AppDelegateklasą - co po kilkunastu @available(iOS 13.0, *)klauzulach oznacza, że ​​zrezygnowałeś z korzystania z SceneDelegateiOS 12 i zgadnij co? Nie ma go w środku ApDelegate!

Dodaj to do swojej AppDelegate:

var window: UIWindow?

W tym momencie powinieneś mieć działającą UIKitaplikację przeznaczoną na iOS 12 i starsze.


Dzięki za to. Mój scenariusz jest właściwie pierwszym punktem, o którym powiedziałeś, istniejącą aplikacją UIKit w Xcode 11. Ale kiedy ją otwieram, nie działa dobrze. Spójrz na aktualizację hierarchii debugowania widoku, którą dodałem.
DavidA

Również w AppDelegate ma już okno var: UIWindow?
DavidA

Martwiłeś mnie! (I wciąż jestem trochę zaniepokojony.) Zaktualizowałem bardzo niewiele moich istniejących aplikacji - w zeszłym tygodniu był frustracja SwiftUI i byłem ciekawy, czy wypróbować układ w UIKit tylko dla iOS 13. Ale moje istniejące aplikacje? Obsługują wielozadaniowość iPada, ale pozostawiono je niezmienione w Xcode 11. Nie mam, SceneDelegatea testowanie mówi (a) działają w iOS 13 i (b) w ogóle nie obsługują wielu okien, po prostu podziel widok między dwie aplikacje. (Nie obsługuję też przeciągania i upuszczania.) Czy jest coś jeszcze na Twoim końcu?
dfd

Powtórzę, po prostu otworzyłem aplikację Xcode 10 w Xcode 11. Nie SceneDelegate, nie SwiftUI, brak możliwości tworzenia wielu instancji aplikacji na iOS 9+. Wydajność jest taka sama jak zawsze - wszystkie są CoreImageniestandardowymi filtrami aktualizowanymi w czasie rzeczywistym - i, cóż, dla mnie? Jeśli istnieje jakiś problem związany z systemem operacyjnym związany ze scenami w hierarchii widoków, jest to dyskusyjne, jeśli nie obsługuje scen. (I na koniec, tak, nadal jestem trochę zaniepokojony. Ale to także wersja beta 5.) Mam nadzieję, że masz dobrą kopię zapasową, która może odtworzyć to, co widzę.
dfd

Dzięki. Podejrzewam, że jest to coś w cyklu życia. Spędzę czas na debugowaniu mojej aplikacji. Zaktualizuję to, gdy tylko się
wymyślę

6

Mam to do pracy, używając odpowiedzi dfd, ale ponieważ moja aplikacja jest w Objective-C, musiałem wprowadzić jedną zmianę:

W Objective-C chcesz umieścić

@property (strong, nonatomic) UIWindow *window;

w AppDelegate.h (nie w .m)


4

Okej, więc to rozgryzłem. Ze względu na zmiany w iOS 13 w nowym domyślnym stylu prezentacji kart firmy Apple, w mojej scenorysie przechodzę z mojego ekranu powitalnego do mojego niestandardowego kontrolera nawigacji przepływu, który domyślnie ustawił nową prezentację (patrz zrzut ekranu poniżej).

Segue

Naprawiłem to, aby wrócić do starego stylu, który domyślnie przywracał stary cykl życia. Zobacz zrzut ekranu poniżej.

Storyboard seque kind

Nie jestem pewien, dlaczego tak się stało, ponieważ było to jedyne miejsce w mojej aplikacji, które to spowodowało (dość duża aplikacja, więc muszę poświęcić trochę czasu na przeglądanie wszystkich scenorysów, aby się upewnić).


2
Twoje pytanie dotyczy tego, jak zrezygnować z używania scen. Ta odpowiedź nie zapewnia rozwiązania problemu rezygnacji ze scen. To nie powinna być akceptowana odpowiedź. Gdyby wszystko, co chciałeś zrobić, to uniknąć nowej prezentacji w stylu karty, mogłabyś znaleźć tę odpowiedź w kilku duplikatach odpowiadających na to pytanie.
rmaddy

1

Xcode 12 - Swift 5.3 - iOS 14

Od Xcode 12 i przy pomocy Swift 5.3 i @mainmożesz mieć wieloplatformową aplikację, która nie ma żadnego SceneDelegatezdarzenia AppDelegate. Będzie tylko prosty plik, taki jak:

import SwiftUI

@main
struct MyMultiPlatformApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.