when updating my App's Deployment target to 15.0, i receive this warning:
'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead
I have tried to look on the net what could be done to remediate this, but couldn't find much info on this. Hope you could share some advice.
The line of code i am using where this alert occurred is:
let window = UIApplication.shared.windows[0]
followed by in my ViewDidLoad():
DispatchQueue.main.async { [weak self] in
if defaults.bool(forKey: "darkModeBoolSwitch") == true {
self?.window.overrideUserInterfaceStyle = .dark
} else if defaults.bool(forKey: "darkModeBoolSwitch") == false {
self?.window.overrideUserInterfaceStyle = .light
}
CodePudding user response:
I am out-of-date with Apple's recent changes to implement scenes.
I did a little digging, and found a protocol UIWindowSceneDelegate
It looks like you are supposed to add an "Application Scene Manifest" to your app's info.plist file that tells the system the class that serves as the app's window scene delegate.
Then in that class you want to implement the method scene(_:willConnectTo:options:). When that method is called you sould try to cast the UIScene that's passed to you to to a UIWindowScene, and if that cast succeeds, you can ask the window scene for it's window and save it to an instance property.
That should allow you to save a pointer to your app's window and use it when needed.
CodePudding user response:
An alternative to @DuncanC's solution that may also work for you: UIApplication has a connectedScenes property, which lists all of the currently-active scenes doing work in your application (for most applications, this is just the one main scene).
Of those scenes, you can filter for scenes which are UIWindowScenes (ignoring scenes which are not currently active and in the foreground), and of those, find the first scene which has a window which is key:
extension UIApplication {
static var firstKeyWindowForConnectedScenes: UIWindow? {
UIApplication.shared
// Of all connected scenes...
.connectedScenes.lazy
// ... grab all foreground active window scenes ...
.compactMap { $0.activationState == .foregroundActive ? ($0 as? UIWindowScene) : nil }
// ... finding the first one which has a key window ...
.first(where: { $0.keyWindow != nil })?
// ... and return that window.
.keyWindow
}
}
I hesitate to call this extension something like UIApplication.keyWindow because the reason for the deprecation of these APIs is because of the generalization to multi-scene applications, each of which may have its own key window... But this should work.
If you still need to support iOS 14, which does not have UIWindowScene.keyWindow, you can replace the firstWhere(...)?.keyWindow with: flatMap(\.windows).first(where: \.isKeyWindow).
