I have a UIWebView that is handling an OAuth authentication flow in my app. The callback URL that the OAuth service uses points to a custom URL scheme I've set up in my app, let's call it mycustomurlscheme.
So once the user authenticates successfully, the OAuth service redirects them to the URL mycustomurlscheme://oauth/success?oauth_token=xxxxxxxxxxxxxxxxxxxx&oauth_verifier=xxxxxxxxxxxxxxxxxxxx. When the UIWebView requests this URL, the app behaves correctly; namely, the application:openURL:sourceApplication:annotation: method in my app delegate gets called, and I dismiss the UIWebView and continue on with the app.
However, I am logging load failures in the UIWebView (using webView:didFailLoadWithError:), and when the above process happens, I see the following in the console:
Error Domain=WebKitErrorDomain Code=102 "Frame load interrupted" UserInfo=0xa1a4810 {NSErrorFailingURLKey=mycustomurlscheme://oauth/success?oauth_token= xxxxxxxxxxxxxxxxxxxx&oauth_verifier=xxxxxxxxxxxxxxxxxxxx, NSErrorFailingURLStringKey=mycustomurlscheme://oauth/success?oauth_token= xxxxxxxxxxxxxxxxxxxx&oauth_verifier=xxxxxxxxxxxxxxxxxxxx, NSLocalizedDescription=Frame load interrupted}
I tried implementing the following UIWebViewDelegate method, thinking that intercepting the request would avoid the error, but the error still happens:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType
{
if ([request.URL.scheme isEqualToString:@"mycustomurlscheme"]) {
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
} else {
return YES;
}
}
This code then causes the following code in my app delegate to run:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSNotification *notification = [NSNotification notificationWithName:kDSApplicationLaunchedWithURLNotification object:nil userInfo:@{kApplicationLaunchOptionsURLKey: url}];
[[NSNotificationCenter defaultCenter] postNotification:notification];
return YES;
}
This notification is picked up by the following block that continues the loading & launching of the app, post-authorization:
self.applicationLaunchNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kDSApplicationLaunchedWithURLNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
NSURL *url = [notification.userInfo valueForKey:kApplicationLaunchOptionsURLKey];
currentRequestToken.verifier = [DSAPIParametersFromQueryString([url query]) valueForKey:@"oauth_verifier"];
[[DSAPIManager sharedManager] acquireAccessTokenWithRequestToken:currentRequestToken success:^(DSAPIOAuth1Token * accessToken) {
[self finishLogin];
} failure:^(NSError *error) {
[self removeAsObserver];
[self showAlert:NSLocalizedString(@"Could not authorize the app. Please try again later.", nil)];
}];
}];
The finishLogin and removeAsObserver methods look like this:
- (void)finishLogin
{
[self removeAsObserver];
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self performSegueWithIdentifier:@"PostLoginSegue" sender:self];
}];
}
- (void)removeAsObserver
{
if (self.applicationLaunchNotificationObserver) {
[[NSNotificationCenter defaultCenter] removeObserver:self.applicationLaunchNotificationObserver];
self.applicationLaunchNotificationObserver = nil;
}
}
Is it safe to ignore this error message? Anyone know why it's happening? My hunch is that the UIWebView thinks the URL has an invalid scheme, but the phone knows it's ok. If that's the case is there any way to tell the UIWebView (or the WebKit engine) that this scheme is valid?