Release memory/cookie/cache from UIWebView once closed - ios

I have a UIViewController which contains a UIWebView.
i login to a website for say facebook using the UIWebview in the UIViewController then i click on done, which dismiss the view controller, which i suppose will release the view controller. but when i open the UIWebview again (without exiting the app and also even after terminating the app) the webpage is still log into Facebook after the web view loads. How should i release the web view so that every time i click on done and return back to the web view, the web view will always be like "brand new" not log-on to any website that i had previously log-on to.
- (void)viewDidLoad{
NSLog(#"webView viewDidLoad called");
appDelegate = (LoginDBAppDelegate *)[[UIApplication sharedApplication] delegate];
loginObj = [appDelegate.loginArray objectAtIndex:currentSelectedRow];
myWebView.delegate = self;
[super viewDidLoad];
[self showWebView];
}
-(void)showWebView{
NSLog(#"webView showWebView called");
NSURL *url = [NSURL URLWithString:loginObj.loginURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[myWebView loadRequest:request];
}
-(IBAction)done_Clicked:(id)sender{
NSLog(#"webView Done_Clicked");
//dismiss the controller
[self.navigationController dismissModalViewControllerAnimated:YES];
}
-(void)dealloc{
[myWebView release];
myWebView.delegate = nil;
[activity release];
[urlTextField release];
[super dealloc];
}
I have tried this but it didn't work:
-(IBAction)done_Clicked:(id)sender{
NSLog(#"webView Done_Clicked");
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[myWebView stringByEvaluatingJavaScriptFromString:#"var body=document.getElementsByTagName('body')[0];body.style.backgroundColor=(body.style.backgroundColor=='')?'white':'';"];
[myWebView stringByEvaluatingJavaScriptFromString:#"document.open();document.close()"];
//dismiss the controller
[self.navigationController dismissModalViewControllerAnimated:YES];
}
I have also tried this without any success:
- (void) viewDidDisappear:(BOOL)animated {
NSLog(#"webView viewDidDisappear called");
[super viewDidDisappear:animated];
[self.myWebView removeFromSuperview];
self.myWebView.delegate = nil;
self.myWebView = nil;
[myWebView release];
}

Got the answer from someone on the forum, so credit to him...
Place this code in viewDidLoad
//Set Cache
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
//Clear All Cookies
for(NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
//if([[cookie domain] isEqualToString:someNSStringUrlDomain]) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}

Related

UISearchBar url request

I have a downloader in which I am trying to get the pasted text in my search bar to start downloading on tapping the return key.
How would I get the search bar to send a request to the pasted text to initialize the download?
What I'm calling:
NSString *pasteboardString = searchBar.text;
NSURL *url = [NSURL URLWithString:pasteboardString];
What needs to get triggered:
[self downloadURL:*HAS TO BE URL* userInfo:nil];
Any help is appreciated, thank you.
So I ended up figuring it out. In case somebody finds this useful.
#pragma mark - Firing Download
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
dispatch_async(dispatch_get_main_queue(), ^
{
// Do the search...
NSURL *url = [NSURL URLWithString:searchBar.text];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
bool valid = [NSURLConnection canHandleRequest:req];
if(valid)
{
[self downloadURL:url userInfo:nil];
NSLog(#"Valid URL - %#",searchBar.text);
[searchBar resignFirstResponder];
[searchBar setText:nil];
}
else
{
[alert showError:#"Enter valid url"];
[searchBar becomeFirstResponder];
[searchBar setText:nil];
}
});
NSLog(#"Search Button Pressed");
}

How to load cordova webview in my viewcontroller?

My cordova library was old and had to update it because of iOS11. I have updated it to latest version 4.4.0. CDVViewController is totally different now which enables webviewEngine that takes UIWebview or WKWebview. How do I initiate Cordova webview in my native app. Previously, I loaded it like this -
- (void) viewDidLoad {
[super viewDidLoad];
CDVViewController *viewController = [CDVViewController new];
viewController.wwwFolderName = #"www";
viewController.startPage = #"blank.html";
viewController.view.frame = self.webView.frame;
[self.webView removeFromSuperview];
self.webView = nil;
[self.view addSubview:viewController.view];
self.webView = viewController.webView;
viewController.webView.delegate = self;
self.cordovaWebViewController = viewController;
self.webView.scalesPageToFit = YES;
if (self.url)
[self.webView loadRequest: [NSURLRequest requestWithURL: self.url]];
}
And used webview delegates as
#pragma mark Webview Delegate
- (void) webViewDidStartLoad: (UIWebView *) webViewLocal {
[self.spinner startAnimating];
[self.cordovaWebViewController webViewDidStartLoad:webViewLocal];
}
- (void) webViewDidFinishLoad: (UIWebView *) webViewLocal {
[self.spinner stopAnimating];
[self.cordovaWebViewController webViewDidFinishLoad:webViewLocal];
}
- (void) webView: (UIWebView *) webView didFailLoadWithError: (NSError *) error {
[self.spinner stopAnimating];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if ([request.URL.absoluteString hasSuffix: #"link_restart_movie_file"]) {
[self loadItem];
return NO;
}
[self.webView loadRequest: request];
return NO;
}
[self.cordovaWebViewController webView:self.webView shouldStartLoadWithRequest:request navigationType:navigationType];
return YES;
}
How do I use WebviewEngine to load in my viewcontroller? Is there any tutorial, that explains the usage of CDVViewController? Please help! Thanks!

Downloading files WKWebView ios

I'm in the progress of migrating my app from UIWebView to WKWebView. All is going well and working as I tinker more with it. However, I notice now that I can't download forum attachments.
I'm using HCDownload, and thus far has always worked perfect for me, so I know it's not on that end. I believe its the request, but I cant figure it out.
I know the following:
UIWebView => WKWebView Equivalent
--------------------------------------------------------------
didFailLoadWithError => didFailNavigation
webViewDidFinishLoad => didFinishNavigation
webViewDidStartLoad => didStartProvisionalNavigation
shouldStartLoadWithRequest => decidePolicyForNavigationAction
So with that known I am trying below:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSURL *fileURl = [request URL];
NSString *externalFileExtension = [fileURl pathExtension];
NSString *internalFileExtension = [[fileURl absoluteString] pathExtension];
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
dlvc.delegate = self;
vc.transitioningDelegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//External file extensions
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
[dlvc downloadURL:fileURl userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(#"externalURL is %#", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
//Internal file links
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
[self presentViewController:vc animated:YES completion:nil];
[dlvc downloadURL:fileURl userInfo:nil];
[vc release];
NSLog(#"internalURL is %#", fileURl);
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
It will fire my download controller by finding the file extension, but instead it downloads the index.php, not the file.
Example url:
https://example.com/index.php?app=core&module=attach&section=attach&attach_id=1234=example.zip;
What am I doing wrong. It worked fine before in UIWebView and I know things are done differently. But how can it download something from say dropbox just fine, but an attached file on a forum gets goofed up.
Any help would be appreciated
Well heres what I ended up with, and all seems to be working fine.
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response;
NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
decisionHandler(WKNavigationResponsePolicyAllow);
//NSLog(#"decidePolicyForNavigationResponse");
}
//Download manager
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
fileURL = request.URL;
HCDownloadViewController *dlvc = [[HCDownloadViewController alloc] init];
UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:dlvc];
vc.transitioningDelegate = self;
dlvc.delegate = self;
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
//Internal file links
NSString *internalFileExtension = fileURL.absoluteString.pathExtension;
if ([fileExtensions containsObject:[internalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(#"internalURL is %#", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
//External file extensions
NSString *externalFileExtension = fileURL.pathExtension;
if ([fileExtensions containsObject:[externalFileExtension lowercaseString]]) {
//Fire download
[dlvc downloadURL:fileURL userInfo:nil];
[self presentViewController:vc animated:YES completion:nil];
[vc release];
NSLog(#"externalURL is %#", fileURL);
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyCancel);
}
return;
}
}
if (decisionHandler) {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
You are probably downloading a not-authorized page because your WKWebView and HCDownload instances don't share cookie sessions like UIWebView could. That's a necessary trade-off for the WK2 process model's speed & security improvements.
I added downloading to my WKWebKit-based OSX/Swift mini-browser by implementing _WKDownloadDelegate. Its a totally undocumented private protocol as of El Cap and iOS9. It lets your navigation delegate call decisionHandler(_WKNavigationResponsePolicyBecomeDownload) whereby WebKit will download in the background after giving you the chance to pick/change a file name. I haven't the foggiest idea on how to implement a file picker in iOS yet, nor if using that protocol would be allowed by the App Store reviewers. But my app now does correctly handle downloading from session-authentication sites like your PHP forum.
Swift 4:
ChrisOSX's sollution also solved my issue. I'm trying to download a document from a link on a site after logging to that site. I've used WKZombie to scrape the link, and then I wanted to download the file using Alamofire. I added this
if let httpResponse = navigationResponse.response as? HTTPURLResponse, let url = httpResponse.url {
let allHeaders = httpResponse.allHeaderFields.reduce([String : String](), { (result, next) -> [String : String] in
guard let stringKey = next.key as? String, let stringValue = next.value as? String else { return result }
var buffer = result
buffer[stringKey] = stringValue
return buffer
})
let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHeaders, for: url)
for cookie in cookies {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
to:
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: #escaping (WKNavigationResponsePolicy) -> Void)
After this, the cookies are stored in the shared cookies, and I was able to download the file with Alamofire without and changes to the download methods..

IOS8: UIWebView memory leak

App description:
I want to develop an app, which shows websites during set time. If time elapsed, it will load next website etc. It must be run as loop: if last website showed, it shoes first.
AppDelegate was not changed.
Storyboard has a Navigation Controller with this ViewController, which include UIWebView:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIWebViewDelegate>
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIWebView *mWebView;
#end
#implementation ViewController
NSMutableArray *mSites;
NSInteger mIndex;
- (void)viewDidLoad {
NSLog(#"%s", __PRETTY_FUNCTION__);
[super viewDidLoad];
mSites = [[NSMutableArray alloc] init];
[mSites addObject:#"http://www.bild.de"];
[mSites addObject:#"http://www.spiegel.de"];
[self setWebView];
mIndex = -1;
[self showNext];
}
- (BOOL)prefersStatusBarHidden
{
NSLog(#"%s", __PRETTY_FUNCTION__);
return YES;
}
- (void)setWebView
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[(self.mWebView.subviews)[0] setBounces:NO]; // No overscroll
[self.mWebView setDelegate:self];
}
- (void)freeMemory
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[self.mWebView loadHTMLString:#"" baseURL:nil];
[self.mWebView stopLoading];
[self.mWebView setDelegate:nil];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
- (void)webViewDidFinishLoad: (UIWebView *)webView
{
NSLog(#"%s", __PRETTY_FUNCTION__);
// Clear cache
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"WebKitCacheModelPreferenceKey"];
}
- (void)handleTimer: (NSTimer *)timer
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[self freeMemory];
[self setWebView];
[self showNext];
}
- (void)showNext
{
NSLog(#"%s", __PRETTY_FUNCTION__);
// Loop
if (mIndex < [mSites count] - 1) {
mIndex++;
} else {
mIndex = 0;
}
NSString *site = [mSites objectAtIndex:mIndex];
NSURL *url = [NSURL URLWithString:site];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.mWebView loadRequest:request];
[NSTimer scheduledTimerWithTimeInterval:15
target:self
selector:#selector(handleTimer: )
userInfo:nil
repeats:NO];
}
- (void)didReceiveMemoryWarning
{
NSLog(#"%s", __PRETTY_FUNCTION__);
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
[self.mWebView reload];
}
#end
Trouble:
I use for testing iPad Air (A1474) and used two websites: http://www.bild.de and http://www.spiegel.de. After ca. 30 minutes crashes the app because of memory usage. The app use more than 300Mb.
I found more solutions to handle the memory leak trouble and integrate them in my code:
- (void)freeMemory
{
[self.mWebView loadHTMLString:#"" baseURL:nil];
[self.mWebView stopLoading];
[self.mWebView setDelegate:nil];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
}
- (void)webViewDidFinishLoad: (UIWebView *)webView
{
// Clear cache
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:#"WebKitCacheModelPreferenceKey"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self.mWebView reload];
}
But the solutions do not take effect. The app do not run longer than a hour.
Have somebody a solution how I can reach a app running time for at least a day for every?
Thanks in advance for suggestions.

How to use a pull to refresh in a WebView ( iOS 5 )?

How can I make a "Pull to refresh" in iOS 5 for an UIWebView ? I can't find a tutorial.
I have got a WebView in a Tab Bar application, and I want to refresh the WebView with a "Pull to refresh" like Twitter.
Where can I find a complete tutorial ?
Thank you
I cannot provide a tutorial, maybe I'll write one but I think it was quite simple,
I did this slightly modifying SPPullView.
Here you can grab the files (SPPullView.m and SPPullView.h).
Relevant code in the main UIViewController is something like:
- (void)viewDidLoad
{
[super viewDidLoad];
self.pullView = [[SPPullView alloc] initWithScrollView:self.webView.scrollView];
[self.pullView setDelegate:self];
[self.webView.scrollView addSubview:self.pullView];
[self.webView.scrollView setDelegate:self];
for (UIView *subview in [self.webView.scrollView subviews] ) {
subview.userInteractionEnabled = NO; // used to disable copy/paste, etc inside the webview
}
//[self doYourStuff];
}
//Called when the user pulls to refresh (this is when you should update your data)
- (void) pullViewShouldRefresh: (SPPullView *) view {
[self updateYourStuff];
}
You can also add some logic or properties to prevent the user zooming, or deactivate the pull view temporarily while zooming.
This works very well: http://blog.gomiso.com/2012/03/22/yet-another-pull-to-refresh-library/
I wrote this code and it is working fine. This may help you.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *fullURL = URL you want to hit;
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObject = [NSURLRequest requestWithURL:url];
webView.delegate = (id)self;
[webView loadRequest:requestObject];
UIRefreshControl *refreshControlOnPull = [[UIRefreshControl alloc] init];
[refreshControlOnPull addTarget:self action:#selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[webView.scrollView refreshControlOnPull]; //<- this is point to use. Add "scrollView" property.
}
-(void)handleRefresh:(UIRefreshControl *)refresh {
// Reload my data
NSString *fullURL = The Url you want to hit;
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObject = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObject];
[refresh endRefreshing];
}

Resources