'How can I access a custom variable in the SceneDelegate from the ViewController?

I know how to access the scene delegate:

self.view.window.windowScene.delegate

And the window:

UIScene *scene = [[[[UIApplication sharedApplication] connectedScenes] allObjects] firstObject];

if ([scene.delegate conformsToProtocol:@protocol(UIWindowSceneDelegate)]) {
    
    UIWindow *window = [(id <UIWindowSceneDelegate>)scene.delegate window];
}

But both methods assume I haven't made any changes to the SceneDelegate.h/.m file.

I have created a custom toolbar and I don't know how to access it from the viewController:

SceneDelegate.h

#import <UIKit/UIKit.h>

@interface SceneDelegate : UIResponder <UIWindowSceneDelegate, NSToolbarDelegate>

@property (strong) NSToolbar *mainToolbar;

@property (strong, nonatomic) UIWindow * window;

@end

I'm using the NSToolbar because it's a Mac Catalyst app that can run on macOS also.



Solution 1:[1]

But both methods assume I haven't made any changes to the SceneDelegate.h/.m file.

Why is this happening?

Because the code you have provided returns an instance of UIWindowSceneDelegate. But you are looking for the object of type SceneDelegate to access its interface. So you have to cast it to the desired interface.

How can I resolve this then?

So you can access it anywhere like:

SceneDelegate.shared.myCustomProperty

By defining a simple class method:

+ (SceneDelegate *)shared {
    return (SceneDelegate *)UIApplication.sharedApplication.connectedScenes.allObjects.firstObject;
}

Note: Don't forget to import SceneDelegate.h and add the shared property to its interface.


You can also just cast it inline like (SceneDelegate *)self.view.window.windowScene.delegate

Solution 2:[2]

Here's how you can check wether the object is kind of the desired class:

UIScene *scene = [[[[UIApplication sharedApplication] connectedScenes] allObjects] firstObject];
if ([scene.delegate isKindOfClass:SceneDelegate.class]) {
    SceneDelegate *delegate = (SceneDelegate *)scene.delegate;
    NSToolbar *toolbar = delegate.mainToolbar;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Pylyp Dukhov