Private browsing with UIWebView on the iPhone & iPad - iphone

How do existing apps implement this feature???
Can I store cookie only for certain sites, and only inside my app? It's my understand that the web view stores cookies in shared mode...so that they are shared with Safari and other apps that use UIWebView.

According to the NSHTTPCookieStorage docs, cookies are not shared between applications:
iPhone OS Note: Cookies are not shared
among applications in iPhone OS.
So it seems like they should be "private" by default. You can also use the [NSHTTPCookieStorage sharedHTTPCookieStorage] object to set the cookie storage policy to not store cookies at all, or you could use the deleteCookie: method to clean up after yourself if you needed to.
As for other content that is loaded by your UIWebview, when you create the NSURLRequest that is loaded by your webview, you can set a cache policy that controls if the content will be cached. For example:
NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: url]
cachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval: 60.0]
[webView loadRequest: request];
NSURLRequestReloadIgnoringLocalAndRemoteCacheData tells the request to ignore the cache and load the request from the network. I'm not sure if it also prevents the response from the network from being cached, but to be sure, you could alway remove it from the cache yourself:
[NSURLCache sharedURLCache] removeCachedResponseForRequest:request];

If you're talking about Private Browsing, the UIWebView actually does not store history after the app is closed (only temporary for going back and forth). Instead you would have to implement storing history yourself, so it would be automatically Private Browsing.
Short answer: Don't do anything. Its already in Private Browsing mode.
EDIT: For handling cache check out this method:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
And make cashedResponse return nil.

Related

Loading web view taking more time with ASIHTTPRequest in ios

In my browser based application, I need to set a proxy for each url and doing this with the help of ASIHTTPRequest.
The problem I am facing is that the web view is taking double the time to load the page, probably because I am loading the page twice in my code.
First I check the status with ASIHTTPRequest to determine if the page is allowed to load by ASIHTTPRequest and if so, then I load that url on web-view.
This is where I think the problem is as I think I am loading the url two times which is consuming time.
Can you make a suggestion on other ways to load page once, but in a way that supports checking for authenticated page with usage of proxy settings, or provide me with a link to guide relevant to this question?
NSString *response = [NSString stringWithContentsOfFile:
[theRequest downloadDestinationPath] encoding:[theRequest responseEncoding] error:nil];
int statusCode = [requestH responseStatusCode];
if (statusCode == 200) {
[webV loadRequest:[NSURLRequest requestWithURL:[requestH url]]];
}
else {
[webV loadHTMLString:response baseURL:[theRequest url]];
}
Implement the delegate methods of NSURLConnection (apple docu) and in the connectionDidFinishLoading save the content of the url to a local file and then in load this local file with loadHTMLString.

UIWebview slow loading secured page

