Проблема управления кешем 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 предоставил мне гораздо больше возможностей.

Другие вопросы по тегам