iOS 13/Facebook SDK error "Unable to find a valid UIWindow"

2.5k views Asked by At

(To forestall well-intended suggestions, yes I posted this question last week on Facebook's developer forum. No responses yet.)

TL;DR

Facebook SDK 5.8 complains at startup FBSDKLog: Unable to find a valid UIWindow.

The Main Story

In a from-scratch, one-view Xcode 11/iOS 13 project, there is no longer a default UIWindow member associated with the application. (The window per se is still around; you can see it, contained in a UIWindowScene, using the View Hierarchy Debugger in Xcode, or the Reveal app.)

FBSDK 5.8 does seem to be iOS-13-aware, and looks around for it. The relevant code is at line 498 of

https://github.com/facebook/facebook-ios-sdk/blob/master/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m.

Facebook's code iterates over the application's connectedScenes member, which for me is an empty set. How do I modify my code so that FBSDK finds the window?

Some Hacking

I tried adding the following to scene(_:willConnectTo:options:) but it seems to be too late — the FBSDKLog message has already appeared by then. (So I'm flailing...)

guard let s = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: s)

The following also failed, but it was just a shot in the dark:

guard let s = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: s.coordinateSpace.bounds)
self.window?.windowScene = s
self.window?.rootViewController = ViewController(nibName: nil, bundle: nil)
self.window?.makeKeyAndVisible()
2

There are 2 answers

2
Miguel Hernández On

If you don't use the new behaviour and don't mind reverting to the old way, you can try the following

  1. Delete Application Scene Manifest key from Info.plist

    Key to delete

  2. Delete SceneDelegate.swift

  3. Add var window: UIWindow?to AppDelegate.swift

    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow? // <-- Here
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    
    //        window!.makeKeyAndVisible()
    
    
        return true
        }
    
    }
    
0
Andrew Nikulitsa On
  1. Add window variable to AppDelegate class
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
  2. Assign UIWindow inside didFinishLaunchingWithOptions
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
         window = UIWindow(frame: UIScreen.main.bounds)
         if let window = window {
             window.makeKeyAndVisible()
             self.window = window
         }
    
         ApplicationDelegate.shared.application(
              application,
              didFinishLaunchingWithOptions: launchOptions
         )
    
         return true
     }