ios - 添加 SceneDelegate 并更新 Info.plist 后黑屏
问题描述
我目前正在使用 Xcode 11、Target iOS 13.0(该应用程序在 iOS 12.1 到 12.4 的所有以下版本中都可以正常工作)出现黑屏,我想让我的应用程序同时适用于 12.1 以上的 iOS 用户和 13.0 目前虽然出现黑屏将以下 UIWindowSceneDelegate 添加到我现有的项目和 App Manifest 中:
添加应用清单文件
import UIKit
import SwiftUI
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
//guard let _ = (scene as? UIWindowScene) else { return }
let user = UserDefaults.standard.object(forKey: "defaultsuserid")
let userSelfIdent = UserDefaults.standard.object(forKey: "userinitialident")
if let windowScene = scene as? UIWindowScene {
let internalWindow = UIWindow(windowScene: windowScene)
if (user != nil && userSelfIdent != nil){
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
internalWindow.rootViewController = newViewcontroller
self.window = internalWindow
internalWindow.makeKeyAndVisible()
}else {
guard let _ = (scene as? UIWindowScene) else { return }
}
}
}
以下是我的 AppDelegate,它首先被调用并执行该didFinishLaunchWithOptions
方法。我想知道只有当我的 Target ios 小于 13.0 并调用 SceneDelegate 方法来在 13.0 之后初始化我的 rootViewController 时,我才能调用这个方法?
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
@available(iOS 13.0, *)
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
@available(iOS 13.0, *)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
if (user != nil && userSelfIdent != nil){
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
self.window?.rootViewController = newViewcontroller
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
Thread.sleep(forTimeInterval: 3.0)
UINavigationBar.appearance().barTintColor = UIColor(red:0.08, green:0.23, blue:0.62, alpha:1.0)
if (user != nil && userSelfIdent != nil){
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
self.window?.rootViewController = newViewcontroller
}
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let defaultUserID = UserDefaults.standard.string(forKey: "defaultUserID")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
switch (application.applicationState) {
case UIApplicationState.active:
do something
case UIApplicationState.background, UIApplicationState.inactive:
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
self.window?.rootViewController = newViewcontroller
}
}
解决方案
你在这里有几个问题。阅读与应用程序生命周期相关的文档很重要,该文档说明了在 iOS 13 下调用的内容以及在 iOS 12 下调用的内容。
您可能还想查看我的支持 iOS 12 和 13的Single View App 模板。
查看您的代码,以下是问题的摘要:
应用委托:
- 如果应用程序在 iOS 12 或更早版本下运行,您应该只设置主窗口和根视图控制器。您需要在运行时检查这一点。
- 该
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
方法不应在应用程序委托中。 - 不直接相关,但在应用启动时从不休眠。删除
Thread.sleep(forTimeInterval: 3.0)
线。用户希望使用您的应用程序,而不是盯着启动屏幕超过必要的时间。在应用程序启动时阻塞主线程可能会导致您的应用程序被杀死。
场景委托:
- 这大部分都很好,但没有理由使用这
guard let _ = (scene as? UIWindowScene) else { return }
条线,特别是因为它在一个if let
已经进行过检查的内部。 - 您似乎没有使用 SwiftUI,因此请删除该导入。
我会将您的应用程序委托更新为更像这样:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
UINavigationBar.appearance().barTintColor = UIColor(red:0.08, green:0.23, blue:0.62, alpha:1.0)
if #available(iOS 13.0, *) {
// In iOS 13 setup is done in SceneDelegate
} else {
let window = UIWindow(frame: UIScreen.main.bounds)
self.window = window
if (user != nil && userSelfIdent != nil){
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
window.rootViewController = newViewcontroller
}
}
return true
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13.0, *) {
// In iOS 13 setup is done in SceneDelegate
} else {
self.window?.makeKeyAndVisible()
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Not called under iOS 13 - See SceneDelegate sceneWillResignActive
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Not called under iOS 13 - See SceneDelegate sceneDidEnterBackground
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Not called under iOS 13 - See SceneDelegate sceneWillEnterForeground
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Not called under iOS 13 - See SceneDelegate sceneDidBecomeActive
}
// MARK: UISceneSession Lifecycle
@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
你的场景委托可能是这样的:
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
if (user != nil && userSelfIdent != nil){
let mainstoryboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewcontroller:UIViewController = mainstoryboard.instantiateViewController(withIdentifier: "swrevealviewcontroller") as! SWRevealViewController
window.rootViewController = newViewcontroller
window.makeKeyAndVisible()
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Not called under iOS 12 - See AppDelegate applicationDidBecomeActive
}
func sceneWillResignActive(_ scene: UIScene) {
// Not called under iOS 12 - See AppDelegate applicationWillResignActive
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Not called under iOS 12 - See AppDelegate applicationWillEnterForeground
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Not called under iOS 12 - See AppDelegate applicationDidEnterBackground
}
}
推荐阅读
- c++ - 将 $(location) 传递给 Bazel --test_arg
- python - Python 3 中的服务目录
- kubernetes - Kubernetes 节点未就绪:ContainerGCFailed / ImageGCFailed 上下文期限已超过
- php - SEO 问题 Google 将我的网站 URL 编入索引两次
- c - 循环中的表格未正确显示数据
- git - 在推送到 github 时,! [rejected] master -> master (fetch first) error: failed to push some refs to "
" - ajax - 如何正确地将 ajax 函数重写为 Reactjs 等效项
- excel - Excel iso 8601 时间戳减去 2 小时转换
- google-bigquery - BigQuery _TABLE_SUFFIX 为空/缺少表
- soap - 在 zend soap 服务器 WSDL 中创建自定义标头