I have a site I'm loading with a UIWebView that has some problems loading when secured with Basic Authtype of Apache:
NSString * myUrlAddress = [NSString stringWithFormat:#"http://user:pass#mysite.mydomain.com"];
NSURL *url = [NSURL URLWithString:myUrlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
[webView loadRequest:requestObj];
Initial loading works most of the times, but sometimes, especially on reloading of the app the callback
- (void)webViewDidFinishLoad:(UIWebView *)webViewloc
is not reached, and it is also not running into
-(void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error
If I use a different server without .htaccess to secure the page it all works fine.
I also see in the access log, that it sometimes just stops loading from the page.
Has this something to do with cachePolicy or timeoutInterval ?
You could try to manage the authentication challenge coming from the server on your own, since it seems that UIWebView is not able to handle it.
This requires setting up your own NSURLRequest/Connection and handle the challenge in the connection:didReceiveAuthenticationChallenge delegate method before trying to load the actual html page in your UIWebView.
You can find full sample code here for a GET request. You might also check into a third-party networking framework that makes handling the communication and the challenge easier (e.g., ASIHTTPRequest, although it is now in a "frozen" state it works well; or AFNetworking)
NSString * myUrlAddress = [NSString stringWithFormat:#"http://user:pass#mysite.mydomain.com"];
NSURL *url = [NSURL URLWithString:myUrlAddress];
[webView loadRequest:[NSURLRequest requestWithURL:url]];

Embedding a Smart URL inside an App

I want to embed a URL inside an iPhone app, that will take the user to a landing page which later on I can redirect that URL to an iTunes App link once it becomes available, all that without resubmitting the App for approval again. Is this possible?
Thanks
Yes. Use the openURL: method of UIApplication to open your landing page URL. When you want to swap it out, have your favourite server-side language perform a 301 or 302 redirect, depending on whether the redirect is permanent or not.
Having said that, if all you want to do is direct people to rate the app or something similar to that, you don't need to swap it out; the application ID is all you need to construct the URL and iTunes Connect gives you that when you register the app, before you upload the binary.
You can use a short URL or any other URL with a redirection, then in your code intercept the redirection to avoid opening Safari if it's not necessary:
Create a NSURLConnection:
NSURL *shortURL = [NSURL URLWithString:#"http://tinyurl.com/xxyy"];
NSURLConnection *conn = [[NSURLConnection alloc]
initWithRequest:[NSURLRequest requestWithURL:shortURL]
delegate:self
startImmediately:YES];
Define some delegate methods. In your class, define an NSURL property finalDestination to hold the final URL.
- (NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)response
{
finalDestination = [response URL];
return request;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (!finalDestination) {
/* redirect failed, use backup url */
finalDestination = /* backup url */
}
[[UIApplication sharedApplication] openURL:finalDestination];
}
Also, check Apple Technical Q&A Launching the App Store from an iPhone application.
(Note: ARC code)

Tracking iPhone on Yahoo Web Analytics using ASIHTTPRequest

I'm trying to track an event in my app using Yahoo Web Analytics. The code I am using looks like
ASIHTTPRequest *yahooTrack = [ASIHTTPRequest requestWithURL:
[NSURL URLWithString:#"http://s.analytics.yahoo.com/p.pl?a=xxxxxxxxxxxxx&js=no&b=yyyyyyyyyyyy&cf6=zzzzzzzzzzz"]];
yahooTrack.didFinishSelector = #selector(statisticsFinished:);
yahooTrack.delegate = self;
[yahooTrack startAsynchronous];
Then the statisticsFinished looks like:
NSLog(#"Cookies: %#", request.requestCookies);
NSLog(#"Redircount: %d", [request redirectCount]);
NSLog(#"Responsecode %d %#\nMsg: %#", request.responseStatusCode,
request.responseStatusMessage, [request responseString]);
And all the information I get back looks correct. Cookies are set, redirectcount is 1 the first time (as it redirects to s.analytics.yahoo.com/itr.pl?.... a normal browser does). Then the redirectcount is 0 for subsequent request until the app is restarted and session cleared. The responseString returns GIF89a.
Even if the data looks correct, Yahoo still won't track. As soon as I call the tracking url directly in my browser it works as expected.
I realize Flurry is a better option, but I'm forced to use Yahoo in this case. Also, using a UIWebView probably would work, but I'm against putting in a webview just for tracking purposes.
Is there any difference in how ASIHTTPRequest and Safari would handle a call to a simple URL as this? Or do you see anything else that could explain why the tracking isn't working?
I finally found the problem. ASIHTTPRequest creates a user-agent based on your applications name, and requests from this user agent is ignored by Yahoo somehow (bug?). As stated in the documentation, you can override the user-agent as follows:
[request addRequestHeader:#"User-Agent" value:#"My-User-Agent-1.0"];
I used the user-agent string of Safari on iPhone, and it worked immediately! BTW; the same problem applies for Android, and the same fix works.

Spoofing the user agent of an embedded Safari browser on the iPhone?

Is there any way to spoof the user agent on Safari on the iPhone?
So for example, you would create an application on the iPhone that has the embedded Safari browser, however any website the user visits with this browser wouldn't know you were on Safari on the iPhone, it would think you are on something like Safari on a PC, or even IE/FireFox.
Thanks
Yes I think you could change this. It would require a bit of a work around to get it working.
You would need to manually manage all requests. By making your own data requests.
In this data request you can add a HTTPheader for User-Agent which will override the default headers.
NSMutableURLRequest* urlRequest = [[[NSMutableURLRequest alloc] initWithURL:requestURL] autorelease];
[urlRequest setHTTPMethod: #"POST"];
[urlRequest setHTTPBody: [nvpString dataUsingEncoding:NSUTF8StringEncoding]];
[urlRequest addValue:#"Your+User+Agent+String" forHTTPHeaderField:#"User-Agent"];
receivedData = [[NSMutableData alloc] retain];
[receivedData setLength:0];
[NSURLConnection connectionWithRequest: urlRequest delegate: self];
If you embed the Safari Web Browser in your app you can subscribe to its delegate methods. One of them will notify your application that safari would like to load a URL, this is where you catch this load and get the data your self.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
now you put your code in here to do the data load.
Once the data has loaded. Give it the data string back to the webView. I have set "baseURL:nil" but you might have to correctly set this to maybe the correct domain for this app.
[webView loadHTMLString:newString baseURL:nil]