How to tell when UIWebView has finished displaying content - objective-c

I'm making a UIWebView load a pdf like this:
UIWebView *pdfView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
pdfView.delegate = self;
[pdfView loadRequest:request];
And then doing some stuff with the view once it loads:
- (void)webViewDidFinishLoad:(UIWebView*)sender {
[sender takeScreenshot]; // my UIView category screenshot method
[sender release];
}
It all works, apart from the fact that at the point webViewDidFinishLoad is called, the view hasn't displayed anything yet, it displays a few milliseconds later. So is there any way to tell when the UIWebView has finished displaying its content (a pdf in this case)?

You could do:
[self performselector:#selector(getScreenshot) withObject:sender afterDelay:0.1];
-(void) getScreenshot:(UIWebView *)webView {
[webView takeScreenshot];
[webView release];
}
Or something similar.

Related

HTTP load failed and I have tried all of the SO suggestions, but nothing works

Error 9802 is a "Fatal Alert" according to the Apple's docs. I have looked at Google and SO and found nothing referencing 9802 that fixes this problem. I can change my code to go for "apple.com" and I get the page, but using my own URL, I get the error above. I have tried everything that I can think of, and nothing works. Time to ask for help! :D
The result of using
/usr/bin/nscurl --ats-diagnostics https://pragerphoneapps.com
is all tests fail (results are uploaded here)
This is an image of my app's .plist file (only pertinent part)
and this is an image of the target info:
And this is my code:
- (IBAction)showHTMLHelp:(UIButton *)sender {
// make the popover
UIViewController* popoverContent = [UIViewController new];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 450, 500)];
popoverView.backgroundColor = [UIColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)1.0]; // frame color?
popoverContent.view = popoverView;
//resize the popover view shown in the current view to the view's size
popoverContent.preferredContentSize = CGSizeMake(450, 500);
NSString *urlAddress = #"https://pragerphoneapps.com"; // #"https://www.pragerphoneapps.com/bookstore-inventory-manager/upload-help/";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
// add the UIWebView for RichText
UIWebView *webView = [[UIWebView alloc] initWithFrame: popoverView.frame];
webView.backgroundColor = [UIColor whiteColor]; // change background color here
// add the webView to the popover
[webView loadRequest:requestObj];
[popoverView addSubview:webView];
// if previous popoverController is still visible... dismiss it
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
}
//create a popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
[popoverController presentPopoverFromRect:((UIButton *)oShowHelp).frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
I seriously recommend you to fix your SSL certificate.
ATS requires you to have a valid SSL certificate, TLS version 1.2 or above and support for forward secrecy.
This will be a requirement at the beginning of 2017 so better get ready.
Anyway, meanwhile try the following steps to get this working.
Put this on top of your file:
#interface NSURLRequest (InvalidSSLCertificate)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
#end
Disable App Transport Security in Info.plist.
Allow invalid SSL certificates before loading request:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
Sample code that successfully loads your site:
NSString *urlAddress = #"https://pragerphoneapps.com"; // #"https://www.pragerphoneapps.com/bookstore-inventory-manager/upload-help/";
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
UIWebView *webView = [[UIWebView alloc] initWithFrame: self.view.frame];
webView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:webView];
[webView loadRequest:requestObj];
I wonder why it can't work for setting "NSAllowArbitraryLoads to YES".If there are caches, try to reboot your Mac or Xcode.
And your "Exception Domains" settings have the wrong format.

Why does createWebviewWithConfiguration not change the displayed view when window.open is called?

I'm quite new to WKWebView and am struggling with this problem where my current view doesnt change when invoking windows.open from javascript see below...
function logo_click() {
window.open(some_valid_url);//url is valid www.google.com for example
}
I'm quite sure that this function is hit since I stepped on it using Safari Tech Preview. And I'm even getting the breakpoint in my createWebviewWithConfiguration() function in xcode obj-c when logo_click is invoked,
-(WKWebView*)webView:(WKWebView )webView createWebViewWithConfiguration:(nonnull WKWebViewConfiguration )inConfig forNavigationAction:(nonnull WKNavigationAction )navigationAction windowFeatures:(nonnull WKWindowFeatures )windowFeatures
{
_webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:inConfig];
if (!navigationAction.targetFrame.isMainFrame) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self.webView loadRequest:navigationAction.request];
//[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.google.com"]]];
}
return _webView;
}
I even tried hardcoding google.com to see if it can navigate from there but my displayed view is still the previous one. I already checked the tutorial on
iphonedevsdk.com/forum/iphone-sdk-development/122635-wkwebview-wont-open-external-links.html
but my view still doesn't change. What could I be missing?
I solved it using the following code...
-(WKWebView*)webView:(WKWebView *)webView createWebViewWithConfiguration:(nonnull WKWebViewConfiguration *)inConfig forNavigationAction:(nonnull WKNavigationAction *)navigationAction windowFeatures:(nonnull WKWindowFeatures *)windowFeatures
{
[_webView removeFromSuperview];
_webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:inConfig];
if (!navigationAction.targetFrame.isMainFrame) {
//[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLRequest* req = navigationAction.request;
[self.webView loadRequest:req];
}
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
_webView.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:_webView];
return _webView;
}

Javascript return a string to objective c

