3

I am currently wrapping a webApp up as an app. With in the web app there is a button that when clicked automatically asks if you want to go to the camera of the stored images and when selected will upload the image for you. In the web app from the phone browser this works as expected.

Now I have wrapped the webApp up in a UIWebView this function no longer works. It actually appears to close the UIWebview when selecting either of the above options. Does anyone know what the procedure is to get this to work through the UIWebView.

Do I have to give permission? Or is there more to it like detecting the HTML when the button is clicked and handling it from the UIWebView.

The HTML on the button looks like this.

   <input type="file" required id="file" name="file" accept="image/*" multiple>

ADDED CODE

WebViewController.h

 #import <UIKit/UIKit.h>

 @interface WebViewController : UIViewController <UIWebViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>
{
    UIViewController *viewController;
}

........

WebViewController.m

 #import "WebViewController.h"
 #import <AssetsLibrary/AssetsLibrary.h>
 #import "AppDelegate.h"
 @end
 @implementation WebViewController


 - (void)viewDidLoad
 {
      [super viewDidLoad];
      viewController = [[UIViewController alloc] init];   
      NSString *fullURL = self.mainURL; // get this from defualts - have removed code for this




NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];

ALAssetsLibrary *lib = [[ALAssetsLibrary alloc] init];

[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
    NSLog(@"%i",[group numberOfAssets]);
} failureBlock:^(NSError *error) {
    if (error.code == ALAssetsLibraryAccessUserDeniedError) {
        NSLog(@"user denied access, code: %i",error.code);
    }else{
        NSLog(@"Other error code: %i",error.code);
    }
}];
 }
  -(void)webViewDidStartLoad:(UIWebView *)viewWeb
 {
      [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
 }
 - (void)webViewDidFinishLoad:(UIWebView *)viewWeb
 {

 }






 //Note: I check to make sure the camera is available.  If it is not (iPod touch or Simulator) I show the photo library instead.
 -(void) showCamera
 {
     UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
     if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
     {
         imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
     }
     else
     {
          imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
     }
     imagePicker.delegate = self;
     [viewController presentViewController:imagePicker animated:YES completion:nil];
 }

  //Here we intercept any time the webview tries to load a document.  When the user hits our "showcamera: url" we go to work.
  - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:
  (UIWebViewNavigationType)navigationType
  {
        if ([request.URL.scheme isEqualToString:@"myApp"])
        {
            if ([request.URL.host isEqualToString:@"myFunction"])
            {
                [self showCamera];
            }
            return NO;
        }
        return YES;
   }

 //After the imagepicker has done it's thing, we pass the data back to the webview to be displayed.
 //If we wanted to be fancy here, we could have done this via Javascript so we could dynamically insert an image without reloading the page.
 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [viewController dismissViewControllerAnimated:YES completion:nil];
    UIImage* image = [info objectForKey:UIImagePickerControllerOriginalImage];
    NSData *imageData = UIImageJPEGRepresentation (image, 0.5);
    NSURL *tmp = [NSURL URLWithString:@"ignore"];
    [_viewWeb loadData:imageData MIMEType:@"image/jpeg" textEncodingName:@"UTF-8" baseURL:tmp];
   }
   @end

I have removed some code that was irrelevant

Rob85
  • 1,719
  • 1
  • 23
  • 46

2 Answers2

7

I have managed to fix the issue and it goes way back to bug that was found in iOS 8 that still hasn't been fixed. Its to do with how the UIWebView is being presented.

Adding this code fixed it.

 -(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
 {
     if ( self.presentedViewController)
     {
         [super dismissViewControllerAnimated:flag completion:completion];
     }
 }

For any one else confused or struggling with this Note that you do not need to start messing around with UIImagePicker or UIWebView delegates. Your web view should take care of opening the camera library or camera. This was a real pain of an issue so hopefully this may help others in my position. you can also see THIS Question as this is where i got my answer from. Thanks Andrey for helping too

Community
  • 1
  • 1
Rob85
  • 1,719
  • 1
  • 23
  • 46
2

As an alternative you can try to use UIWebViewDelegate's method webView:shouldStartLoadWithRequest:navigationType: to catch custom events:

In your HTML:

<a href="myApp://myFunction">Do something</a>
<button onclick="window.location.href='myApp://myFunction'">Do some action</button>

And then:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([request.URL.scheme isEqualToString:@"myApp"]) {
        if ([request.URL.host isEqualToString:@"myFunction"]) {
            // do something
        }
        return NO;
    }
    return YES;
}
Andrey Gershengoren
  • 896
  • 1
  • 5
  • 18