UIWebView: как отловить событие загрузки страниц на ajax-сайтах?

Добрый день!
Подскажите пожалуйста как отловить событие загрузки страниц на ajax-сайтах, когда методы делегата:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

- (void)webViewDidFinishLoad:(UIWebView *)webView

не вызываются. Проверял на m.vk.com.
Мне это нужно, чтобы блокировать и разблокировать кнопки назад/вперед при переходе по страницам.

Гугл подсказал копать в сторону NSURLProtocol, но пока с трудом получается определить переход по всем ссылкам m.vk.com
  • Вопрос задан
  • 3574 просмотра
Пригласить эксперта
Ответы на вопрос 2
@max_sokolov
Если кнопки всегда активны, проблемы с навигацией нет? Методы goBack goForward отрабатывают?

В любом случае NSURLProtocol может помочь. Вот пример без излишеств. По событию didReceiveResponse можно проверять canGoBack и canGoForward

Немного погуглил по теме, у ребят на stackoverflow.com еще проблемы с html5 cache на iOS 7.
Ответ написан
alexv1981
@alexv1981 Автор вопроса
Хм... а при загрузке в браузер этой странички с использованием моего протокола, вообще тормоза и зависания немалые. Вроде делал все как тут:

@implementation WebBrowserURLProtocol
{
    NSURLConnection *_connection;
}

#pragma mark - NSURLProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    if ([NSURLProtocol propertyForKey:@"urlConnectionSent" inRequest:request] != nil)
        return NO;
    
    return YES;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (void)startLoading
{
    NSMutableURLRequest *newRequest = [self.request mutableCopy];
    
    [NSURLProtocol setProperty:@YES forKey:@"urlConnectionSent" inRequest:newRequest];
    
    _connection = [NSURLConnection connectionWithRequest:newRequest delegate:self];
}

- (void)stopLoading
{
    [_connection cancel];
}

#pragma mark - NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.client URLProtocol:self didLoadData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self.client URLProtocol:self didFailWithError:error];
    _connection = nil;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.client URLProtocolDidFinishLoading:self];
    _connection = nil;
    
    [WebBrowserURLProtocol postNotification];
}

#pragma mark - Notifications

+(void)postNotification
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"kURLProtocolDidFinishLoading" object:nil];
    });
}

@end


В итоге я переписал класс, используя в нем только один метод
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
и тормоза пропали. Для задачи обновления кнопок назад/вперед это вполне сносно:

@implementation WebBrowserURLProtocol

+(void)postNotification
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"kURLProtocolDidFinishLoading" object:nil];
    });
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    [WebBrowserURLProtocol postNotification];
    
    return NO;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (void)startLoading
{
}

- (void)stopLoading
{
}

@end


от чего такие неурядицы с этим классом....?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы