Отказаться от UISceneDelegate / SwiftUI на iOS

120

В настоящее время я использую Xcode 11 Beta 5. В моем приложении он отлично работает на iOS 12 и ниже. Однако в iOS 13 похоже, что UISceneпо умолчанию используется. Это заставляет мое приложение ничего не делать.

Когда приложение запускается при новой установке, пользователь должен принять условия использования. После согласования они переходят на экран загрузки, который затем направляет их на главный экран. На опубликованном мною скриншоте вид позади текущего на переднем плане - это экран загрузки заставки.

Вскоре мы рассмотрим возможность добавления поддержки сцены с несколькими представлениями во всем приложении, но сейчас у нас есть более приоритетные вещи, над которыми нужно работать.

https://imgur.com/i0qLhAL

«Поддержка нескольких окон» уже отключена в общих настройках целевого приложения. Также у меня для параметра Enable Multiple Windows установлено значение NO в файле info.plist.

Пока ничего толком не сработало. В основном я хочу отказаться / отключить несколько окон и UIScene / SwiftUI, чтобы восстановить исходное поведение в iOS 10-12. Возможно ли это в iOS 13 или мы должны его обновить?

Обновить:

Вот скриншот иерархии отладки представления. Левая сторона - iOS 12, правая - iOS 13. Почему не добавляется ничего в Info.plist или какие-либо классы или методы делегата сцены? Практически просто запустил его в существующем готовом для производства коде на Xcode 11.

https://imgur.com/C3aLsDo

DavidA
источник
Вам нужно поддерживать только iOS 13 и новее или вам нужно поддерживать iOS 13 и iOS 12?
rmaddy
Поддержка @rmaddy между iOS 11-13 + (будущие версии).
DavidA
Ваш основной интерфейс - через код или раскадровку?
rmaddy
@rmaddy, это делается в раскадровках, есть ссылка на xib ViewControllers.
DavidA
Без конкретной информации о том, что делает ваше приложение и когда, трудно сказать. Обратите внимание, что методы контроллера представления, такие как viewWill|DidAppear, не вызываются одинаково в iOS 13, например, при отклонении представленных контроллеров представления. Добавьте множество сообщений отладки жизненного цикла и точек останова и сравните поток между iOS 12 и 13 и посмотрите, в чем он отличается.
rmaddy

Ответы:

337

Хотя вы должны использовать сцены, когда ваше приложение работает под iOS 13 и более поздних версий, вы можете полностью отказаться, пока вы по-прежнему поддерживаете iOS 12 или более ранние версии.

  • Полностью удалите запись «Application Scene Manifest» из Info.plist.

  • Если есть класс делегата сцены, удалите его.

  • Если в делегате вашего приложения есть методы, связанные со сценой, удалите эти методы.

  • Если его нет, добавьте свойство var window: UIWindow?в делегат вашего приложения.

Теперь ваше приложение должно использовать только делегата приложения, а в iOS 13 оно должно иметь тот же жизненный цикл, что и iOS 12.

Примечание. Ничто из этого не относится к Swift или SwiftUI.

мэдди
источник
Мы публиковали ответы одновременно. :-) Один вопрос - та недостающая строка в AppDelegateтом, что я адресовал. Возвращается ли это автоматически к описанному вами процессу? (Мне как бы больше нравится ваш ответ, поскольку он полностью игнорирует сцены.)
dfd
1
То же самое происходит со мной, и у меня нет записи манифеста в моем Info.plist, ни каких-либо методов AppDelegate, а также нет класса SceneDelegate. Я устанавливаю свой контроллер как «условия и положения» для Дэвида как rootViewController, и он выглядит так же, как показано здесь в вопросе выше. Пожалуйста, помогите, так как я застрял с этой ошибкой пользовательского интерфейса и не могу двигаться дальше ... тьфу!
Мохсин Хубаиб Ахмед,
1
@MohsinKhubaibAhmed Вы спрашиваете совсем о другом. См stackoverflow.com/questions/56435510/...
rmaddy
1
Всем привет! Я выполнил трехэтапную инструкцию, но после появления экрана запуска у меня черный экран. Выбрана основная раскадровка, а также начальный контроллер представления. Есть ли у вас какие-либо предложения?
user3191334
1
@ user3191334 У меня тоже черный экран получился. В моем случае это был темный режим, дающий мне черный фон по умолчанию. Добавьте контент в свою базовую раскадровку, и все появится.
Гордон Дав
42

Надеюсь, лучше использовать ответ, чем комментарий. (Не стесняйтесь комментировать, я отредактирую.)

