Search code examples
iosobjective-cuiwebviewmailto

UIWebView ignoring mailto


I am trying to get mailto links working with UIWebView.

So far I am using the delegate below to open a range of things (http://, file:// etc) and they all work fine. However it seems as if mailto doesn't even get there, if I do an alert for every url passed into it, all of the others alert but there is nothing for mailto links.

Xcode does throw

WebKit discarded an uncaught exception in the webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener: delegate: <NSRangeException> *** -[__NSArrayI objectAtIndex:]: index 4294967295 beyond bounds [0 .. 0]

Delegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

NSURL *url = request.URL;
NSArray *components = [url.absoluteString componentsSeparatedByString:@"/"];
NSString *folder = [components objectAtIndex:[components count]-2];

UIAlertView *display_url = [[UIAlertView alloc]initWithTitle:@"Warning" message:[NSString stringWithFormat:@"URL %@ ", request.URL.scheme] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];

[display_url show];

[...]

Any ideas as to why "mailto" links would be ignored and throw the error?


Solution

  • These 2 lines are the reason:

    NSArray *components = [url.absoluteString componentsSeparatedByString:@"/"];
    NSString *folder = [components objectAtIndex:[components count]-2];
    

    According to the the RFC, there are no slashes in mailto: URLs. So the components array contains only 1 object (the whole URL). Then you request an object at index -1, which throws an exception. The WebKit seems to catch the exception (your app will crash otherwise) and display the message you posted.

    In general it is a good idea to check your input (URLs in this case. You can't assume that the URL will always be like "protocol://domain.com/something/something-else". There are many possible cases here (like relative paths).

    As for parsing mailto URLs, you can find an example in this answer.