UIWebView opening the camera and images when a button is clicked - html

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

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

As an alternative you can try to use UIWebViewDelegate's method webView:shouldStartLoadWithRequest:navigationType: to catch custom events:
In your HTML:
Do something
<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;
}

Related

I am trying to Load html string into a webview. But the webview shows a white blank colour on run time

I am trying to Load html string into a webview. But the webview shows a white blank colour on run time. added the UIWebViewDelegate and declare object like this.
#property (strong, nonatomic) IBOutlet UIWebView *aboutWebView;
but still having the same issue.
- (void)viewDidLoad {
[super viewDidLoad];
[[self navigationController] setNavigationBarHidden:YES animated:YES];
[_aboutWebView setDelegate:self];
[self loadWebView];
// Do any additional setup after loading the view.
}
-(void)loadWebView{
_aboutWebView= [[UIWebView alloc]init];
_aboutWebView.backgroundColor= [UIColor blueColor];
NSString *embedHTML= #"html Code";
[_aboutWebView loadHTMLString: embedHTML baseURL: nil];
}
Please remove the below line from your code.It works for you.
_aboutWebView= [[UIWebView alloc]init];
Set the web-view delegate after initialising it , and add this line of code [webView setScalesPageToFit:YES];
There is no need for allocating your webview again in loadWebView method of yours.
comment this line "_aboutWebView= [[UIWebView alloc]init]".
You are already creating an IBOutlet for your webview which automatically creates an object for view.
Have below in HTML String
<head><style type='text/css'>body {background-color: transparent;border: 0px;margin: 0px;padding: 0px;}</style></head>
And for webview have this
yourWebView.backgroundColor = [UIColor clearColor];
yourWebView.opaque = NO;
This will not show white color in run time...
First at all,your HTML format is not correct,writing correct HTML to load on webView.
Then,add self.view.backgroundColor=[UIColor whiteColor]; in function - (void)viewDidLoad.
Hope to help you!

Pass Variable (cookie) from local html to UILabel - iOS

I wanted to know how I could go about passing a Variable (cookie) in a local HTML file in my iOS App, and pass what the cookie says onto a UILabel. Here is what the HTML code is. I need to pass this message into a UILabel
<script language="javascript">setCookie('Test','You Sir have succeeded. Congratulations.', 300);
</script>
And here is my updated code for iOS app
Header File:
import
#interface ViewController : UIViewController {
IBOutlet UIWebView *webView;
IBOutlet UILabel *mylabel;
}
#end
Main File
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"DTPContent/cookietest" ofType:#"html"]isDirectory:NO]]];
[super viewDidLoad];
NSString *myCookie = [self->webView stringByEvaluatingJavaScriptFromString:#"getCookie('Test')"]; self->mylabel.text = myCookie;
}
#end
Thank You in Advance!
Assuming you already have a javascript function to get the cookies, like that, you can simply execute the javascript with webview's method stringByEvaluatingJavaScriptFromString , get it's returned string and set it in a UILabel.
It will be something like this:
NSString *myCookie = [self.webView stringByEvaluatingJavaScriptFromString:#"getCookie('Test')"];
self.mylabel.text = myCookie;

How to load a second view controller with a swipe gesture?

I have a Tabbed Based application and I want to use swipe gestures to navigate through the view controllers.
I tried:
- (IBAction)swipeLeftDetected:(UIGestureRecognizer *)sender {
UISecondViewController *second =[[UISecondViewController alloc] initWithNibName:#"UISecondViewController" bundle:nil];
second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second animated:YES];
}
paired with this:
- (void)viewDidLoad; {
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeftDetected:)];
swipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeRecognizer];
}
But it crashes on the swipe. Any help? Thanks!
Your code works well on my Xcode.
Only changed:
UISecondViewController *second =[[UISecondViewController alloc] initWithNibName:#"UISecondViewController" bundle:nil];
to:
SecondViewController *second =[[SecondViewController alloc] init];
because I don't have the UISecondViewController class.
Just verify there is UISecondViewController.xib in your project, otherwise it will crash.
But I'm not sure here is your problem.

Injecting local files into UIWebView without breaking links

I am working on an iOS app that needs to display webpages from a server inside a UIWebView while injecting relevant local png and css files as needed in order to speed up load time. Here is the code I am using to try to do this:
NSData *myFileData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.example.com/index.html"]]];
NSString* myFileHtml = [[NSString alloc] initWithData:myFileData encoding:NSASCIIStringEncoding];
[myWebView loadHTMLString:myFileHtml baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
My problem is that some of the webpages have buttons in them that link to other webpages on the server, and because the UIWebView is only loading a string, the buttons when tapped don't cause the UIWebView to load the new webpage URL like it would if I had used the loadRequest method.
My question is how can I get the the UIWebView to behave like it is loading a request while still injecting local files from the baseurl?
Thanks
The relative links in the button cannot work, because the linked pages are on a remote server and not on the device's file system. However you can use a UIWebViewDelegate method to make it work:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSString *localRootPath = [NSString stringWithFormat:#"file://%#", [[NSBundle mainBundle] bundlePath]];
NSString *remoteRootPath = #"http://yourdomain.com";
NSString *remotePath = [[request.URL absoluteString] stringByReplacingOccurrencesOfString:localRootPath withString:remoteRootPath];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:remotePath]]];
// or you can use your own loading mechanism here
return NO;
}
return YES;
}
This method intercepts all requests from your WebView. If the request was triggered by a user tap / click the URL gets modified from a relative URL to a absolute URL so it can be loaded from the server. Don't forget to set the delegate on the WebView or this method will not be called.
NSURLPRotocol is a handler for NSURLConnection and will give you the opportunity to intercept the calls to the server and substitute your own content.
1) Derive a class from NSURlProtocol
2) Call NSURLProtocol registerClass: in your application:didFinishLaunchingWithOption
3) Read the documentation on implement these methods as necessary:
initWithRequest:cachedResponse:client:,
startLoading,
URLProtocol:didReceiveResponse:cacheStoragePolicy:
URLProtocolDidFinishLoading:

How to make links shown in phonegaps childbrowser open in Safar?

I have a phone gap app which loads an HTML 5 app in a child browser. Links which are on the pages loaded in the child browser also load in the child browser. I would like these links to open in Safari. How could i do that?
Thanks
You just need to add this in your AppDelegate.m
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
// Intercept the external http requests and forward to Safari.app
// Otherwise forward to the PhoneGap WebView
if ([[url scheme] isEqualToString:#"http"] || [[url scheme] isEqualToString:#"https"]) {
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else {
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
}
Hope this helps