С этим я тоже столкнулся, и здесь есть несколько сценариев:

  • Если вы хотите работать с существующимUIKit приложением в Xcode 11, просто откройте его, и оно должно работать нормально. Все мои приложения есть, без SceneDelegate файлов, без каких-либо изменений AppDelegateили раскадровок.
  • Если вы хотите создать новое UIKITприложение для iOS 13 , просто создайте его, убедившись, что вы не отметили флажок «Использовать SwiftUI».

Но мне интересно, сталкиваетесь ли вы с третьим сценарием - тем, что я сделал около недели назад. Создание нового приложения ʻUIKit, ориентированного на что-то более раннее, чем iOS 13 . (Я на самом деле нацелился на iOS 9!)

Да, ваш шаблон выдаст вам 15 ошибок (по состоянию на бета 5), а также SceneDelegate файлом / классом. К счастью, Xcode поможет вам автоматически исправить все, кроме одного.

Последний - добавить одну строку, которая является частью SceneDelegateкласса, но, к сожалению, Apple оставила ее вне AppDelegateкласса - что после более чем десятка @available(iOS 13.0, *)предложений означает, что вы отказались от SceneDelegateиспользования iOS 12 и знаете что? Это не там ApDelegate!

Добавьте это в свой AppDelegate:

var window: UIWindow?

На этом этапе у вас должно быть работающее UIKitприложение, ориентированное на iOS 12 и ранее.

dfd
источник
Спасибо за это. Мой сценарий в значительной степени является первым пунктом, о котором вы сказали, о существующем приложении UIKit в Xcode 11. Но когда я открываю его, оно не работает нормально. Посмотрите на добавленное мной обновление иерархии отладки представления.
DavidA
Также в AppDelegate уже есть var window: UIWindow?
DavidA
Вы меня беспокоили! (И я все еще немного волнуюсь.) Я очень мало обновил свои существующие приложения - на прошлой неделе было разочарование в SwiftUI, и мне было любопытно попробовать макет в UIKit только для iOS 13. Но мои существующие приложения? Они поддерживают многозадачность iPad, но оставлены без изменений в Xcode 11, которого у меня нет, SceneDelegateи тестирование говорит: (а) они работают в iOS 13 и (б) они вообще не поддерживают несколько окон, просто разделите представление между двумя приложениями. (Я также не поддерживаю перетаскивание.) Что-то еще происходит с вашей стороны?
dfd
Повторюсь, я просто открыл свое приложение Xcode 10 в Xcode 11. Нет SceneDelegate, нет SwiftUI, нет возможности создавать несколько экземпляров моих приложений iOS 9+. Производительность такая же, как и всегда - все это CoreImageнастраиваемые фильтры, обновляемые в реальном времени - ну, а для меня? Если есть какая-то проблема, связанная с ОС, связанная со сценами в иерархии представлений, это спорный вопрос, если он не поддерживает сцены. (И в заключение, да, я все еще немного обеспокоен. Но это еще и бета-версия 5.) Надеюсь, у вас есть хорошая резервная копия, которая может воспроизвести то, что я вижу.
dfd
Спасибо. Я подозреваю, что это что-то в пределах жизненного цикла. Я потрачу время на отладку своего приложения. Я буду обновлять это всякий раз, когда выясню, что это поможет кому-нибудь в подобной ситуации
DavidA
7

Я заставил это работать, используя ответ dfd, но поскольку мое приложение находится в Objective-C, мне пришлось внести одно изменение:

В Objective-C вы хотите поставить

@property (strong, nonatomic) UIWindow *window;

в AppDelegate.h (не в .m)

Ник Бхатт
источник
4

Хорошо, я понял это. Из-за изменений в iOS 13 нового стиля представления карточек Apple по умолчанию, в моей раскадровке, переходящей от заставки к моему настраиваемому контроллеру навигации потока, по умолчанию используется новая презентация (см. Снимок экрана ниже).

Переход

Я исправил это, вернувшись к старому стилю, который по умолчанию использовался для старого жизненного цикла. Смотрите скриншот ниже.

Storyboard seque kind

Не уверен, почему это произошло, так как это было единственное место в моем приложении, которое вызвало это (довольно большое приложение, поэтому мне нужно потратить некоторое время на просмотр всех раскадровок, чтобы убедиться).

DavidA
источник
2
Ваш вопрос касается того, как отказаться от использования сцен. Этот ответ не дает решения для отказа от сцен. Это не должен быть принятым ответом. Если бы все, что вы хотели сделать, это избежать новой презентации в виде карточек, вы могли бы найти этот ответ в нескольких дубликатах, касающихся этого вопроса.
rmaddy
1

Xcode 12 - Swift 5.3 - iOS 14

Начиная с Xcode 12 и с помощью Swift 5.3 и у @mainвас может быть мультиплатформенное приложение, у которого нет SceneDelegateсобытия или AppDelegate. Будет только простой файл вроде:

import SwiftUI

@main
struct MyMultiPlatformApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Моджтаба Хоссейни
источник