UIWebView加载失败,并带有自定义URL方案

我有一个UIWebView,它在我的应用程序中处理OAuth身份validation流程。 OAuth服务使用的回调url指向我在我的应用中设置的自定义url方案,我们称之为mycustomurlscheme

因此,一旦用户成功进行身份validation,OAuth服务会将其重定向到URL mycustomurlscheme:// oauth / success?oauth_token = xxxxxxxxxxxxxxxxxxxx&oauth_verifier = xxxxxxxxxxxxxxxxxxxx 。 当UIWebView请求此URL时,该应用程序行为正常; 即application:openURL:sourceApplication:annotation:我的应用程序委托中的方法被调用,我关闭UIWebView并继续使用该应用程序。

但是,我在UIWebView中记录加载失败(使用webView:didFailLoadWithError: ,当上述过程发生时,我在控制台中看到以下内容:

 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} 

我尝试实现以下UIWebViewDelegate方法,认为拦截请求可以避免错误,但错误仍然发生:

 - (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; } } 

此代码然后导致我的应用程序委托中的以下代码运行:

 - (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; } 

此通知由以下块接收,该块继续加载和启动应用程序,授权后:

 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)]; }]; }]; 

finishLoginremoveAsObserver方法如下所示:

 - (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; } } 

忽略此错误消息是否安全? 有人知道为什么会这样吗? 我的预感是UIWebView认为URL有一个无效的方案,但手机知道它没问题。 如果是这种情况有什么办法告诉UIWebView(或WebKit引擎)这个方案是有效的?

这里的错误实际上是Frame load interrupted与url方案无关。 使用自定义url方案是完全可能的,不会产生任何错误。 我在他的许多应用程序中都有它们,并且从未遇到任何问题。

我相信你的问题是因为[webView stoploading]; 从技术上讲,当你return NO时会停止加载,所以[webView stopLoading]; 只会导致过程中断。 删除这一行,让它继续return NO ,看看会发生什么,我99.9%肯定这是原因。

所以你的代码看起来像

 - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { if ([request.URL.scheme isEqualToString:@"mycustomurlscheme"]) { // Dismiss the view controller, continue loading the app, etc. return NO; } return YES; // No need for the else statement if this is the only thing to happen if it fails the if statement. } 

UPDATE

基于don评论删除[webView stopLoading]; 没有解决你的问题。 如果是这种情况,你将其纳入if语句,我怀疑还有其他事情发生。 你有共享所有代码吗? 有了这个// Dismiss the view controller, continue loading the app, etc.在你的代码中// Dismiss the view controller, continue loading the app, etc.我怀疑你没有分享所有内容,在这种情况下我们无法提供帮助。

检查“standardUserDefaults”中是否有“UserAgent”的内容。 UserAgent很可能会在请求URL中附加。 或者检查在url请求中发送的任何“UserAgent”。