Using web view behind a proxy (cocoa) - cocoa

I'm creating a web-browser type app (using a web view object) that needs to be able to connect to the internet via a proxy. Server, port, username and password can all be hardcoded into the app but unfortunately I have no idea how to customise the proxy settings of a web view without changing the system wide proxy settings.
If you know how to do this please provide some example code, thanks a lot!
(Also, if it changes anything - I'm developing for mac, not iPhone)

The easiest way I know is to wire up a UIWebView delegate and listen to all requests before they go through, and redirect the ones you care about through ASIHttpRequest and your custom proxy settings.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// Configure a proxy server manually
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:#"192.168.0.1"];
[request setProxyPort:3128];
// Alternatively, you can use a manually-specified Proxy Auto Config file (PAC)
// (It's probably best if you use a local file)
[request setPACurl:[NSURL URLWithString:#"file:///Users/ben/Desktop/test.pac"]];
// fire the request async
[request setDelegate:self];
[request startAsynchronous];
return NO;
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
// todo: save data to disk and load with [self webView]
}
It's a bit wonky,but it should work. Just remember to manage your memory properly and don't use this leaky example code... YMMV, I haven't even tested if this compiles, typed it all in the browser window with some copy and paste hackery.

Related

how to make NSURL point to local dir?

reading Adium code today, found an interesting usage of NSURL:
NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:#"adium://%#/adium", [messageStyle.bundle bundleIdentifier]]];
[[webView mainFrame] loadHTMLString:[messageStyle baseTemplateForChat:chat] baseURL:baseURL];
I tried to log the url and got this adium://im.adium.Smooth Operator.style/adium, Then I created a blank project to see how to create such an NSURL but failed. When I sending loadHTMLString message to a webview's frame in my project, if the baseURL is nil, everything is fine, if not, I got a blank page in the view.
here is my code, the project name is webkit
NSURL *baseURL = [NSURL URLWithString:#"webkit://resource"];
//if baseURL is nil or [[NSBundle mainBundle] bundleURL], everything is fine
[[webView mainFrame] loadHTMLString:#"<html><head></head><body><div>helloworld</div></body></html>"
baseURL: baseURL];
[frameView setDocumentView:webView];
[[frameView documentView] setFrame:[frameView visibleRect]];
the question is how to make a self defined protocol instead of http://?
adium://%#/adium , first section is called protocol you can also register your protocol webkit: Take a look at How to map a custom protocol to an application on the Mac? and Launch Scripts from Webpage Links
[NSURLProtocol registerClass:[AIAdiumURLProtocol class]];
[ESWebView registerURLSchemeAsLocal:#"adium"];
I tried to find where did adium define the adium schema in the info.plist, unfortunately, there's nothing there, only some irc/xmpp protocols.
so I finally launched the debugger, and found the code above in the AIWebKitDelegate init method, anyway this is another way to register a self defined protocol~

WebView loads slowly in Mac OS

I have created plugin for Mail.app on Mac OS.
I'm using WebView to display web pages, all would be fine but web pages load slowly.
Then I created test cocoa application to compare loading time.
I was surprised when the test application loads page ~5 times faster.
In developer bar I saw my test application receives 304 code that indicates "the resource for the requested URL has not changed and cached resource can be used".
In contrast to the test application the plugin always receives 200 http code and loads resource again.
Maybe I should specify to use a cache in the webview, or I have some bundle permissions problems.
In the plugin, I tried to specify SharedURLCache like this
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:1024*1024*20
diskCapacity:1024*1024*5
diskPath:NSHomeDirectory()];
[NSURLCache setSharedURLCache:cache];
Then I tried subscribe to the ResourceLoadDelegate on the WebView and change request object like this
- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
{
if ([request cachePolicy] != NSURLRequestReturnCacheDataElseLoad)
{
return [NSURLRequest requestWithURL:[request URL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:[request timeoutInterval]];
} else {
return request;
}
}
Also I tried to change properties on WebView
[[webView preferences] setUsesPageCache:YES];
[[webView preferences] setCacheModel:WebCacheModelPrimaryWebBrowser];
but it's all not working.
Thanks for help.

Catch mailto links in WebView

Is there a method to this madness? I am trying to build a browser app for a kiosk that restrict much need for running additional applications and simply stay within one website.
I research and found decidePolicyForNavigationAction should work for what I want, but how do I start filtering URI schemes (mailto://, irc://, etc.)? Thanks!
You're implementing a WebView in your application to browse the web, right?
If yes, look into the WebPolicyDelegate Protocol reference.
Especially the following delegate might be of interest:
- (void)webView:(WebView *)webView
decidePolicyForNewWindowAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
newFrameName:(NSString *)frameName
decisionListener:(id < WebPolicyDecisionListener >)listener
Using the above delegate, you can validate any request, including mailto requests.
Quick example how to detect the URL scheme and decide wether to block:
NSLog(#"Request URL scheme = %#",[[request URL] scheme]);
if([[[request URL] scheme]isEqualToString:#"mailto"])
{
[listener ignore]; // Block Request
}
else
{
[listener use]; // Allow Request
}

Downloading an mp3 from link inside app

i'm making an mac app that downloads an mp3 from a link.
For example, this link: http://media.soundcloud.com/stream/VGGUdzU69Ng5?stream_token=2U9W2
As you can see, it is an mp3 file.
How can i download it to a specific path?
Thank you
The simplest way is to use NSURLDownload:
NSURL* url = [NSURL URLWithString:#"http://media.soundcloud.com/stream/VGGUdzU69Ng5?stream_token=2U9W2"];
NSString* destinationPath = [NSHomeDirectory() stringByAppendingPathComponent:#"someFile.mp3"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
NSURLDownload* download = [[NSURLDownload alloc] initWithRequest:request delegate:nil];
[download setDestination:destinationPath allowOverwrite:NO];
Ideally you'd set an object as the delegate so you can receive progress notifications and then release the NSURLDownload object when finished.
Probably the simplest way would be to set a policy delegate for your web view, and have that delegate respond to the question of what to do with that link by telling the listener to download.
Edit: Oh, missed the part about “to a specific path”. I've no idea on that; sorry. I hope someone else can fill in that aspect.

how to make web browser in Xcode load a web page automatically

I am building a web browser in Xcode cocoa application, using the interface builder. I have it all working when it comes to typing in web address and clicking go.
but I would like for it to automatically load a web page instead of seeing white when I open my project, I looked in inspector to see if you can set a specific web address but I couldn't find anything to do this.
How about if you load the URL that you would like in the viewdidload function:
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *targetURL = [NSURL fileURLWithPath:WebsitePath];
NSURLRequest *WebRequest = [NSURLRequest requestWithURL:targetURL];
[self.WebViewer loadRequest:WebRequest];
self.WebViewer.scalesPageToFit = YES;
}
Maybe you can try to load the WebView when the application finish launching,just add the URL Request in the applicationDidFinishLauching parameter,else if your WebView is on the MainView you can add a loadingScreen that appear while the webView is loading!
Lucky!

Resources