WebKit/URL Loading System/NSURLCache problem

  • In the course of determining how I can exploit WebKit/WebFoundation,
    I've been fiddling with the NSURLCache object.  The cache itself works
    for items added to the cache by the WebView et al (of course), but I
    don't seem to have the full ability to insert my own items in the cache.

    It works up until the last step, where the WebView ignores what I've
    put in the cache and loads the web page from the live copy.  Even with
    the request's policy set to NSURLRequestReturnCacheDataDontLoad, the
    WebView load still ignores the cache and I get
    didFailLoadingWithError:"resource unavailable".  Why is it that my own
    cachedResponseForRequest:myRequest check works but asking the WebView
    to load using the very same myRequest fails?  It's as if WebViews
    ignore the cache policy of the initial request, and always use
    NSURLRequestUseProtocolCachePolicy internally.  I realize that I could
    tell the mainFrame to loadData:MIMEType:encodingName:baseURL: or
    loadHTMLString:baseURL:, but all of the images on the page will load
    using NSURLRequestUseProtocolCachePolicy.

    ----

    // Create a NSURLRequest:
        NSURLRequest *myRequest = [[NSURLRequest alloc]
      initWithURL:[NSURL URLWithString:@"http://www.apple.com"]
            cachePolicy:NSURLRequestReturnCacheDataElseLoad
            timeoutInterval:60.0];

    // Create your own NSCachedURLResponse and add it to the cache:
    NSData *myData = ... // the HTML you wish to put in WebKit's cache as
    'www.apple.com'
        NSURLResponse *responseToCache = [[NSURLResponse alloc]
      initWithURL:[NSURL URLWithString:@"http://www.apple.com"]
            MIMEType:@"text/html"
      expectedContentLength:[myData length]
      textEncodingName:nil];
        NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc]
      initWithResponse:responseToCache
      data:myData];
        [[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse
    forRequest:myRequest];

    // Check if it's really there; I'm using myRequest again, but it can
    just as easily be
    // another NSURLRequest with the same URL and cache-friendly policy:
    NSLog(@"cache=%@", [[NSURLCache sharedURLCache]
    cachedResponseForRequest:myRequest]);

    // Have your WebView load the web page using the initial request.
    [[myWebView mainFrame] loadRequest:myRequest];

    --
    Leon McNeill (Beastie)    <beastie...>
    http://www.lairware.com/
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • Data stored in the NSURLCache is stored by it's canonical URL.  If the
    example below is an indication, you've got a situation where the URL
    you're inserting is not the canonical version (no trailing slash)...
    the URL loading system looks for the canonical version, so it isn't
    finding it.

    the NSURLProtocol method canonicalRequestForRequest: will make a
    request canonical.

    However, there is the problem... you can't ask for the concrete
    subclass of NSURLProtocol that will handle the specific URL scheme.

    I think the current implementation just standardizes the URL using the
    NSURL method that does that.  That MIGHT get what you want.

    Perhaps a better solution (which is, arguably, more trouble)... is to
    either subclass NSURLProtocol and register for HTTP requests, then
    examine them when they are asked for.. if they're to one of your
    special pages, then handle them, otherwise pass them off to the stock
    implementation.

    it largely depends on what exactly you're trying to do really..  I've
    got some other ideas if you can be more specific.

    On Monday, July 14, 2003, at 11:03 AM, Leon McNeill wrote:

    > In the course of determining how I can exploit WebKit/WebFoundation,
    > I've been fiddling with the NSURLCache object.  The cache itself works
    > for items added to the cache by the WebView et al (of course), but I
    > don't seem to have the full ability to insert my own items in the
    > cache.
    >
    > It works up until the last step, where the WebView ignores what I've
    > put in the cache and loads the web page from the live copy.  Even with
    > the request's policy set to NSURLRequestReturnCacheDataDontLoad, the
    > WebView load still ignores the cache and I get
    > didFailLoadingWithError:"resource unavailable".  Why is it that my own
    > cachedResponseForRequest:myRequest check works but asking the WebView
    > to load using the very same myRequest fails?  It's as if WebViews
    > ignore the cache policy of the initial request, and always use
    > NSURLRequestUseProtocolCachePolicy internally.  I realize that I could
    > tell the mainFrame to loadData:MIMEType:encodingName:baseURL: or
    > loadHTMLString:baseURL:, but all of the images on the page will load
    > using NSURLRequestUseProtocolCachePolicy.
    >
    > ----
    >
    > // Create a NSURLRequest:
    > NSURLRequest *myRequest = [[NSURLRequest alloc]
    > initWithURL:[NSURL URLWithString:@"http://www.apple.com"]
    > cachePolicy:NSURLRequestReturnCacheDataElseLoad
    > timeoutInterval:60.0];
    >
    > // Create your own NSCachedURLResponse and add it to the cache:
    > NSData *myData = ... // the HTML you wish to put in WebKit's cache as
    > 'www.apple.com'
    > NSURLResponse *responseToCache = [[NSURLResponse alloc]
    > initWithURL:[NSURL URLWithString:@"http://www.apple.com"]
    > MIMEType:@"text/html"
    > expectedContentLength:[myData length]
    > textEncodingName:nil];
    > NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc]
    > initWithResponse:responseToCache
    > data:myData];
    > [[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse
    > forRequest:myRequest];
    >
    > // Check if it's really there; I'm using myRequest again, but it can
    > just as easily be
    > // another NSURLRequest with the same URL and cache-friendly policy:
    > NSLog(@"cache=%@", [[NSURLCache sharedURLCache]
    > cachedResponseForRequest:myRequest]);
    >
    > // Have your WebView load the web page using the initial request.
    > [[myWebView mainFrame] loadRequest:myRequest];
    >
    > --
    > Leon McNeill (Beastie)    <beastie...>
    > http://www.lairware.com/
    > _______________________________________________
    > cocoa-dev mailing list | <cocoa-dev...>
    > Help/Unsubscribe/Archives:
    > http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    > Do not post admin requests to the list. They will be ignored.
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.