Catch mailto links in WebView - macos

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
}

Related

SoundCloud OSX Oauth process doesn't create account unless cancelled

I've been trying to use the CocoaSoundCloudAPI to create a basic desktop app for OSX in Cocoa.
I'm struggling with authentication. Clicking a login button opens up an external browser window that tries to give my app authentication. If I click "Connect" the connect button shows a lovely animation... forever, and [SCSoundCloud account] is null.
However, if I click "Cancel" in the external browser window during this process, I see that SCAccount becomes !nil
Can anyone explain this?
Here's my code:
#import "SCMAppDelegate.h"
#implementation SCMAppDelegate
+ (void)initialize
{
[SCSoundCloud setClientID:#"MYID"
secret:#"MYSECRET"
redirectURL:[NSURL URLWithString:#"sampleproject1://oauth"]];
}
- (IBAction)login:(id)sender
{
[SCSoundCloud requestAccessWithPreparedAuthorizationURLHandler:^(NSURL *preparedURL){
// Load the URL in a web view or open it in an external browser
[[NSWorkspace sharedWorkspace] openURL:preparedURL];
}];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
{
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
andSelector:#selector(handleURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
andEventID:kAEGetURL];
}
- (void)handleURLEvent:(NSAppleEventDescriptor*)event
withReplyEvent:(NSAppleEventDescriptor*)replyEvent;
{
NSString* url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
BOOL handled = [SCSoundCloud handleRedirectURL:[NSURL URLWithString:url]];
if (!handled) {
NSLog(#"The URL (%#) could not be handled by the SoundCloud API. Maybe you want to do something with it.", url);
}
NSLog(#"This is the account: %#", [SCSoundCloud account]);
}
#end
I've been using https://github.com/soundcloud/CocoaSoundCloudAPI/blob/master/GeneralUsage.md as a guide, and have found most things to work. Can anyone push me in the right direction?
I did some NSLogging and found that, in fact, I was receiving a valid SoundCloud Account object, it just needed some more time to receive the object back.
I was, however, surprised that my external browser window never received a notification to indicate that connection had completed - is this an error on my behalf or a regular occurrence when it comes to external oauth2 requests?
It seems that, even if I use Facebook authorisation with my app, I never get notified in the browser page that authentication has completed. Does anyone know how I can achieve this? I'm quite sure that my callback url is correct, but I'll keep trying...

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.

MacOSX Custom Webkit view + Flash content with clickable links

Symptom:
View the flash website with any browser, the links inside the flash content work and launch a new window
view the flash with my custom WebView, click the same links. No response.
I tried delegating "decidePolicyForNewWindowAction" and "decidePolicyForNavigationAction" but ironically, these are only called after I launch a URL from my code, NOT as a response to the user clicking the link from the page.
I am sure the fact this is a flash app content has something to do with it. I don't know how to resolve this. Help will be appreciated.
You'll need to set a UIDelegate for the WebView, and then implement - (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request in that delegate.
If you then set a policy delegate for the new WebView that you return (that WebView can be in a hidden window), the delegate method that will be called is:
- (void)webView:(WebView *)aWebView
decidePolicyForNavigationAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id < WebPolicyDecisionListener >)listener`
The URL to which the Flash app is trying to send the window is in the WebActionOriginalURLKey of the actionInformation dictionary, and you can at that point decide if you want the navigation to proceed, or send an ignore to the WebPolicyDecisionListener and handle the URL some other way.

WebView integration

I am wondering how to integrate a WebView in a cocoa application:
- How to call javascript function from cocoa in the WebView
- How to handle in cocoa the click in a link inside the WebView
...
Thanks in advance for your help
First of all, there is no NSWebView in cocoa, it's called UIWebView on the iphone and WebView on Mac.
If you want to simply load a page with the webview, create an NSURLRequest (using NSURL) then call - (void)loadRequest:(NSURLRequest *)request
If you want to use javascript functions, just make an NSString containing your script, then call - (NSString*)stringByEvaluatingJavaScriptFromString:(NSString *)script.
I don't fully understand why you want to handle a click inside the webview... If you want to detect a redirect, there is a delegate method that can help you:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

Using web view behind a proxy (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.

Resources