how does one check if UIWebView is empty or not - ios

I need to check if a webview when completed loading has any content or not.
What I require is simple. Its a small webview strip at the bottom of my pages (like an advert)
I call
NSURLRequest *request=[NSURLRequest requestWithURL:adURL];
[gWebView loadRequest:request];
I get the callback
-(void)webViewDidFinishLoad:(UIWebView *)webView {
But in my scenario the webview shall return empty and sometime it shall have data.
I do not want to show the webview if my server php file returned nothing.
How can I verify that I received an empty page in the callback (or any other way)?

If you are loading a HTML page:
NSString *string = [myWebView stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('html')[0].innerHTML"];
BOOL isEmpty = string==nil || [string length]==0;
Or you could load the content first, test if it is not empty, and then feed it to the webview. See UIWebView's loadHTMLString:baseURL: or loadData:MIMEType:textEncodingName:baseURL:.

This is based on Jano's approach but should perform better:
NSString *script = #"document.getElementsByTagName('body')[0].innerHTML.length";
NSString *length = [self.webView stringByEvaluatingJavaScriptFromString:script];
if (length.integerValue > 0) {
NSLog(#"not empty");
}

Just replying to an old post, but maybe new arrivals will find it useful. I struggled with the same problem and found this solution to work in my case:
if (webView.request.URL.absoluteURL == nil) {
NSLog(#"nil webby");
NSLog(#"url: %#", webView.request.URL.absoluteURL);
// Perform some task when the url is nil
} else {
NSLog(#"loaded webby");
NSLog(#"url: %#", webView.request.URL.absoluteURL);
// Perform some task when the url is loaded
}
You can call it from the webViewDidFinishLoad: method.

In my case, I was looking to detect if the PDF was malformed. I.e., the web view would be empty because the PDF could not be loaded. Since with iOS 7.1.1, I wasn't getting the didFailLoadWithError delegate callback, I needed a different way to do this. I ended up using the method below before attempting to load the PDF doc into the web view.
// See https://developer.apple.com/library/ios/documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html
- (BOOL) isValidPDFDoc: (NSURL *) deviceLocalURL {
CFStringRef path;
CFURLRef url;
CGPDFDocumentRef document;
size_t count;
BOOL validDocument = YES;
// Must use path of URL not absoluteString here.
path = CFStringCreateWithCString (NULL, [[deviceLocalURL path] cStringUsingEncoding:NSASCIIStringEncoding],
kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath (NULL, path, // 1
kCFURLPOSIXPathStyle, 0);
CFRelease (path);
document = CGPDFDocumentCreateWithURL (url);// 2
if (!document) {
validDocument = NO;
}
CFRelease(url);
count = CGPDFDocumentGetNumberOfPages (document);// 3
if (count == 0) {
validDocument = NO;
}
CGPDFDocumentRelease (document);
return validDocument;
}

Related

AVAssetResourceLoaderDelegate: Not playing video

I'm trying to do a simple implementation of AVAssetResourceLoaderDelegate on OSX/iOS as a sort of sanity check before continuing to implement a more complex version. I figured I would start by just making it load the full video file in one big read. To my surprise I haven't been able to get this to work.
Here's my code:
- (BOOL) resourceLoader:(AVAssetResourceLoader *)resourceLoader shouldWaitForLoadingOfRequestedResource:(nonnull AVAssetResourceLoadingRequest *)loadingRequest
{
NSString* path = #"/Users/andrew/Projects/work/videotextureplugin-streaming/unityProject/Assets/StreamingAssets/BigBuckBunny_640x360.m4v";
AVAssetResourceLoadingDataRequest* dataRequest = loadingRequest.dataRequest;
AVAssetResourceLoadingContentInformationRequest* contentRequest = loadingRequest.contentInformationRequest;
// handle content request
if (contentRequest)
{
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:NULL];
unsigned long long fileSize = [attributes fileSize]; // in bytes
NSLog(#"File Size: %llu", fileSize);
contentRequest.contentType = #"com.apple.m4v-video";
contentRequest.contentLength = fileSize;
contentRequest.byteRangeAccessSupported = NO;
}
// handle data request
if (dataRequest)
{
NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path];
NSData* requestedData = [file readDataToEndOfFile];
NSLog(#"Requested data length: %lu", (unsigned long)[requestedData length]);
[loadingRequest.dataRequest respondWithData:requestedData];
[loadingRequest finishLoading];
}
return YES;
}
The file size and data length values are correct when they print. It just says "AVPlayer ready to play but has zero video tracks" in the log. I've tried a few different video files, as well as various contentType settings with no luck. All of the files I've tested work fine if I open them via a URL like "file:///" followed by the same path used above.
Thanks in advance for any assistance or advice on debugging this.

IOS Use variable take in method webViewDidFinishLoad

I have two webView, in the first i load an hostname and, when webViewDidFinishLoad i take a part of current url with this method:
//Method that take a part of currentUrl of a webView
- (NSString *) webViewGetLocation {
NSString *html = [dnsWebView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML"];
if ([html rangeOfString:#"Account"].location != NSNotFound) {
//Take loaded ip
NSString *currentURL = [dnsWebView stringByEvaluatingJavaScriptFromString:#"window.location.href"];
NSLog(#"IP TAKEN: %#", currentURL);
//Do substring to find part of ip, until the port
NSString *ip = [[self splitString: currentURL key: #"/login"] objectAtIndex: 0];
NSLog(#"IP AND PORT: %#", ip);
}
return ip;
}
and at this time all ok.
Now in the second webView, i load an url that should be composed by the ip, that i take in previous method, and a second part that not change.
My problem is: how can i take that url (return ip), since i have launched method "webViewGetLocation" in method "webViewDidFinishLoad" that do not have a return value???
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self webViewGetLocation];
}
I try to save returned ip of method "webViewGetLocation" in an appDelegate variable, but in viewDidLoad it is empty.
Thats easy, create a class property of type NSURL in your .h file
Then set it in - (void)webViewDidFinishLoad:(UIWebView *)webView {
NSURL *url = [NSURL URLWithString:#"folder/file.html" relativeToURL:baseURL];
It's possible, in the same class, call method "webViewDidFinishLoad" more times, one for each webview for example???

How to get this into code form (if statement)

How to make this statement into an actual "if statement" in Xcode?
This is what i want in the form of an "if statement" :
"if a certain link is shown in UIWebView, then image.hidden = NO;"
The UIWebView is currently showing another website, but it has a page in that website that is the certain link I mentioned in the if statement.
The code for the UIWebView is this:
.h:
IBOutlet UIWebView *Name;
NSURL *NameURL;
.m
NameURL = [NSURL URLWithString:#"mywebname.com"];
NSURLRequest *Request = [NSURLRequest requestWithURL: NameURL];
[Name loadRequest: Request];
To access the actual page content within UIWebView, you need to use
stringByEvaluatingJavaScriptFromString: to invoke some JavaScript snippet. Once the page finishes loading, the idea is to loop through all a elements and check for its href attribute, comparing it to the 'certain site' that you mentioned.
Rough implementation:
JS Code
for (var i = 0; i < document.getElementsByTagName('a').length; i++)
{
if (document.getElementsByTagName('a')[i].href.match(/google/) return 'YES';
}
return 'NO';
Obj-C Code
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *test = [webView stringByEvaluatingJavaScriptFromString:aboveJSString];
if ([test isEqualToString:#"YES"]) image.hidden = NO;
}
Hope it helps.
According to Anh Do's answer stringByEvaluatingJavaScriptFromString isn't reliable for me.
Instead you should use:
currentURL = currentWebView.request.URL.absoluteString;
So the code will be likeā€¦.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"HELLO DID GET CALLELDLLL LL LL LL ");
//get the url you webView called "Name" is displaying...
NSString *currentURL = Name.request.URL.absoluteString;
//Check if that url is "mywebname.com"
if ([currentURL isEqualToString:#"mywebname.com"])
{
image.hidden = NO;
}
}
PS. Don't for get to add delegate to you webview
By setting delegate do this..
In ViewDidLoad:
[Name setDelegate:self];
In .h file
#interface "nameofyourviewcontroller" : UIViewController<UIWebViewDelegate>

try to use rangeOfString to behave url for youtube video

I need the app recognize if it's a youtube video embed, then in-app webView
Here is the code I'm using now:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
NSString *urlString = request.URL.absoluteString;
NSString *youtube;
youtube = #"youtube";
if ([urlString rangeOfString:youtube options: NSCaseInsensitiveSearch].location != NSNotFound){
return YES;
}
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
}
That works in most cases because most youtube links are directly transferred as embedded video already on the webpage. However, I check if i choose a profile page or others from youtube, this will still open in-app, becuz my app doesn't have back button (buttons in html page). So any link that's not to a video will cause can't return.
I tried use #"youtube.com/watch" #"/watch?" #"watch?" as rangeOfString, but only youtube works.
For example:
This a youtube video url: data-url="http://youtube.com/watch?feature=player_detailpage&v=Ke1Y3P9D0Bc" (in-app view good)
dara-url="youtube.com" (fail, still in-app view)
I wonder either i stored string by wrong format, symbols not support in rangeOfString?
Or there can be another way like urlString rangeOfString:youtube && #"watch"
Thank you for this, really appreciate.
NSURL *myURL = [NSURL URLWithString:#"http://www.youtube.com/watch?feature=player_detailpage&v=Ke1Y3P9D0Bc"];
NSString *host = myURL.host;
NSString *path = myURL.path;
NSLog(#"%#", host); // Output: www.youtube.com
NSLog(#"%#", path); // Output: /watch
NSLog(#"%#", myURL.query); // Output: feature=player_detailpage&v=Ke1Y3P9D0Bc
if (NSMaxRange([host rangeOfString:#"youtube.com" options:(NSCaseInsensitiveSearch|NSBackwardsSearch)]) == host.length &&
[path.lowercaseString isEqualToString:#"/watch"]) {
NSLog(#"This is a youtube video.");
}
You can certainly use,
if ([urlString rangeOfString:youtube options: NSCaseInsensitiveSearch].location != NSNotFound && [urlString rangeOfString:#"watch" options: NSCaseInsensitiveSearch].location != NSNotFound)
Whether that will get you what you want, I don't know, but it should work as a valid if statement.

UIWebView loadRequest reuse gives flickering effect

I have multiple pdf files. Based on user input i am loading the pdf using UIWebView. On first loadRequest it loads the pdf properly. From second call to LoadRequest onwards its showing some flickering effect while loading the new pdf.. Meaning that starts blur display of content and slowly display content properly in few secs.
Code snippet below:
- (void) loadDocument: (NSString *) documentName
{
NSString * path = [[NSBundle mainBundle] pathForResource: documentName ofType: self.docType];
NSURL * url = [NSURL fileURLWithPath: path];
request = [NSURLRequest requestWithURL: url];
[PdfWebView loadRequest: request];
}
- (void) loadNewDoc:(int)segIndex
{
switch (mPageIndex)
{
case 0:
[self loadDocument:#"PDF_0"];
break;
case 1:
[self loadDocument:#"PDF_1"];
break;
case 2:
[self loadDocument:#"PDF_2"];
break;
default:
break;
}
}
You can clear the web view before starting the new request by using
[yourwebview loadHTMLString:#"<html><head></head><body></body></html>" baseURL:nil];
Or even
[yourwebview stringByEvaluatingJavaScriptFromString:#"document.open();document.close();"];
This may remove the flickering effect
for me, this helped (its robovm java code):
UIView.transition(_wv, 0.5, UIViewAnimationOptions.TransitionCrossDissolve, new Runnable() {
#Override
public void run() {
_wv.loadData(new NSData(pdf), "application/pdf", "utf-8", null);
}
}, null);

Resources