shouldStartLoadWithRequest appending link with applewebdata - iphone

I am receiving a description text in HTML format, and I am loading it in a webview, if a link clicked in the description so I load it in separate view controller. But shouldStartLoadWithRequest giving a some appended link. here is my code
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if(navigationType == UIWebViewNavigationTypeLinkClicked) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
WebsiteViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"WebsiteViewController"];
vc.url = request.URL.absoluteString;
NSLog(#"link is : %#", [[request URL] absoluteString]);
[self.navigationController pushViewController:vc animated:YES];
return false;
}
return true;
}
it prints this
link is : applewebdata://038EEEBF-A4C9-4C7D-8FB5-32056714B855/www.yahoo.com
and I am loading it like this
[webViewDescription loadHTMLString:description baseURL:nil];

As you are using loadHTMLString and you are setting baseURL to nil therefore applewebdata URI scheme is used by iOS instead of the “http” in URIs used for accessing internal resources on the device. You could try setting the baseURL

I had a similar issue. In practice, setting the baseURL to 'http://' or something like that wasn't working for me either. I also only saw the applewebdata scheme about 50% of the time, the other 50% of the time I saw the correct scheme I was expecting.
To resolve this, I ended up intercepting -webView:shouldStartLoadWithRequest:navigationType: callbacks and using a regular expression to strip out Apple's applewebdata scheme. Here's what it ended up looking like
// Scheme used to intercept UIWebView callbacks
static NSString *bridgeScheme = #"myCoolScheme";
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
BOOL shouldStartLoad = YES;
NSURL *requestURL = request.URL;
// Strip out applewebdata://<UUID> prefix applied when HTML is loaded locally
if ([requestURL.scheme isEqualToString:#"applewebdata"]) {
NSString *requestURLString = requestURL.absoluteString;
NSString *trimmedRequestURLString = [requestURLString stringByReplacingOccurrencesOfString:#"^(?:applewebdata://[0-9A-Z-]*/?)" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, requestURLString.length)];
if (trimmedRequestURLString.length > 0) {
requestURL = [NSURL URLWithString:trimmedRequestURLString];
}
}
if ([requestURL.scheme isEqualToString:bridgeScheme]) {
// Do your thing
shouldStartLoad = NO;
}
return shouldStartLoad;
}

Related

Listen to all requests from UIWebView

I can intercept the initial load request from a UIWebView with:
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType.
How do I log all the requests from the page I'm loading?
Update: Another option is to use NSURLProtocol to hear requests the application makes, including all the ones from the web view.
I will suggest a creative solution. This is not really what you want, but since that is not really possible at this point with the SDK, this is the only possible solution.
#interface PrintingCache : NSURLCache
{
}
#end
#implementation PrintingCache
- (NSCachedURLResponse*)cachedResponseForRequest:(NSURLRequest*)request
{
NSLog(#"url %#", request.URL.absoluteString);
return [super cachedResponseForRequest:request];
}
#end
Now in your app delegate, do the following:
NSString *path = ...// the path to the cache file
NSUInteger discCapacity = 10*1024*1024;
NSUInteger memoryCapacity = 512*1024;
FilteredWebCache *cache = [[Printing alloc] initWithMemoryCapacity: memoryCapacity diskCapacity: discCapacity diskPath:path];
[NSURLCache setSharedURLCache:cache];
This creates a shared cache, and all of your application's URL requests will go through this cache, including your web view. However, you may get more URLs from other sources that you do not want.
Try the below code
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"url %#", [[request URL] absoluteString]);
return YES;
}
hope it will help you.
This works:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"url %#", [[request URL] absoluteString]);
return YES;
}
Make sure you put webView.delegate = self; in the [super viewDidLoad], else it won't show anything.

Can we restrict some websites to open in web view

I want in my app to not to open some particular sites in web view. So can we restrict any website in such a way. I want to add one more thing that i want to completely restrict a website not any particular page.
Thanks in advance.
Yes, you can block the page from loading in this UIWebview delegate method.
Remember to set the class as the webviews delegate. webView.delegate = self;, and the class needs to be UIViewController <UIWebViewDelegate>
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([request.URL.absoluteString rangeOfString:#"google"].length != 0) {
// maybe show a UIAlertView to indicate the page is blocked?
return NO;
}else {
return YES;
}
}
EDIT: now it checks if google is mentioned in the URL, and blocks it if it contains Google
A little improvement : save the websites you want to block in a NSArray :
NSArray *restrictedSites = [NSArray arrayWithObjects:#"http://www.google.com", #"http://www.google.co.uk", nil];
Now check if the website requested is one of the restricted websites :
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *site = request.URL.absoluteString
for(NSString *str in restrictedSites)
{
if ([site isEqualToString:str])
{
return NO;
}
}
return YES;
}
Alternatively you can check if the website requested contains a URL. In th following case, all the url containing "http://www.google" or "http://www.apple" will be blocked :
First create the restricted site array :
NSArray *restrictedSites = [NSArray arrayWithObjects:#"http://www.google", #"http://www.apple", nil];
Now check if the website requested contains one of the restricted websites (without .com or .co.uk etc...) :
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *site = request.URL.absoluteString
for(NSString *str in restrictedSites)
{
if ([site rangeOfString:str].location != NSNotFound)
{
return NO;
}
}
return YES;
}
So here, all http://www.google.com, http://www.google.fr, http://www.google.co.uk will be blocked.

