我有一个UIWebView,它在我的应用程序中处理OAuth身份验证流程。 OAuth服务使用的回调网址指向我在我的应用中设置的自定义网址方案,我们称之为mycustomurlscheme
。
因此,一旦用户成功进行身份验证,OAuth服务会将其重定向到URL mycustomurlscheme:// oauth / success?oauth_token = xxxxxxxxxxxxxxxxxxxx& oauth_verifier = xxxxxxxxxxxxxxxxxxxx 。当UIWebView请求此URL时,该应用程序行为正常;即,我的app委托中的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;
}
}
然后,此代码会导致我的app委托中的以下代码运行:
- (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)];
}];
}];
finishLogin
和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引擎)这个方案是否有效?
答案 0 :(得分:1)
这里的错误实际上是Frame load interrupted
与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.
}
<强>更新强>
基于删除[webView stopLoading];
的评论并未解决您的问题。如果是这种情况,你将其纳入if语句,我怀疑还有其他事情发生。你分享了所有的代码吗?在您的代码中使用此// Dismiss the view controller, continue loading the app, etc.
,我怀疑您没有分享所有内容,在这种情况下我们无法提供帮助。
答案 1 :(得分:0)
检查&#34; UserAgent&#34;是否有任何内容。在&#34; standardUserDefaults&#34 ;. UserAgent很可能会在请求URL中附加。或者检查任何&#34; UserAgent&#34;发送网址请求。