i got a webview and i would like to capture an input from a webview HTML form. i have tried but i cant can some one help me please
this is my webview code
// Init Web View
UIWebView *webView;
webView = [[UIWebView alloc] initWithFrame:boundsRect];
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
webView.scalesPageToFit = YES;
webView.contentMode = UIViewContentModeCenter;
webView.multipleTouchEnabled = NO;
webView.userInteractionEnabled = YES;
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
[self addSubview:webView];
[webView release];
return self;
To get value from webView, i used below code.
NSString* value = [webView stringByEvaluatingJavaScriptFromString:#"document.getElementById('text').value"]‌​;
NSLog(#"got: %#",value);
You could look into how phonegap http://phonegap.com/ solves this.

UIWebView loads HTML from local file but fails occasionally

I've come across many ways to load and reload the content of a UIWebView from a local html file but it seems like the issue I have keeps coming back.
On my project I have a webView that dynamically loads HTML content pulled from one of the 50 different HTML files I have in my XCode project.
Depending on which button the user presses on the viewController before, a different HTML file is used to reload the content of my webView. Everything works fine most of the time but every now and then, the webView will simply display "(null)", after the webViewDidFinishLoad delegate method is called.
I don't understand what is going on, and when I go back and forth on this viewController and the webView is reloaded the HTML content ends up showing up properly eventually for the same HTML file.
Here is the code to load the HTML in the webView (called from the viewWillAppear method) :
- (void) reloadWebViewFromLocalFile{
// Reset the UIWebView
[self.contentWebView removeFromSuperview];
self.contentWebView = nil;
self.contentWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 1)];
[self.contentWebView setContentMode:UIViewContentModeScaleAspectFit];
[self.contentWebView setDelegate:self];
[self.contentScrollView addSubview:self.contentWebView];
[self.contentWebView release];
NSString *fileName = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d.%d",self.currentIndexPath.section+1,self.currentIndexPath.row+1] ofType:#"html"];
NSString *CSSContent = [NSString stringWithFormat:#"<style type=\"text/css\">body{padding-left:8px;padding-right:8px;font-family:\"%#\";}p{text-align:justify;}img{max-width:300px;display:block; margin:auto;}strong{font-family:\"%#\";}h1{font-size:20;font-family:\"%#\"}h2{font-size:18;font-family:\"%#\"}h3{font-size:17;font-family:\"%#\"}</style><script type=\"text/javascript\">touchMove = function(event) {event.preventDefault();}</script>", FONT_STAG_BOOK, FONT_STAG_SEMIBOLD, FONT_STAG_SEMIBOLD, FONT_STAG_SEMIBOLD, FONT_STAG_SEMIBOLD];
self.HTMLString = [NSString stringWithFormat:#"<html><head>%#</head>%#</html>",CSSContent,[NSString stringWithUTF8String:[[NSData dataWithContentsOfFile:fileName] bytes]]];
[self.contentWebView loadHTMLString:self.HTMLString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
}
and this is the webViewDidFinishLoad delegate method :
- (void)webViewDidFinishLoad:(UIWebView *)webView{
NSString *stringContent = [self.contentWebView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML"];
float height = [[self.contentWebView stringByEvaluatingJavaScriptFromString:#"document.body.offsetHeight;"] floatValue] + 20;
[self.contentWebView setFrame:CGRectMake(0, 0, 320, height)];
[self.contentScrollView setContentSize:CGSizeMake(0, height+self.nextButton.frame.size.height)];
[self.nextButton setFrame:CGRectMake(0, height, 320, self.nextButton.frame.size.height)];
if ([self.contentWebView respondsToSelector:#selector(scrollView)]) {
self.contentWebView.scrollView.scrollEnabled = NO; // available starting in iOS 5
} else {
for (id subview in self.contentWebView .subviews)
if ([[subview class] isSubclassOfClass: [UIScrollView class]])
((UIScrollView *)subview).scrollEnabled = NO;
}
}
Edit : Forgot to copy-paste the line that actually loads the HTML string in the webView
The problem seems to be using the bytes function, which doesn't work too well if the content encoding isn't exact...
[NSString stringWithUTF8String:[[NSData dataWithContentsOfFile:fileName] bytes]];
should be
[[NSString alloc] initWithData:[NSData dataWithContentsOfFile:fileName] encoding:NSUTF8StringEncoding];

iOS: Force UIWebView to reload / prevent caching

I have an iPhone app that shows a website. This website changes it's content from time to time but my app doesn't reload it every time it is opened. I tried to prevent the caching of the site, but without success.
This is my init method:
- (id)init:(NSString *)url withTitle:(NSString *)theTitle withPageName:(NSString *)pageName {
self = [super init];
if(self) {
NSLog(#"websiteviewcontroller init");
self.title = theTitle;
self.url = url;
self.pageName = pageName;
CGRect frame = [[UIScreen mainScreen] applicationFrame];
webView = [[UIWebView alloc] initWithFrame:frame];
NSURL *theURL = [NSURL URLWithString:url];
[webView loadRequest:[NSURLRequest requestWithURL:theURL]];
// support zooming
webView.scalesPageToFit = YES;
//[[NSURLCache sharedURLCache] removeAllCachedResponses];
[webView reload];
}
return self;
}
This is my viewWillAppear-Method:
- (void)viewWillAppear:(BOOL)animated {
CGRect frame = [[UIScreen mainScreen] applicationFrame];
webView = [[UIWebView alloc] initWithFrame:frame];
NSURL *theURL = [NSURL URLWithString:url];
[webView loadRequest:[NSURLRequest requestWithURL:theURL]];
[webView reload];
// support zooming
webView.scalesPageToFit = YES;
}
Please help me to solve this problem. All answers are much appreciated.
This code snipplet fixed my problem:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
The answer is just for the next question. For a ore complete answer:
UIwebview without Cache