iPhone UIWebview Loads on Simulator But not on Device - iphone

I have a UIWebview on a Tab Bar that loads properly on the Simulator but not on the Device. Has anyone ever come across this situation? I've been looking all over the Google- machine for the last three days to no avail. Any help would be hugely appreciated.

I faced the same problem. The solution evaded me a lot of time, but what I discovered was that I had:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"shouldStartLoadWithRequest Loading: %#", [request URL]);
}
and I did not return any thing from this. When I changed it to
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"shouldStartLoadWithRequest Loading: %#", [request URL]);
return TRUE;
}
it works. Simulator does not care if you returned a BOOL or not, but the actual device, it does not work.

First check your connectivity. Are you able to access both URLs (about and PHP page) from Safari on the device?
Then I suggest you stick some error handling code in your UIWebViewDelegate. So something like :
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// load error, hide the activity indicator in the status bar
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if ([error code] == NSURLErrorCancelled) {
// don't show the error
// if you want to know why I ignore these errors
// check out this question:
// http://stackoverflow.com/questions/1577670
return;
}
[webView loadHTMLString:[[[NSString alloc] initWithFormat:#"Failed to load page %# %08d", [error localizedDescription, [error code]]] autorelease] baseURL:nil];
}
Let us know how you go.

Related

shouldStartLoadWithRequest appending link with applewebdata

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;
}

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.

Can web apps in iPhone call inapp for virtual things purchase?

If I would like to write a web apps that users can purchase some virtual things, can I call the iphone inapp? or I can use other payment methods?
No you cant, you will need to implement special non standard tags into your application, when the user clicks on these links they will have some thing like this:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
NSString *urlAbsolute = [request.URL absoluteString];
if ([urlAbsolute hasPrefix:#"YourSpecialTag://"])
{
//YourSpecialTag://BuyID=100
//Parse the url
//Get the id = 100
//Continue with in-app purchase
return NO;
}
}
return YES;
}

iphone uiwebview authentication challenge keeps firing when signed in

i have recently implemented authentication challenge log in through the iPhones UIWebView. i've got it working to the point where i get challenged then i present an alert with text fields, then send the data to the site that needs authentication.
i have not yet tried to use this on anything else besides my netgear router. But my problem is when i navigate through the settings for the router, the authentication challenge gets called, thus presenting the alert even though the user is logged in.
below is the code i'm using, any advice would be grately appreciated
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"Did start loading: %# auth:%d", [[request URL] absoluteString], _authed);
myRequest=[request copy];
if (_authed) {
NSLog(#"_authed");
_authed = NO;
// pretty sure i'm leaking here, leave me alone... i just happen to leak sometimes
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;
}
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return YES;}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
NSLog(#"protection space %#", protectionSpace.authenticationMethod);
//if(![protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]){
return NO;
//}
//else{
// return YES;
//}
//[protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic];}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;{NSLog(#"received response via nsurlconnection %#", connection);
NSLog(#"got auth challange %#", challenge);
UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = NO;
/*NSString *aarrgghh=[NSString stringWithFormat:#"%#",connection];
NSString *searchForMe = #"login";
NSLog (#"arrgghhh %#",aarrgghh);
NSRange range = [aarrgghh rangeOfString:searchForMe];*/
if ([challenge previousFailureCount] <=1) {
//present alert with text fields for credentials
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}}
-(void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
NSLog(#"Challenge cancelled");}
//`-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(#"received data");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;{
NSLog(#"received response via nsurlconnection %#", response);
// THIS IS WHERE YOU SET MAKE THE NEW REQUEST TO UIWebView, which will use the new saved auth info
if(_authed){
//NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:self.webView.request.URL.absoluteString]];
[webView loadRequest:myRequest];
}
}
`
Might be a simpler way to do this, but this is what worked for me.
First off, when shouldStartLoadWithRequest returns YES, that tells UIWebView to create NSURLConnections and run them for you . Since you can't assign a delegate to this connection, that's not going to work. If you want to handle authentication via a NSURLConnectionDelegate, then shouldStartLoadWithRequest should always return NO for that UIWebView.
So you need to handle the connection yourself. Fire off an NSURLConnection with the request and use the rest of the NSURLConnection delegate methods to handle the loading (e.g. keep track of the MIME type and build up an NSMutableData)
Finally, when you get to connectionDidFinishLoading, you can call UIWebView's loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName baseURL:(NSURL *)baseURL with the NSData your connection downloaded.