I have a running application in appstore which contains UIWebView. It worked perfectly fine till iOS 6.0. In OS 6 some hyperlinks are not working but the same thing is working fine when I use the safari browser in iOS on the iPad.
Do I need to add some extra delegate methods to make it working?
Currently I m Using following code:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:kAuthenticationURL]];
[request setValue:[NSMutableURLRequest userAgentRequests] forHTTPHeaderField:#"User-Agent"];
[request setHTTPMethod:#"POST"];
[request setHTTPShouldHandleCookies:YES];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSData *postData = [[NSString stringWithFormat:#"username=%#&code=%#", username, password]
dataUsingEncoding:NSASCIIStringEncoding];
[request setHTTPBody:postData];
delegate i have used:
1)
- (void)webViewDidStartLoad:(UIWebView *)webView
2)
- (void)webViewDidFinishLoad:(UIWebView *)webView
inside this method I have used the following for loading data:
[self.webView stringByEvaluatingJavaScriptFromString:#"window.location.reload = function(){};"];
3)
- (BOOL)webView:(UIWebView *)webViewshouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType`
Do i need to implement some thing extra for make it working in iOS 6?
Any help is appriciated...
Maybe you're having the same problem as described here: stringByEvaluatingJavaScriptFromString is not working in iOS 6 or here iOS 6 - UIWebView loadHTMLString not working properly
It seems iOS 6 loads and renders the page differently and could be stricter then 5
You could try to suppres iOS6's incremental rendering as stated here
suppressesIncrementalRendering
A Boolean value indicating whether the web view suppresses content rendering
until it is fully loaded into memory.
#property(nonatomic) BOOL suppressesIncrementalRendering
You could also try to debug using your mac as described here:
Additional tip: to debug javascript errors on iOS6, a new feature
makes it very simple:
Go to the "Settings" application in your iPhone, enter the "Safari" settings and tap on "Advanced" at the bottom, then enable the "WebKit
Inspector" from there
Display your page to be debugged on the screen (i.e. launch your app and go to your screen that contains the WebView to make it visible)
Plug your iPhone to your Mac via your USB cable
Open Safari.app on your Mac, go to the "Development" menu (1), select the menu item with the name of your iPhone and select your
application in the submenu.
You will then be able to debug your web page presented in your iPhone
using the powerful Web Inspector from your Mac, and can look into the
javascript console, the DOM tree, etc.
(1) If you don't have the "Development" menu in Safari on your Mac, you can enable it in the "Advanced" preferences tab of the Safari
application.
More on remote debugging can be found here (scroll all the way down to 'Remote Debugging') or here (WWDC video session: "Debugging UIWebViews and Websites on iOS")
Related
Although there are many discussions about the subject, I have not still found an answer.
The problem is, that after the UIWebView loads a page, it will never release all the used memory resources.
I have created an empty project. Just added the UIWebView. The memory used before loading a request (http://methodhome.com/cleanhappy) was 4.5MB, and after loading has completed - 70 ~ 90 MB.
After releasing the UIWebView, the used memory was still 55MB.
So it looks like there are about 50MB of leaked memory.
I have tried next methods:
[_webView stringByEvaluatingJavaScriptFromString:#"var body=document.getElementsByTagName('body')[0];body.style.backgroundColor=(body.style.backgroundColor=='')?'white':'';"];
[_webView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML='';"];
[_webView stringByEvaluatingJavaScriptFromString:#"document.open();document.close();"];
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
[_webView loadHTMLString:#"" baseURL:nil];
[_webView stopLoading];
_webView.delegate = nil;
[_webView removeFromSuperview];
_webView = nil;
[[NSURLCache sharedURLCache] removeAllCachedResponses];
I have also tried setting:
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"WebKitCacheModelPreferenceKey"];
and have played with cache settings of memory and disk.
Nothing helped.
How can it be possible? How are the popular browsers are working like Safari and Chrome with such a leaks. What is the trick to release those resources?
How can it be possible?
UIWebView is an old API, based on WebKitLegacy. It's not deprecated for 1 single reason - Apple had no replacement (until iOS 9).
How are the popular browsers are working like Safari and Chrome with
such a leaks.
Safari is a browser, created by Apple itself. It can use any hacks and private APIs, restricted in AppStore. Actually, for now Safari behavior is very close to WKWebView's one. But it never was similar to UIWebView.
Only recently Google Chrome was able to migrate to WKWebView. See https://bugs.chromium.org/p/chromium/issues/detail?id=423444 for details. Before that, Google Chrome was facing the same problem.
What is the trick to release those resources?
I've tried a lot of tricks, but none of them worked for me. Unfortunately, the only solution is migration to WKWebView, introduced in iOS 8. Moreover, WKWebView had a lot of bugs under iOS 8, so in most cases it's usable only starting from iOS 9.
All right, I am having a problem opening the iBooks app using an IBAction in my app. I have it set up so that when the user presses a button, it calls this action to open the iBooks app:
-(IBAction)openBooks:(id)sender
{
NSString *stringURL = "iBooks://";
NSURL *url = [NSURL URLWithString:stringURL];
[[UIApllication sharedApplication] openURL:url];
}
This does the whole app switching this and looks great. I see the bookshelf where all of my books should be, but then the iBooks app crashes before my books load! The app I wrote doesn't crash, but iBooks fails!
I am running my app via XCode (the app isn't actually distributed to my iPad, per se), is that why iBooks crashes? When I touch the iBooks icon to open it (not via my app) it opens fine and works. But if I change the url in my IBAction like this:
NSString *stringURL = "maps://";
and run my app, my button works and Maps opens up!
Is this an iBook bug? Or is it my bug?
FWIW, I'm using iOS 6 and XCode 4.6.3
You HAVE to check if iOS can open a url before opening it. Either your url scheme is wrong (like in your case) or the user doesn't even have iBooks installed. Even if you have the correct url you can't open it unless the user has installed an app that corresponds to the url.
NSURL *url = ...
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
else {
// can't open url
}
OK, so my bad. I found that I was using the wrong URL scheme. The iBooks:// I got from wiki.akosma does NOT work, but itms-books: DOES work.
when I load a UIWebView with the following code:
NSString *helpText = [NSString stringWithFormat:#"Lorem Ipsum"];
[self.helpWebView loadHTMLString:[NSString stringWithFormat:#"<html><head></head><body stlye=\"background-color: transparent;\"><div align='justify' style=\"color: #000000; font-family: Helvetica; font-size: %fem;\">%#</div></body></html>", fontSize, helpText] baseURL:[NSURL URLWithString:#""]];
I get this error, but only the first time when a WebView is loaded in my app:
void SendDelegateMessage(NSInvocation *): delegate (webView:decidePolicyForNavigationAction:request:frame:decisionListener:) failed to return after waiting 10 seconds. main run loop mode: kCFRunLoopDefaultMode
And the text will load, but only after 10 seconds. But the UI is blocked for 10 Seconds. When I navigate through the app, other ("later") UIWebViews will load immediately and it is not related to this specific UIWebView, i.e. if I got to UIWebView A and then to UIWebView B, A will load after 10 seconds of UI blocking and B will load instantly. IF it starts with B and then goes to A, B will load after 10 seconds and A will load instantly. So, only the first UIWebView which is loaded creates a problem.
And I really only load the html above. Some douzen of characters, no JScript, no big tables, no funny html stuff. It will even block the UI and report the error message if I load a blank HTML-String.
I have not set any delegate stuff or something like this. I created the UIWebView in Interface Builder, connected it to the header via property and I am using loadHTMLString to get content into.
Important: I can currently only use the Simulator, so I cannot predict, whether this is only a Simulator issue. If you know it, please let me know. At the moment, I cannot test at a real device. The Simulator should not go into this error because of ressources however. I have a current MacBook Air and almost no extra programs installed ("clean installation" of Mac OS X Lion).
Another Point: The only reason why I use UIWebView is that I need full justification for the text. If this would work any other way, would help me too. At least from Android development, I know that there is no other way than a WebView.
I think the problem is solved with the update from today (iOS 6.1 SDK) and I also think it is related to the simulator. I think it is about interfering outgoing requests from skpaymenttransaction and other UIWebView... I am not sure about anything, however...
It would appear that Apple have changed the way homescreen/standalone web apps work in iOS 6. According to various blog posts (example) these apps now get their own dedicated space for storing their cached files, sqllite dbs, local storage etc, rather than sharing with the Safari browser like before.
Before iOS 6 when developing I used to go through the following procedure religiously to clear the cache...
Remove app from homescreen.
Close all pages/tabs in Safari.
Finally "Clear Cookies & Data" or "Clear Data" in "Settings" > "Safari".
Unfortunately now that Apple have moved the goal posts this same procedure doesn't seem to work. After clearing, even though my changes are picked up in Safari, when I add to the homescreen and launch the app the old HTML,JS etc is still picked up.
Does anyone know how to reliably fully clear the cache in iOS 6?
I can't verify the cache being cleared properly but this worked for me :
In order to do this, you need to allow Web Inspector on your iOS device.
Go to Settings > Safari > Advanced > Web Inspector (it has to be active)
And you have to activate the developer menu on your computer's Safari.
Go to Preferences > Advanced > Activate Developer menu
Connect your device to your computer with the USB cable
Go to safari > Developpement > Your Device name > Inspect an App (The app has to be running)
This will open The inspector on your computer for the web app
While the inspector is open Clear the cache (command + alt + E)
With the inspector still open refresh the page on your computer (command + R)
Somehow the Webapp cache got cleared and i got the non-cached code.
I found a a work-around. Just put a link on the web page itself for users who are having trouble seeing new version...
refresh
It works just like the iPhone/iPad refresh button on the address bar!
First plug the phone into the computer then open the web app on the phone and Safari on the computer, then you can open the web inspector in Safari from the menu "Develop>Name of phone>title of app" (if you can't see the develop menu you can turn it on in Safari's preferences).
From there you can see/edit the cookies and local storage just like sites on your computer and pressing command+r while the inspector is focused will reload the app on the phone.
You can connect your device and open Safari's web inspector on your computer and run document.location.reload() in the console tab to reload the page.
Before reloading you can press Option+Command+E to make sure the cache is cleared.
Instead of above you can also press Shift+Command+R to reload the page without cache but sometimes it hasn't worked for me.
Try appending a unique GET tag to the ends of any and all href attributes, for example:
<link rel="stylesheet" type="text/css" href="/css/global.css?
<?php echo(mt_rand(10000000, 99999999)); ?>
" />
This would generate href="/css/global.css?########", with a different number nearly every time. This forces iOS' Safari to pull the "new" page down, as there is no data in its cache originating from the same URI, and there likely never will be (unless you plan on reloading the app millions of times during development :D )
If the iOS6 device has a jailbreak applied, you can use ssh to delete the content of the folder "/private/var/mobile/Library/Caches/com.apple.webapp".
Next time that you start the web app, all files will be re-downloaded from the webserver.
The only way to deal with this currently is to wait, but there is a workaround. If you change the name of the file, it will pull the new code. However, if you change it back to the old name before the cache clears, the old code will be used. The cache refreshes periodically and will update eventually. I just had this happen to me with a CSS file that refused to change. Time will fix it, but if you just need it to update for testing, a name change will work.
This drove me nuts for a while. Tried clearing the cache on device - no luck. Renaming the page did help, but once you rename it back, you still get the same stale version.
Found the solution yesterday. You need to connect your device to Mac and open Web Inspector in Safari Develop menu. Once in Web Inspector, simply press "Reload page" button on the Inspector's toolbar and - voila - you see the fresh version on your device's screen.
Just set the request you pass to the webview to NSURLRequestReloadIgnoringLocalCacheData
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[self.webView loadRequest:request];
I have a link on my mobile app (created with Sencha Touch 2) with a target="_blank" attribute. The app is packaged as a native iOS app. The problem is, the link is not opening in Safari as expected, instead it opens inside the app. It is very important that the link opens in Safari in a new browser window. How can I achieve that?
I should add that I am using the native packager of Sencha (sencha package). The default behaviour seems to open the new window in the same webview. But I need them to be opened in mobile Safari.
In an Xcode project I could do the following:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
}
return YES;
}
How to do that with Sencha Touch native packaging?
I use this to open links in either Mobile Safari, or a new window. Works with Native iOS packaging and web apps:
function externalLink(link) {
try{
Ext.device.Device.openURL(link);
}catch(err) {
window.open(link, '_blank');
}
}
I haven't discovered a way to do this with sencha native packaging.
But wrapping the application in a phonegap and compiling the application in Xcode, with required urls added to the ExternalHost array in phonegap.plist should work right?
Also, (still on the Phonegap solution) I assume hacking AppDelegate.m to open links in Safari would work just as fine.
Programmatically (Javascript) opens a link in Mobile Safari.
Ideal if you cannot use a standard html link but you must use Javascript:
var a = document.createElement("a");
a.setAttribute('href', facebook);
a.setAttribute('target', '_blank');
a.click();