ofxiOSEAGLView's window is null after reinitialising a ofxiOSViewController instance

Hey everyone,

Probably a bit of a different use-case than what the iOS version of oF is used for, but I was wondering if anybody can give me a hint of what’s happening in my app.

I have the AppDelegate that initialises the app with a non-oF view controller and then a method startOFView which, if called, changes the view controller:

-(void) startOFView:(bool)demo:(NSString *)colorProfile {
  [self.navigationController pushViewController:self.nativeViewController animated:true];
}

The nativeViewController's role is to launch the oF view and to perform some logic after the User gets out of the oF view. So here is the place where the ofxiOSViewController instance and the ofApp are instantiated.

The ofApp is basically a camera feed that does some tracking with openCV and it’s started in the nativeViewControlle with the following method:

- (void)switchToCamera:(id)sender {
  [self.navigationController setNavigationBarHidden:NO animated:YES];
  
  self.cameraApp = new Camera(self.demo, std::string([self.colorProfile UTF8String]));
  self.cameraViewController = [[CameraViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds] app:self.cameraApp];
  
  [self.navigationController pushViewController:self.cameraViewController animated:YES];
  self.navigationController.navigationBar.topItem.title = @"End Task";
}

The CameraViewController definition is basic:

#import "ofxiOSViewController.h"

@interface CameraViewController : ofxiOSViewController

@end

This works perfectly when starting the oF view controller with the camera app for the first time, but when I return to the root view (the non-oF view) and want to come back to the ofView, I get an error because the ofAppiOSWindow instance is null all of a sudden.

This worked fine pre-iOS 13 so I assume some new APIs are messing up the way oF initialises the Window. It seems that when I create a new instance of ofxiOSViewController, it comes with a null window.

Let me know if this doesn’t make sense and if I can clarify anything. Will appreciate any help on this one :pray:

UPDATE: I though of adding some traces of what’s happening

First, I initialise my ViewController where app is the Camera app I was talking about before.

- (id) initWithFrame:(CGRect)frame app:(ofxiOSApp *)app {
  return self = [super initWithFrame:frame app:app]; // error triggered here
}

The call to the superclass initWithFrame causes the error. So in ofxiOSViewController this happens:

- (id)initWithFrame:(CGRect)frame app:(ofxiOSApp *)app {
    [self initWithFrame:frame app:app sharegroup:nil]; // error triggered here
    return self;
}

It goes further in the ofxiOSViewController:

- (id)initWithFrame:(CGRect)frame app:(ofxiOSApp *)app sharegroup:(EAGLSharegroup *)sharegroup{
    currentInterfaceOrientation = pendingInterfaceOrientation = UIInterfaceOrientationPortrait;
    if((self = [super init])) {
        currentInterfaceOrientation = pendingInterfaceOrientation = self.interfaceOrientation;
        if( [[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] == NSOrderedAscending ) {
            bReadyToRotate  = NO;
        }else{
            bReadyToRotate  = YES;
        }
        bFirstUpdate    = NO;
        bAnimated       = NO;
        self.glView = [[[ofxiOSEAGLView alloc] initWithFrame:frame andApp:app sharegroup:sharegroup] autorelease];
        
        // error below
        [self.glView setMultipleTouchEnabled:ofxiOSGetOFWindow()->isMultiTouch()]; // error triggered here
        self.glView.delegate = self;
    }
    
    return self;
}

And lastly:

bool ofAppiOSWindow::isMultiTouch() {
	return settings.enableMultiTouch;
}

The console says: [ fatal ] ofxiOSEAGLView::initWithFrame - window is NULL

Also, this only happens the second time I start the Camera view. The first time everything works normally. And this worked perfectly prior to iOS 13, so no idea what has changed. I’m guessing something to do with the memory management and I need to look more into making sure I clean everything and instantiate everything properly again.

Edit: Looking at the ofAppiOSWindow implementation, it looks like it follows the singleton pattern, so it seems that the instance is cleaned after the first launch of the camera and then it stays set to null even though I re-create everything.

Another Update: Managed to work around the problem

I was debugging with some breakpoints and I could see that the close() method was being called for the main window, hence the null. So I modified the init method in my ViewController to check whether the window is null and re-initialise the oF app - basically copy the main.m code all over again.

- (id) initWithFrame:(CGRect)frame app:(ofxiOSApp *)app {
  if (ofAppiOSWindow::getInstance() == NULL) {
    ofiOSWindowSettings settings;
    settings.enableRetina = true; // enables retina resolution if the device supports it.
    settings.enableDepth = false; // enables depth buffer for 3d drawing.
    settings.enableAntiAliasing = true; // enables anti-aliasing which smooths out graphics on the screen.
    settings.numOfAntiAliasingSamples = 4; // number of samples used for anti-aliasing.
    settings.enableHardwareOrientation = false; // enables native view orientation.
    settings.enableHardwareOrientationAnimation = false; // enables native orientation changes to be animated.
    settings.glesVersion = OFXIOS_RENDERER_ES2; // type of renderer to use, ES1, ES2, etc.
    
    ofAppiOSWindow * window = (ofAppiOSWindow *)(ofCreateWindow(settings).get());
    window->startAppWithDelegate("AppDelegate");
  }
  return self = [super initWithFrame:frame app:app];
}

Doesn’t look that elegant, but works until I find another way to prevent the window from getting closed. Or maybe it’s actually better memory-wise to re-initialise the whole thing.