Mapa de caching sin connection

Tengo una gran necesidad de hacer un map sin connection para mi aplicación, ya que está hecho principalmente para Tailandia, donde la connection a internet es a menudo difícil de conseguir. Estoy usando OpenStreetMap ahora mismo para mi MKTileOverlay pero tengo problemas para implementarlo para uso sin connection. He encontrado un tutorial que dice a la subclass MKTileOverlay . Entonces, en mi ViewController donde está el map, tengo:

  - (void)viewWillAppear:(BOOL)animated { CLLocationCoordinate2D coord = {.latitude = 15.8700320, .longitude = 100.9925410}; MKCoordinateSpan span = {.latitudeDelta = 3, .longitudeDelta = 3}; MKCoordinateRegion region = {coord, span}; [mapView setRegion:region]; } - (void)viewDidLoad { [super viewDidLoad]; self.title = @"Map"; NSString *template = @"http://tile.openstreetmap.org/{z}/{x}/{y}.png"; self.overlay = [[XXTileOverlay alloc] initWithURLTemplate:template]; self.overlay.canReplaceMapContent = YES; [mapView addOverlay:self.overlay level:MKOverlayLevelAboveLabels]; } - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id)overlay { return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay]; } 

En mi subclass de MKTileOverlay , tengo:

 - (NSURL *)URLForTilePath:(MKTileOverlayPath)path { return [NSURL URLWithString:[NSString stringWithFormat:@"http://tile.openstreetmap.org/{%ld}/{%ld}/{%ld}.png", (long)path.z, (long)path.x, (long)path.y]]; } - (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *data, NSError *error))result { if (!result) { return; } NSData *cachedData = [self.cache objectForKey:[self URLForTilePath:path]]; if (cachedData) { result(cachedData, nil); } else { NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]]; [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { result(data, connectionError); }]; } } 

El problema es que NADA se carga, a less que comente el código en la subclass. ¿Dónde estoy arruinando?

En nuestra compañía, elegimos utilizar MapBox para nuestra asignación fuera de línea.

Allí, puede diseñar y diseñar sus propios maps con MapBox Studio, luego exportar sus maps (en un range elegido de niveles de zoom) a un file externo. La nuestra tiene un tamaño de aproximadamente 40 Mb.

Desde allí, puede usar MapBox iOS SDK para agregarlo fácilmente a su aplicación.

(Descargo de responsabilidad: no, no trabajo para ellos! Específicamente los elegimos por la capacidad de definir nuestros propios colors y styles de tierra / mar, y la capacidad de tener los files de map incluidos en nuestro proyecto Xcode y usables fuera de línea).

Aprecio que tu pregunta exacta fue cómo hacer que los maps de OpenStreetMap estén fuera de línea, pero espero que esto te sea útil.

Parece que no estás poblando el caching. ¿Siempre va a estar vacío?

 if (cachedData) { result(cachedData, nil); } else { NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]]; [NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { // Instantiate a new cache if we don't already have one. if (!self.cache) self.cache = [NSCache new]; // Add the data into the cache so it's there for next time. if (data) { [self.cache setObject:data forKey:[self URLForTilePath:path]]; } result(data, connectionError); }]; } 

Creo que resolverá tu problema aquí. Recuerde que NSCache no persiste en el disco (solo en la memory), de modo que si bien sobrevive a la aplicación en segundo plano, necesitará algo más complejo en el largo ploop si desea una capacidad total fuera de línea (probablemente datos básicos).