Перехват веб-запросов от плагина WebView Flash - PullRequest
2 голосов
/ 22 марта 2010

У меня есть настольное браузерное приложение, которое использует WebView для размещения плагина Flash. Плагин Flash регулярно запрашивает новые данные на внешнем веб-сайте, которые затем рисует в виде причудливой графики.

Я бы хотел перехватить эти веб-запросы и получить данные (чтобы я мог отображать их через Growl, вместо того, чтобы держать окно рабочего стола). Но, что лучше всего сказать, запросы, сделанные Flash, не принимаются обычными делегатами WebView.

Есть ли другое место, где я могу установить крючок? Я попытался установить пользовательский NSURLCache через [NSURLCache setSharedURLCache], но это так и не было вызвано. Я также попробовал метод swizzling несколько других классов (например, NSCachedURLResponse), но не смог найти выход. Есть идеи? Большое спасибо!

1 Ответ

3 голосов
/ 17 августа 2010

Удивлен, никто не ответил на это, на самом деле это довольно легко.Создайте подкласс NSURLProtocol, а затем вызовите registerClass, чтобы начать перехват.

[NSURLProtocol registerClass:[MyCustomURLProtocol class]];

Вот важные биты подкласса:

#define REQUEST_HEADER_TAG  @"x-mycustomurl-intercept"

+ (BOOL)canInitWithRequest:(NSURLRequest*)theRequest
{
    // Check for the custom header on the request to break the 
    // infinite loop created by the [startLoading] below.
    if ([theRequest valueForHTTPHeaderField:REQUEST_HEADER_TAG]) {
        return NO;
    }

    if ([theRequest.URL.scheme caseInsensitiveCompare:@"http"] == NSOrderedSame) {
        return YES;
    }
    return NO;
}

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

- (id)initWithRequest:(NSURLRequest*)theRequest
       cachedResponse:(NSCachedURLResponse*)cachedResponse
               client:(id<NSURLProtocolClient>)client
{
    // Add a custom header on the request to break the 
    // infinite loop created by the [startLoading] below.
    NSMutableURLRequest* newRequest = [theRequest mutableCopy];
    [newRequest setValue:@"" forHTTPHeaderField:REQUEST_HEADER_TAG];

    // Now continue the process with this "tagged" request
    self = [super initWithRequest:theRequest 
                   cachedResponse:cachedResponse 
                           client:client];
    if (self) {
       // capture the data received 
       [self setRequest:newRequest];
       receivedData = [[NSMutableData data] retain];
    }

    [newRequest release];
    return self;
}

- (void)dealloc
{
    [connection release];
    [request release];
    [receivedData release];
    [super dealloc];
}


- (void)startLoading
{
    // Load the data off the web as usual, but set myself up as the delegate 
    // so I can intercept the response data as it comes in.
    [self setConnection:[NSURLConnection connectionWithRequest:request delegate:self]];
}


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

#pragma mark NSURLConnection delegate implementation

- (void)connection:(NSURLConnection*)conn 
                   didReceiveResponse:(NSURLResponse*)response 
{
    [[self client] URLProtocol:self 
            didReceiveResponse:response 
            cacheStoragePolicy:[request cachePolicy]];
    [receivedData setLength:0];
}


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


- (void)connectionDidFinishLoading:(NSURLConnection*)conn
{
    [[self client] URLProtocolDidFinishLoading:self];
    [self setConnection:nil];
    if (requestTag != 0) {
        if (requestDelegate && 
            [requestDelegate respondsToSelector:
               @selector(finishedLoadingData:forURL:taggedWith:)]) {
            [requestDelegate finishedLoadingData:receivedData 
                                          forURL:[request URL] 
                                      taggedWith:requestTag];
        }
    }
}


- (void)connection:(NSURLConnection*)conn didFailWithError:(NSError*)error 
{
    [[self client] URLProtocol:self didFailWithError:error];
    [self setConnection:nil];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...