Je reçois actuellement un écran vide avec Xcode 11, Target iOS 13.0 (l'application fonctionne bien avec toutes les versions ci-dessous iOS 12.1 à 12.4), je veux que mon application fonctionne pour les utilisateurs iOS supérieurs à 12.1 et aussi 13.0 obtenant actuellement un écran vide malgré ajouter le SceneDelegate ci-dessous à mon projet existant et
ajout d'un fichier manifeste d'application
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 }
}
}
}
Ce qui suit est mon AppDelegate qui est appelé en premier et exécute la méthode didFinishLaunchWithOptions
. Je veux savoir comment puis-je effectuer cet appel de méthode uniquement si mon ios cible est inférieur à 13.0 et appeler la méthode SceneDelegate pour initialiser mon rootViewController après 13.0?
@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
}
}
Vous avez plusieurs problèmes ici. Il est important de lire la documentation relative au cycle de vie de l'application qui indique ce qui est appelé sous iOS 13 et ce qui est appelé sous iOS 12.
Vous pouvez également voir mon modèle d'application Single View qui prend en charge iOS 12 et 13.
En regardant votre code, voici un résumé des problèmes:
AppDelegate:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)
ne doit pas être dans le délégué d'application.Thread.sleep(forTimeInterval: 3.0)
. Les utilisateurs veulent utiliser votre application, sans regarder l'écran de lancement plus longtemps que nécessaire. Et le blocage du fil principal au lancement de l'application peut entraîner la mort de votre application.SceneDelegate:
guard let _ = (scene as? UIWindowScene) else { return }
, d'autant plus qu'elle se trouve à l'intérieur d'un if let
qui fait déjà cette vérification.Je mettrais à jour votre délégué d'application pour qu'il ressemble davantage à ceci:
@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.
}
}
Votre délégué de scène pourrait ressembler à:
@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
}
}
Donc, étapes pour accéder à une version iOS 13 et inférieure
1) Changez la cible de déploiement en iOS 12.
2) Remplacez les méthodes d'AppDelegate par ce qu'elles devraient avoir pour le développement iOS 12. Ajoutez également ceci:
var window: UIWindow?
3) Supprimez SceneDelegate.
4) Supprimez le manifeste de scène d'application dans votre info.plist.
Cela fonctionnera sur iOS 13 et la version iOS inférieure
Lorsque j'ai eu un problème similaire, cela était dû au fait que le modèle d'application unique généré à l'aide de Xcode 11.0 était incompatible avec celui nécessaire pour une application construite avec Xcode 11.2.
J'ai donc créé une nouvelle application de page unique avec Xcode 11.2 et copié la SceneDelegate générée dans mon ancien projet qui a été créé à l'aide de Xcode 11.0.
Après cela, l'écran vide avait disparu et mon interface était à nouveau visible.
J'étais coincé avec ce problème, et finalement j'ai résolu de supprimer les références searchDisplayController du storyboard.
<searchDisplayController id="pWz-So-g6H">
<connections>
<outlet property="delegate" destination="Yci-sd-Mof" id="fjs-ah-jLs"/>
<outlet property="searchContentsController" destination="Yci-sd-Mof" id="gQN-1r-gti"/>
<outlet property="searchResultsDataSource" destination="Yci-sd-Mof" id="2Jf-lh-Ute"/>
<outlet property="searchResultsDelegate" destination="Yci-sd-Mof" id="Hap-SA-f02"/>
</connections>
</searchDisplayController>
Suivez facilement ces étapes
1-) Supprimer le fichier délégué de scène
2-) Ajoutez le code ci-dessous à AppDelegate.Swift
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
}
3-) Supprimez la ligne Manifeste de la scène d'application de votre fichier .plist