How do I autofill username and password in UIWebView iOS app?

I am teaching myself how to program an iPhone app by looking at code examples from various sources online, so it is fair to say that I do not understand the language (yet).
I am have successfully built a UIWebView browser app that goes to a login page. However, I am trying to take it one step further by having the
Following Byron's code on his own stack overflow question, I have tried to follow in his footsteps.
Is it possible for a UIWebView to save and autofill previously entered form values (e.g., username & password)?
However, when the following line of code is live in the app, the browser will only load a blank page.
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
I really appreciate any assistance to help get me back on the right track. Thank you very much,
Below is my entire code:
#import "ViewController.h"
// 6/13/2012 added to cache username and password
#import
#import "SFHFKeychainUtils.h"
// -----
#interface ViewController ()
#end
#implementation ViewController
#synthesize webView;
#synthesize spinner;
-(IBAction)goBack:(id)sender{
if ([webView canGoBack]) {
[webView goBack];
}
}
-(IBAction)goForward:(id)sender{
if ([webView canGoForward]){
[webView goForward];
}
}
- (void)viewDidLoad
{
NSURL *url = [NSURL URLWithString:#"http://xxxxxx.com/weblink/hh_login.html"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
// 6/13/2012 added to cache username and password
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; {
//save form data
if(navigationType == UIWebViewNavigationTypeFormSubmitted) {
//grab the data from the page
NSString *username = [self.webView stringByEvaluatingJavaScriptFromString: #"document.myForm.username.value"];
NSString *password = [self.webView stringByEvaluatingJavaScriptFromString: #"document.myForm.password.value"];
//store values locally
[[NSUserDefaults standardUserDefaults] setObject:username forKey:#"username"];
[SFHFKeychainUtils storeUsername:username andPassword:password forServiceName:#"MyService" updateExisting:YES error:nil];
}
}
// -----
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
[spinner startAnimating];
}
//- (void)webViewDidFinishLoad:(UIWebView *)webView {
// [spinner stopAnimating];
//}
// 6/13/2012 added to cache username and password
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[spinner stopAnimating];
//verify view is on the login page of the site (simplified)
NSURL *requestURL = [self.webView.request URL];
if ([requestURL.host isEqualToString:#"http://xxxxxx.com/weblink/hh_login.html"]) {
//check for stored login credentials
NSString *username = [[NSUserDefaults standardUserDefaults] objectForKey:#"username"];
if (username.length != 0 ) {
//create js strings
NSString *loadUsernameJS = [NSString stringWithFormat:#"document.myForm.username.value ='%#'", username];
NSString *password = [SFHFKeychainUtils getPasswordForUsername: username andServiceName:#"MyService" error:nil];
if (password.length == 0 ) password = #"";
NSString *loadPasswordJS = [NSString stringWithFormat:#"document.myForm.password.value ='%#'", password];
//autofill the form
[self.webView stringByEvaluatingJavaScriptFromString: loadUsernameJS];
[self.webView stringByEvaluatingJavaScriptFromString: loadPasswordJS];
}
}
}
// -----
#end
TRY BELOW ONE
You need to fill the credential when webview has loaded .
below is the delegate method of UIWebView called when the WebView has loaded.At this time pass the credential not as were passing before loading the UIWebView which is not correct.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if(!isLoggedIn){//just load only onetime.
//pass the login Credintails into textfield of WebView.
NSString* userId = #"userName" //here just replace that string to the username
NSString* password = #"password";//here just replace that string to the password
if(userId != nil && password != nil ){
NSString* jScriptString1 = [NSString stringWithFormat:#"document.getElementById('username').value='%#'", userId];
//username is the id for username field in Login form
NSString* jScriptString2 = [NSString stringWithFormat:#"document.getElementById('password').value='%#'", password];
//here password is the id for password field in Login Form
//Now Call The Javascript for entring these Credential in login Form
[webView stringByEvaluatingJavaScriptFromString:jScriptString1];
[webView stringByEvaluatingJavaScriptFromString:jScriptString2];
//Further if you want to submit login Form Automatically the you may use below line
[webView stringByEvaluatingJavaScriptFromString:#"document.forms['login_form'].submit();"];
// here 'login_form' is the id name of LoginForm
}
isLoggedIn=TRUE;
}
}
It'll really help you.

Load custom view in phonegap/iphone

I have made a plugin for the iphone which is working fine. I can call all the native methods. I also made a custom view (.xib file) which i want to load. But i can't figure out how to do this with phonegap in the way.
Normally i would do something like:
[self addSubView:myView2];
But this doesn't work.
Anyone any idea how to load and display a custom made .xib file when using phonegap??
Have you used Child browser plugin so far, this plugin also contain ChildBrowserViewController.xib . So to call another xib in your Phonegap you need to modify your- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
method in appDelgate.m file.
Some how in your HTML and javascript code, you need to provide special link (using href or window.location method) that you need to handle in shouldStartLoadWithRequestmethod, import your #import MyCustomViewController.h in your appDelegate.m file.
Please have look at the following snippet-
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
NSURL *url = [request URL];
if([request.URL.absoluteString isEqualToString:#"about:blank"])
return [ super webView:theWebView shouldStartLoadWithRequest:request
navigationType:navigationType ];
if ([[url scheme] isEqualToString:#"gap"]) {
return [ super webView:theWebView shouldStartLoadWithRequest:request
navigationType:navigationType ];
}
else {
NSString *urlFormat = [[[url path] componentsSeparatedByString:#"."] lastObject];
if ([urlFormat compare:#"xib"] == NSOrderedSame) {
[theWebView sizeToFit];
MyCustomViewController* customVC = [ [ MyCustomViewController alloc ] initWithScale:FALSE ];
customVC.modalPresentationStyle = UIModalPresentationFormSheet;
customVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[super.viewController presentModalViewController:customVC animated:YES ];
[customVC release];
//return YES;
return NO;
}
else
return [ super webView:theWebView shouldStartLoadWithRequest:request
navigationType:navigationType ];
}
}
thanks,
mayur

PhoneGap/iOS - How to get Childbrowser to ignore links to Appstore?

I have an app in the process of upgrading to the iOS5 SDK and Phonegap 1.0.0
The Childbrowser plugin is working properly, but when a link to the iTunes app store is clicked - the link is opened in a Childbrowser window.
I would prefer it to open in Appstore directly, which is what happens if I do not use the ChildBrowser plugin.
This is the appstore link (points to a submit a review page within the appstore)
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=386470812&pageNumber=0&sortOrdering=1&type=Purple+Software&mt=8
and this is how AppDelegate is modified
AppDelegate.m, scroll way down and replace the following:
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
with this:
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:
(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
if ([[url scheme] isEqualToString:#"gap"] || [url isFileURL]) {
return [ super webView:theWebView shouldStartLoadWithRequest:request
navigationType:navigationType ];
}
else {
ChildBrowserViewController* childBrowser =
[ [ ChildBrowserViewController alloc ] initWithScale:FALSE ];
[super.viewController presentModalViewController:childBrowser
animated:YES ];
[childBrowser loadURL:[url description]];
[childBrowser release];
return NO;
}
}
I used the method outlined in this blogpost to get the Childbrowser up and running
http://iphonedevlog.wordpress.com/2011/09/24/installing-childbrowser-into-xcode-4-with-phonegap-1-0-mac-os-x-snow-leopard/
Any thoughts on how to change this to produce the desired action?
Many thanks..
You need to check whether your URL contain http://itunes.apple.com/ as a substring by using rangeOfString: method and location attribute.
Please confirm your javascript called the url like this, window.location="http://itunes.apple.com/us/app/code-check-basic-free-medical/id386470812?mt=8"; or you can use any jquery method.
Please replace shouldStartLoadWithRequest: method with the following snippet.
/**
* Start Loading Request
* This is where most of the magic happens... We take the request(s) and process the response.
* From here we can re direct links and other protocalls to different internal methods.
*/
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:
(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
if ([[url scheme] isEqualToString:#"gap"] || [url isFileURL]) {
return [ super webView:theWebView shouldStartLoadWithRequest:request
navigationType:navigationType ];
}
else {
//here we will check whether urlString has http://itunes.apple.com/ as substring or not
NSString* urlString=[url absoluteString];
if ([urlString rangeOfString:#"http://itunes.apple.com/"].location == NSNotFound){
ChildBrowserViewController* childBrowser = [ [ ChildBrowserViewController alloc ] initWithScale:FALSE ];
childBrowser.modalPresentationStyle = UIModalPresentationFormSheet;
childBrowser.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[super.viewController presentModalViewController:childBrowser animated:YES ];
[childBrowser loadURL:urlString];
[childBrowser release];
return NO;
}
else
return YES;
}
}
thanks,
Mayur