1

I am trying to add a NSCache to my subclasse MKTileOverlay class:

@interface WMSTileOverlay ()

@property NSCache *cache;

@end

@implementation WMSTileOverlay

-(instancetype)initWithURLTemplate:(NSString *)URLTemplate {
    self = [super initWithURLTemplate:URLTemplate];

    if (self) {
        DLog(@"setting cache");
        self.cache = [[NSCache alloc] init];
        DLog(@"original self.cache: %@", self.cache);

    }

    return self;
}
-(void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result {
if (!result) {
    return;
}

NSData *cachedData = [self.cache objectForKey:[self URLForTilePath:path]];
if (cachedData) {
    DLog(@"Cached tile found!!!!!!!");
    result(cachedData, nil);
} else {

    NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (connectionError) {
            result (nil, connectionError);
        }
        else {
            DLog(@"adding data to cache for tile %@", [self URLForTilePath:path]);
            DLog(@"cache: %@", self.cache);
            [self.cache setObject:data forKey:[self URLForTilePath:path]];

            if ([self.cache objectForKey:[self URLForTilePath:path]]) {
                DLog(@"found the data for url path");
            }
            result (data, nil);
        }
    }];
}

}

But I never see a tile be fetched from the cache (I never see the log message "Cache Tile Found!!!!!!").

What might I be doing wrong?

EDIT: I added in log info

I added in a bunch of logging. I check to see if the cache created and that it is the same cache that I reference to find the tile. I also check to see if the data was added to the cache and it is found right after adding it:

DEBUG | -[WMSTileOverlay initWithMapContext:andLayer:] | original self.cache: <NSCache: 0x1bf59e10>
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | adding data to cache for tile service=wms&version=1.1.1&request=GetMap&SRS=EPSG:4326&layers=displayimg&mode=tiled&tile=30295+46150+17&format=image/png&transparent=true
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | cache: <NSCache: 0x1bf59e10>
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | found the data for url path
Padin215
  • 7,444
  • 13
  • 65
  • 103
  • Are you sure `connectionError` is `nil`? Perhaps `data` is `nil`. Are you calling `loadTileAtPath` too frequently and not letting `sendAsynchronousRequest` respond before the next request for the same asset comes through? – Ian MacDonald Jan 16 '15 at 21:27
  • The data is not nil, I see the tiles load on the map. – Padin215 Jan 16 '15 at 21:31
  • Are you sure that the initialiser is called? Is it possible that the cache is never created, thus no hits can ever occur? You could try making sure that the cache is properly changed by adding a log line around the setObject:... call – Henri Normak Jan 16 '15 at 21:41
  • Yes, I am positive the initializer is being called. – Padin215 Jan 16 '15 at 21:46
  • I also added a IF statement to see if the data was actually added to the cache and it is. I find it right after I add it. I'm wondering if `MKTileOverlay` has its own caching system. When I zoom out and back in, it doesn't always re-fetch the tile but due to the image of the tile, I can't tell 100% if its the correct zoom level tile or a tile from a lower zoom level (lower the zoom number, the further zoomed out you are) zoomed in on. – Padin215 Jan 16 '15 at 21:58

1 Answers1

0

It's because once a tile for a specific path is loaded, MapKit won't call loadTileAtPath again for that path within the same session, I think MapKit already has cached loaded tiles internally in some way.

always_beta
  • 229
  • 4
  • 10
  • I think you are correct. I have noticed if the app sits idle for a long time, if I move the map again it will load the tile from my cache. I assume after X time, the MapKit clears its cache and then finds the tile in my cache. – Padin215 Feb 22 '16 at 17:58