UIWebKit Недостатки - PullRequest
       7

UIWebKit Недостатки

0 голосов
/ 08 марта 2012

Как и многие другие люди до меня, у меня есть веб-контент, который я хочу отобразить в своем приложении.Мой сайт - это сайт на базе ASP.NET, разработанный в Microsoft Visual Web Developer, и он использует Ajax Toolkit среди других отличных дополнений.Я могу открыть сайт в мобильном браузере Safari на моем iPhone, и я даже собрал несколько страниц, удобных для мобильных устройств.

Я (или, точнее, мой босс) хочу приложение для 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 голосов
/ 14 марта 2012

Ну, вот как я это решил.UIWebView никогда не вызывает ни один из методов NSURLConnection, и у него нет встроенных методов безопасности, поэтому, когда веб-представление собирается загрузить страницу, я сначала отправляю NSURLConnection по тому же адресу, который затем может обработатьаутентификация через такие методы, как didReceiveAuthenticationChallenge.Переменная «_sessionChecked» - это простая BOOL, которая отслеживает, была ли отправлена ​​аутентификационная NSURLConnection для этой страницы.После этого я могу просто загрузить страницу в веб-представление в обычном режиме.

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

Метод didReceiveResponse вызывается, когда NSURLConnection получает ответ от сервера.Этот ответ содержит две важные вещи: было ли соединение успешно аутентифицировано с помощью учетных данных, предоставленных NSURLRequest, и какой URL-адрес должен быть направлен, если это так.После успешной аутентификации я отправляю новый URL в веб-представление для загрузки.

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

Большое спасибо Ардалу Ахмету за это руководство .

...