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

2024-01-03

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

因此,一旦用户身份验证成功,OAuth 服务会将其重定向到 URLmycustomurlscheme://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)];
                    }];
                }];

The finishLogin and removeAsObserver方法如下所示:

- (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 so the [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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIWebView 加载失败,自定义 URL 方案 的相关文章

随机推荐