In log out action, we are terminating the session by using terminate() method of session. But after log-out, if we click on back button of the browser, i can able to see the content of last page, but i am unable to do any action(This is fine). If we clear the browser cache after log-out, there is no problem. So we found, it is because of browser cache.
So please let us know how to clear the browser cache from webobjects application programmatically.
I actually think it may retain cached information when you close out the UIWebView. I've tried removing a UIWebView from my UIViewController, releasing it, then creating a new one. The new one remembered exactly where I was at when I went back to an address without having to reload everything (it remembered my previous UIWebView was logged in).
So a couple of suggestions:
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:NSURLRequest];
This would remove a cached response for a specific request. There is also a call that will remove all cached responses for all requests ran on the UIWebView:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
After that, you can try deleting any associated cookies with the UIWebView:
for(NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
if([[cookie domain] isEqualToString:someNSStringUrlDomain]) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}
}
Happy Coding :)
Deepak
Related
I understand that as of iOS9 you should be able to read cookies with SFSafariViewController.
If I set a cookie on my page in JS using the following:
var dd = new Date(Date.now() + 1000 * 60 * 60 * 24).toGMTString();
var expires = "expires="+ dd;
document.cookie = "mycookie=cookievalue; " + expires + " domain=.mydomain.co.uk ; path=/ ";
If I do :
- (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully
{
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookiesArray = [storage cookies];
}
cookiesArray is always empty.
If I use a traditional UIWebView
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookiesArray = [storage cookies];
}
I get the cookie I was expecting.
Any ideas what I might be doing wrong?
SFSafariViewController is basically a Safari process, running outside of your app. Your app will not have any access to the cookies used by the SFSafariViewController, just as your app has no access to the cookies in the Safari app itself.
If you need this functionality, you'll need to stuck with UIWebView or WKWebView.
SFSafariViewController runs in a separate process, so reading cookies is NOT possible.
However, in case SFSafariViewController is the only option available due to some limitations with the existing available options like WKWebView, and UIWebView.Then the custom URL scheme approach will be helpful in sending the data from SFSafariViewController to the parent App which initiates the SFSafariViewController.
In the above case, a possible URL will be as follows, where "myapp" is the custom URL scheme
"myapp://SendData?mycookie=cookievalue&domain=.mydomain.co.uk&path=/"
So, the custom URL scheme will be registered against the parent app to launch it and custom URL scheme parameters will have the intended data to be received by the parent app. If the data is sensitive then it can be encrypted by javascript prior to sending and can be decrypted by the parent app after receiving it.
Hope this would help :)
For more details on the custom URL scheme, please visit
https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
I am implementing one simple login-logout controller for my application. I am using a GET request for the login screen and segue to get the secondViewController. At the second view controller there is logout button that when pressed returns back to loginView - But whatever I type in the fields I always get in until I close the app (so the cache is playing part here)
Is there any good way to clear the cache. I have tried to do that by alloc init NSURLCache at the beginning of the request and then set removeAllCachedResponses but its not doing any difference.
Any other suggestions?
Try to remove all your cookies from the cookie store upon logout:
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [storage cookies]) {
[storage deleteCookie:cookie];
}
AFNetwork uses the shared NSURLCache you can clear this one by call the
removeAllCachedResponses on the shared cache
[[NSURLCache sharedURLCache] removeAllCachedResponses];
I'm very new to iOS development so please be gentle.
I understand that webViewDidFinishLoad will fire for each <iframe> plus the original html page.
I'm trying to find the URL of the request that resulted in that webViewDidFinishLoad. As far as I can tell, I can only access webView.request.mainDocumentURL.
I find this perplexing. Inside the shouldStartLoadWithRequest method, which fires also for each <iframe> and the original html request, you can access the URL in question, be it the iframe or the parent page.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"Parent page request: %#", request.mainDocumentURL);
NSLog(#"Actual URL request: %#", [request URL]); // This returns what I want.
return YES;
}
That first log statement will output the url.
However, inside webViewDidFinishLoad
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSURLRequest* request = [webView request];
NSLog(#"Parent page request: %#", request.mainDocumentURL);
NSLog(#"Request outputs the parent, not the iframe: %#", [request URL]);
// how do I access the <iframe> url?
}
Help me StackOverflow. My google-fu is weak and your wisdom is strong.
EDIT: I should be clear on the goal of this. I want to Do Stuff™ when the load event of the parent page fires, not for iframes. I want this to happen as soon as possible, so I don't want to wait until everything finishes.
Think of the UIWebView as your browser. The scope of the object you are interrogating is at the browser level, the iFrames are more granular than that. The URL that populates the iFrame is used to stream content for that section of the page, but for the purposes of the UIWebView, you only need to remember the main URL so the page can be managed (reloaded, etc...) as that URL clearly brings with it instructions as to how to manage the iFrame's content.
If you really need to those iFrame source URLS, simply extendeding UIWebView to hold an array of links (populate the array inside "shouldStartLoadWithRequest"). You can then do whatever you want with that list of links.
Good Luck.
Background
I am developing a simple iPad application that allow the user to browse the same website with different logins at the same time. Therefore I have two UIWebView and they should have different cookie storage so the user can login one account on the first UIWebView and another account on the second UIWebView.
What have I tried?
I think the solution is to implement different cookie storages in the two UIWebView I have.
Sasmito Adibowo wrote an article Implementing Your Own Cookie Storage which provide details on how to use a custom cookie storage for WebView on Mac.
It is done by modify the NSURLRequest that WebView is going to send, adding cookie headers to it, and also intercept the response from WebView and extract the cookies from the response header and save it to our own cookie storage.
Technically, it is done by implementing these two delegate methods:
- (void)webView:(WebView *)sender resource:(id)identifier didReceiveResponse:(NSURLResponse *)response fromDataSource:(WebDataSource *)dataSource
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
Although it is undocumented, UIWebView did support one of the method above with a slightly different method name:
- (NSURLRequest *)uiWebView:(UIWebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(id)dataSource
However, UIWebView don't have a equivalent delegate method for webView:resource:didReceiveResponse:fromDataSource: and hence I cannot extract the cookies from the response headers.
The Question
Is there a way to have UIWebView to use a custom cookie storage, so the two UIWebView can have their own cookie storage?
Thanks!
Have you tried getting the cookies associated with a particular webview (and holding onto them) in webViewDidStartLoad:
NSHTTPCookie *cookie;
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [cookieJar cookies]) {
[self.cookies addObject:cookie];
}
And storing these cookies right after (retrieve values and keys from self.cookies):
NSMutableDictionary *cookieDict = [NSMutableDictionary dictionary];
[cookieDict setObject:#"value1" forKey:NSHTTPCookieName];
[cookieDict setObject:#"value2" forKey:NSHTTPCookieValue];
[cookieDict setObject:#"value3" forKey:NSHTTPCookieDomain];
...etc..
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieDict];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
You'll also need to see this in your viewDidLoad:
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
If you're willing to dig a little deeper, the used-to-be famous ASIHttpRequest knew how to arrange this back in the day.
Read switching cookie storage for requests.
They also have an interesting wrapper for UIWebView requests, AKA ASIWebPageRequest.
Sadly, the project has since been discontinued, but it should provide you with an operation ground to achieve your goal.
Otherwise, as bdev has presented, I would queue the requests and replace the cookie storage each time, before firing a request. You could use the dispatcher nicely here.
I'm trying to download the specified web pages with their inner page resources to disk.
When I send a NSURLRequest, only the initial URL would be request, but the resources as images,css,js would not be download.
Someone suggests to use cache, but I don't want to cache every web page browsed in the uiwebview, but only the one I specified.For example, when I input an url to the uiwebview addressbar then click on the "save" button, the page will be saved entire, but the other browsing in the webview will not be cached automatically.
Does there any way to download the entire webpages?
Thank you very much!
I ran in the same problem once, and I solved it using ASIWebPageRequest . It was old by the time, but still works.
I wrote a method (based on sample method) for download a webpage in a folder. You need to modify this to get it work.
- (IBAction)loadURL:(NSURL *)url inFolder:(NSString*)folderPath
{
// Assume request is a property of our controller
// First, we'll cancel any in-progress page load
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[[self request] setDelegate:nil];
[[self request] cancel];
[self setRequest:[ASIWebPageRequest requestWithURL:url]];
[[self request] setDelegate:self];
[[self request] setDidFailSelector:#selector(webPageFetchFailed:)];
[[self request] setDidFinishSelector:#selector(webPageFetchSucceeded:)];
// Tell the request to embed external resources directly in the page
[[self request] setUrlReplacementMode:ASIReplaceExternalResourcesWithData];
self.theCache.storagePath = folderPath;
// It is strongly recommended you use a download cache with ASIWebPageRequest
// When using a cache, external resources are automatically stored in the cache
// and can be pulled from the cache on subsequent page loads
self.request.cacheStoragePolicy = ASICachePermanentlyCacheStoragePolicy;
[[self request] setDownloadCache:self.theCache];
// Ask the download cache for a place to store the cached data
// This is the most efficient way for an ASIWebPageRequest to store a web page
//[[self request] setDownloadDestinationPath:
//[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:[self request]]];
[[self request] setDownloadDestinationPath:[self.theCache pathToStoreCachedResponseDataForRequest:[self request]]];
[[self request] startAsynchronous];
}
I used ASIDownloadCache too.
...
ASIDownloadCache *localCache = [[ASIDownloadCache alloc] init];
self.theCache = localCache;
...
You could implement a custum NSUrlCache and save everything. Everything that is downloaded using a NSUrlRequest will use the NSUrlCache. Everything a UIWebView does uses the NSUrlRequest. If you need a sample, then have a look at https://github.com/evermeer/EVURLCache