How to get rid of message " 'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead" with AdMob banner?
Asked Answered
T

3

5

I want to get rid of the " 'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead" message in my function (my function works very well by the way.).

The line of code involved:

banner.rootViewController = UIApplication.shared.windows.first?.rootViewController

How can i do that?

My function :

struct AdView : UIViewRepresentable {
    func makeUIView(context: UIViewRepresentableContext<AdView>) -> GADBannerView {
        let banner = GADBannerView(adSize: kGADAdSizeBanner)
        banner.adUnitID = "ca-app-pub-3940256099942544/2934735716" // test ad
                banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        return banner
    }
    
    func updateUIView(_ uiView: GADBannerView, context: UIViewRepresentableContext<AdView>) {}
}

I tried that but it's not working :

banner.rootViewController = UIApplication.shared.connectedScenes.first?.rootViewController

Thanks

Tatia answered 20/10, 2021 at 17:24 Comment(0)
H
17

You can use following as UIApplication.shared.currentUIWindow()?.rootViewController

public extension UIApplication {
    func currentUIWindow() -> UIWindow? {
        let connectedScenes = UIApplication.shared.connectedScenes
            .filter { $0.activationState == .foregroundActive }
            .compactMap { $0 as? UIWindowScene }
        
        let window = connectedScenes.first?
            .windows
            .first { $0.isKeyWindow }

        return window
        
    }
}
Higgins answered 22/10, 2021 at 21:41 Comment(4)
Thank you for the catch! Correct now, I've just copied the code I'm using via iPad (with some simplification) and forgot to remove it.Higgins
This seems to happen later than using UIWindowScene.windows.first?, unfortunately. Using UIApplication.shared.connectedScenes.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }.first { $0.isKeyWindow } does the trick.Riggle
Can you comment more on “this seems to happen later”?Higgins
Note that answers like this fail to take into account an app that supports multiple scenes.Crichton
B
2

For swift UI simply create a constant

  struct SceneConstants {
        static let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
    }
Biebel answered 5/9, 2023 at 19:46 Comment(1)
Note that answers like this fail to take into account an app that supports multiple scenes.Crichton
R
1

In Objective C I was able to replace:

NSArray  *windows = [[UIApplication sharedApplication] windows];

with

NSArray *scenes=[[[UIApplication sharedApplication] connectedScenes] allObjects];
NSArray *windows=[[scenes objectAtIndex:0] windows];

My full method is:

-(UIViewController *)parentController {
    
    UIWindow *foundWindow = nil;
    NSArray *scenes=[[[UIApplication sharedApplication] connectedScenes] allObjects];
    NSArray *windows=[[scenes objectAtIndex:0] windows];
    for (UIWindow  *window in windows) {
        if (window.isKeyWindow) {
            foundWindow = window;
            break;
        }
    }
    UIViewController* parentController = foundWindow.rootViewController;
    while( parentController.presentedViewController &&
          parentController != parentController.presentedViewController ){
        parentController = parentController.presentedViewController;
    }
    return  parentController;
}
Rokach answered 3/11, 2022 at 22:11 Comment(1)
Note that answers like this fail to take into account an app that supports multiple scenes.Crichton

© 2022 - 2024 — McMap. All rights reserved.