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;

@end

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? 

Thanks

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.

https://github.com/julianstorer/JUCE/pull/62

 

 

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;

@end

(https://github.com/julianstorer/JUCE/pull/86)

Is that something JUCE team would consider adding?

Yup it’s on the develop branch

1 Like

Thanks! :sunglasses: