ffranz ffranz - 3 months ago 44
Objective-C Question

I need help modifying the InAppBrowser in native code




this is a different question but is still regarding my original problem:

Is there an elegant way to access the camera from the inappbrowser under iOS?

tl;dr: I want to open the cordova camera plugin on top of the inappbrowser plugin(view hierarchy problem)


After my first approach (old question) did not lead me anywhere, I tried to modify the inappbrowser (gitlink). I wanted it to be a subview of the cordova view, which the following code managed to accomplish:


__weak CDVInAppBrowser* weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf.inAppBrowserViewController != nil) {
//[weakSelf.viewController presentViewController:nav animated:YES completion:nil];
[self.viewController.view addSubview:self.inAppBrowserViewController.view];
}
});


To close the inappbrowser I use my modified close method:

- (void)close:(CDVInvokedUrlCommand*)command
{
if (self.inAppBrowserViewController != nil) {
UIView *lastView;
for(UIView *subview in [self.viewController.view subviews]) {
lastView = subview;
}
[lastView removeFromSuperview];

if (self.callbackId != nil) {
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:@{@"type":@"exit"}];
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}

self.inAppBrowserViewController.navigationDelegate = nil;
self.inAppBrowserViewController = nil;
_previousStatusBarStyle = -1;
}
}


Please keep in mind that I have no experience in objective c and do not really know what I am doing, I will be grateful for any hints.


Both modifications work as expected, I am able to show the camera plugin on top of the inappbrowser and get the image to it and also trigger the
exit
event of the plugin on closing.


The following tasks are now working:


  • open inappbrowser

  • trigger camera from inappbrowser

  • get image to inappbrowser

  • close inappbrowser



BUT if I want to open the inappbrowser again (without restarting the app), the subview opens but does not show anything, just a blank page. It works again when I restart the app, but every time the inappbrowser opens after closing the app only shows a blank screen.

I suspect there are some residuals of the inappbrowser which are the cause of the problem.
I see 2 possible solutions here:


  • delete everything concernig the inappbrowser on closing

  • reinitialize the inappbrowser overwriting everything on every start



I do not know how to implemet either.

Can somebody please help me or point in the general direction of a possible solution.



p.s.: I know that this is not the intended behaviour of the inappbrowser since it wants to make calls to the native api impossible, but I need it this way. Iframes or closing the inappbrowser to get the camera is no option.

Answer

I figured it out! You have to modify the show method of CDVInAppBrowser:

dispatch_async(dispatch_get_main_queue(), ^{
    if (weakSelf.inAppBrowserViewController != nil) {
        //[weakSelf.viewController presentViewController:nav animated:YES completion:nil];
        self.inAppBrowserViewController.view.frame = CGRectMake(0,20,self.inAppBrowserViewController.view.frame.size.width,self.inAppBrowserViewController.view.frame.size.height-20);            
        [self.viewController.view addSubview:self.inAppBrowserViewController.view];
    }
});

Just remove the commented line and add the 2 following the commented line. In the close method of CDVInAppBrowser you have to add:

UIView *lastView;
for(UIView *subview in [self.viewController.view subviews]) {
    lastView = subview;
}
[lastView removeFromSuperview];

right before [self.inAppBrowserViewController close];.
Done, the camera now opens on top of the inappbrowser and passes the image to it.

Comments