UIWebKit不足

时间:2012-03-07 21:08:16

标签: asp.net ios uiwebview ajaxcontroltoolkit

像我之前的很多其他人一样,我有一些我希望在我的应用中显示的网页内容。我的站点是在Microsoft Visual Web Developer中开发的基于ASP.NET的站点,它使用Ajax Toolkit和其他漂亮的插件。我可以在iPhone的移动Safari浏览器中打开网站,我甚至将一些适合移动设备的页面拼凑在一起。

我(或更准确地说,我的老板)想要一个iPhone应用程序,它存储用于访问我的网站的凭据,并在打开应用程序时自动发送。这是问题所在:

我的网站未在UIWebView中加载。它也不会遇到任何委托方法(完成加载,加载失败等)。它只是启动连接请求并坐在那里。该网站在我用于测试的同一设备上的Safari中工作,所以我认为这个问题与UIWebKit有关,没有Safari内置的一些工具。

什么(具体)导致我的网站无法在UIWebKit中加载,当它在Safari中正确加载时?

我将发布我设置的方法,以便通过我的电话

来捕捉生命中的任何迹象
[myWebView loadRequest:myRequest];

当我运行我的应用程序并达到上面的loadRequest调用时,没有调用以下任何方法。

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"WillSendForAuthenticationChallenge");
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"Webview failed to load.");
    if (error.code == NSURLErrorCancelled) return; // this is Error -999, called when the user forcibly ends the connection by starting a new connection.
    UIAlertView *failure = [[UIAlertView alloc] initWithTitle:@"Failed" message:error.localizedDescription delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [failure show];
    [spinner stopAnimating];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"Loading request: %@",request.URL);
    return YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webview
{
    NSLog(@"Webview finished loading.");
    [spinner stopAnimating];
}

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    NSLog(@"Can Authenticate: %@",[protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]);
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    NSLog(@"Received an authentication challenge.");
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

1 个答案:

答案 0 :(得分:0)

嗯,这就是我解决它的方式。 UIWebView从不调用任何NSURLConnection方法,并且它没有任何内置的安全方法,因此当Web视图即将加载页面时,我首先将NSURLConnection发送到同一地址,然后可以处理通过didReceiveAuthenticationChallenge等方法进行身份验证。变量“_sessionChecked”是一个简单的BOOL,用于跟踪是否已为此页面发送了身份验证NSURLConnection。一旦有了,我可以简单地将页面正常加载到Web视图中。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"Loading request: %@",request.URL);
    if (_sessionChecked) {
        NSLog(@"Session already checked.");
        return YES;
    }

    NSLog(@"Will check session.");

    NSMutableURLRequest *newReq = request.mutableCopy;

    [newReq setValue:USRAGNT forHTTPHeaderField:@"User-Agent"];

    NSURLConnection *conn = [NSURLConnection connectionWithRequest:newReq delegate:self];
    if (conn == nil) {
        NSLog(@"Cannot create connection.");
    }
    return NO;
}

当NSURLConnection从服务器获取响应时,将调用didReceiveResponse方法。此响应包含两个重要的事项:连接是否使用NSURLRequest提供的凭据成功进行了身份验证,以及如果是,则指向哪个URL。验证成功后,我将新URL发送到要加载的Web视图。

- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"connection:didReceiveResponse");

    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
        _sessionChecked = YES;

        NSString *newUrl = @"";
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
        int status = [httpResponse statusCode];

        if (status == 401 || status == 403) {
            NSLog(@"Not authenticated. http status code: %d", status);
            newUrl = @"";
            [myWebView stopLoading];
            [spinner stopAnimating];
            UIAlertView *failed = [[UIAlertView alloc] initWithTitle:@"Authentication Failed" message:@"You do not have any credentials stored, or your stored credentials are not valid." delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [failed show];
            _sessionChecked = NO;
        }
        else {
            NSLog(@"Authenticated. http status code: %d", status);
            newUrl = [NSString stringWithFormat:@"%@", response.URL];
        }

        // cancel the connection. we got what we want from the response,
        // no need to download the response data.
        [connection cancel];

        // start loading the new request in webView
        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:newUrl]];
        [myWebView loadRequest:req];
    }
}

非常感谢Ardal Ahmet this how-to