Проблема управления кешем iOS / MapKit с библиотекой MKTileOverlay и PINCache
Я использую MapKit для создания спутниковой и радиолокационной анимации, добавив MKTileOverlay поверх mapView.
С помощью UISlider и PlayButton я смог создать анимацию, такую как GIF, играя с альфа-каналом MKOverlayRenderer (устанавливая их в 0 или 0,75 в зависимости от положения моего ползунка).
Анимация довольно плавная, все мои спутниковые и радарные плитки правильно загружены поверх mapView.
Я столкнулся с одной проблемой с управлением кэшем.
Я понял, что MapKit не использует кеш для моего tileOverlay, поэтому я использовал библиотеку PINCache, чтобы сохранить свои тайлы, чтобы он не запрашивал и не загружал изображения каждый раз, когда я играю анимацию.
Моя реализация:
Я переопределяю метод URLForTilePath
для того, чтобы построить мой URL, чтобы получить мои изображения плитки.
- (NSURL *)URLForTilePath:(MKTileOverlayPath)path{
double latMin, latMax, longMin, longMax;
path.contentScaleFactor = 1.0;
NSMutableArray *result = [[NSMutableArray alloc] init];
result = getBBoxForCoordinates((int)path.x, (int)path.y, (int)path.z);
longMin = [[result objectAtIndex:0] doubleValue];
latMin = [[result objectAtIndex:1] doubleValue];
longMax = [[result objectAtIndex:2] doubleValue];
latMax = [[result objectAtIndex:3] doubleValue];
NSString *finalURL = self.url;
finalURL = [finalURL stringByReplacingOccurrencesOfString:@"DATE"
withString:_date];
NSString *bbox = [NSString stringWithFormat:@"bbox=%f,%f,%f,%f", longMin, latMin, longMax, latMax];
finalURL = [finalURL stringByReplacingOccurrencesOfString:@"BBOX"
withString:bbox];
return [NSURL URLWithString:finalURL];
}
И ключевой метод, который будет вызывать URLForTilePath
моя реализация loadTileAtPath
:
- (void)loadTileAtPath:(MKTileOverlayPath)path
result:(void (^)(NSData *data, NSError *error))result
{
if (!result)
{
return;
}
NSString *str = self.isRadar == true ? [NSString stringWithFormat:@"Radar%@", self.date] : [NSString stringWithFormat:@"Satellite%@", self.date];
NSData *cachedData = [[PINCache sharedCache] objectForKey:str];
if (cachedData)
{
result(cachedData, nil);
}
else
{
NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *str = self.isRadar == true ? [NSString stringWithFormat:@"Radar%@", self.date] : [NSString stringWithFormat:@"Satellite%@", self.date];
[[PINCache sharedCache] setObject:data forKey:str block:nil];
result(data, connectionError);
}];
}
}
В основном то, что я пытаюсь достичь, это:
- Проверьте, если я кэшировал данные, если это так, то получите объект.
- Если нет, я делаю запрос на скачивание плитки с URL-адресом
URLForTilePath
, - Затем я устанавливаю объект в кэш.
- Строка
str
мой ключ для управления кешем - У меня есть 2 важных значения для сортировки и дифференцирования плиток: тип (радар или спутник, другое изображение, другой URL) и дата.
Я вижу, что управление кешем работает, оверлеи работают быстрее, но главная проблема, с которой я сталкиваюсь, заключается в том, что они не загружают и не создают плитки по соответствующей координате.
Мой mapView - это как загадка неправильно построенного мира.
С моим фрагментом кода, вы видите что-то не то, что я сделал?
1 ответ
Я не мог найти причину этой проблемы управления памятью / кешем с mapKit.
Я решил попробовать с GoogleMap, это заняло у меня менее 2 часов, чтобы реализовать его, и результаты потрясающие.
Я хотел уважать сообщество Apple, используя решение Apple, но Google Map предоставил мне гораздо больше возможностей.