Adding UIWindow to JuceAppStartupDelegate


I'm using React Native to build the main UI of my app, which is working quite well, however I have an issue where if there is a JS error in Debug mode, I can't hit `Reload` from the React Native error view as its already crashed the app. This is because React is assuming the app has a standard AppDelegate with a window property e.g. 

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


The exception is coming from JuceAppStartupDelegate: 

exception 'NSInvalidArgumentException', reason: '-[JuceAppStartupDelegate window]: unrecognized selector sent to instance

And its caused by this bit of code in React Native:

- (void)dismiss
  self.hidden = YES;

  [self resignFirstResponder];

  [RCTSharedApplication().delegate.window makeKeyWindow]; // <-- crash here

I started by adding a window property to JuceAppStartupDelegate

@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate>
    UIWindow *window;

But then of course I can't make a reference to it in my MainWindow class (where I am initialising a UIWindow already) as its not included in the JuceHeader. 

I'm not sure how to proceed with this, I wonder if I need to create my own subclass of JUCEApplicationBase? 


p.s. any plans to give us some nice syntax highlighting on the forum? 


So I found a simple solution that works for now - just comment the offending line out! 

- (void)dismiss
  self.hidden = YES;
  [self resignFirstResponder];
  //[RCTSharedApplication().delegate.window makeKeyWindow];

I can now reload the app after a JS error without having to restart it in Xcode. Its great having such fast iterations, one of the big selling points of React Native. A bit like Projucer live build for mobile development, but without any rebuilding going on! 


So I've come up against this error again. This time due to a library I'm trying to use that expects the AppDelegate to have a window property.

Back to my original question:

How can I add a window property to JuceAppStartupDelegate and have it accessible from my MainWindow class so that I can instantiate it?


It's not something we have a mechanism for.. If you can suggest a clean way to add the functionality you need, then let us know, but it sounds like a tricky thing to implement in a nice clean way!


Ok thanks, I'll see what I can come up with.


I've just created a pull request, see what you think, it works for my purposes.




Solved with the help of @fabian - I didn’t realise its possible to cast the base UIApplicationDelegate class which has the window property. So if you are doing your own MainWindow initialisation for iOS like I am you can do something like this:

NSObject<UIApplicationDelegate> *appDelegate = [[UIApplication sharedApplication] delegate];

appDelegate.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
appDelegate.window.backgroundColor = [UIColor whiteColor];


I thought this issue was solved but I was still using my own fork of JUCE.

I now realise all thats needed for the above code to work is to add the window property to JuceAppStartupDelegate, i.e.

@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

- (void) applicationDidFinishLaunching: (UIApplication*) application;
- (void) applicationWillTerminate: (UIApplication*) application;
- (void) applicationDidEnterBackground: (UIApplication*) application;
- (void) applicationWillEnterForeground: (UIApplication*) application;
- (void) applicationDidBecomeActive: (UIApplication*) application;
- (void) applicationWillResignActive: (UIApplication*) application;



Is that something JUCE team would consider adding?


Yup it’s on the develop branch


Thanks! :sunglasses: