Ios 缓存磁贴的MKTileOverlay子类
您好,我正在使用Ios 缓存磁贴的MKTileOverlay子类,ios,iphone,mkmapview,subclass,mktileoverlay,Ios,Iphone,Mkmapview,Subclass,Mktileoverlay,您好,我正在使用MKTileOverlay在我的iOS7应用程序中演示OpenStreetMap互动程序。现在我想实现缓存这些磁贴的功能。我在NSHipster()上看到一篇帖子,并相应地做了 这是我的MKTileOverlay子类: #import "DETileOverlay.h" @implementation DETileOverlay - (void)loadTileAtPath:(MKTileOverlayPath)path result:(voi
MKTileOverlay
在我的iOS7应用程序中演示OpenStreetMap互动程序。现在我想实现缓存这些磁贴的功能。我在NSHipster()上看到一篇帖子,并相应地做了
这是我的MKTileOverlay子类:
#import "DETileOverlay.h"
@implementation DETileOverlay
- (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:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
result(data, connectionError);
}];
}
}
@end
然后我就这样使用它:
#import "DETileOverlay.h"
@interface DEMapViewController : UIViewController <MKMapViewDelegate> {
}
@property (nonatomic, retain) DETileOverlay *overlay;
-(void)viewDidLoad {
[super viewDidLoad];
self.overlay = [[DETileOverlay alloc] initWithURLTemplate:@"http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"];
self.overlay.canReplaceMapContent = YES;
self.overlay.mapView = map;
[map addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}
// iOS 7
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)ovl
{
MKTileOverlayRenderer *renderer = [[MKTileOverlayRenderer alloc]initWithOverlay:ovl];
return renderer;
}
- (void) mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 300, 300);
[map setRegion:region animated:YES];
}
....
} else {
NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
[NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// Should inspect the response to see if the request completed successfully!!
[self.cache setObject:data forKey:[self URLForTilePath:path]];
result(data, connectionError);
}];
}
#导入“DETileOverlay.h”
@接口DEMapViewController:UIViewController{
}
@属性(非原子,保留)DETileOverlay*overlay;
-(无效)viewDidLoad{
[超级视图下载];
self.overlay=[[DETileOverlay alloc]initWithURLTemplate:@”http://tile.stamen.com/watercolor/{z} /{x}/{y}.jpg“];
self.overlay.canReplaceMapContent=是;
self.overlay.mapView=map;
[地图添加覆盖:self.overlay级别:mkoverlayleveloverlabels];
}
//iOS 7
-(MKOverlayRenderer*)地图视图:(MKMapView*)地图视图渲染器ForOverlay:(id)ovl
{
MKTileOverlayRenderer*renderer=[[MKTileOverlayRenderer alloc]initWithOverlay:ovl];
返回渲染器;
}
-(void)mapView:(MKMapView*)mapView
didUpdateUserLocation:(MKUserLocation*)userLocation
{
mkcoordinaereregion=mkcoordinaereregionmakewithdistance(userLocation.location.coordination,300300);
[地图设置区域:区域动画:是];
}
当我启动我的应用程序时,没有加载磁贴。如果我不在我的子类中重写loadTileAtPath,一切都会正常工作。我做错了什么
非常感谢。根据您所说的已解决问题的注释,但根据您的代码,您从未将磁贴添加到缓存中。如果没有这一点,我认为你不会得到任何缓存,并且无论如何都会请求分片。因此,在completionHandler中,应将生成的磁贴添加到缓存中,如下所示:
#import "DETileOverlay.h"
@interface DEMapViewController : UIViewController <MKMapViewDelegate> {
}
@property (nonatomic, retain) DETileOverlay *overlay;
-(void)viewDidLoad {
[super viewDidLoad];
self.overlay = [[DETileOverlay alloc] initWithURLTemplate:@"http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg"];
self.overlay.canReplaceMapContent = YES;
self.overlay.mapView = map;
[map addOverlay:self.overlay level:MKOverlayLevelAboveLabels];
}
// iOS 7
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)ovl
{
MKTileOverlayRenderer *renderer = [[MKTileOverlayRenderer alloc]initWithOverlay:ovl];
return renderer;
}
- (void) mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation
{
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.location.coordinate, 300, 300);
[map setRegion:region animated:YES];
}
....
} else {
NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
[NSURLConnection sendAsynchronousRequest:request queue:self.operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// Should inspect the response to see if the request completed successfully!!
[self.cache setObject:data forKey:[self URLForTilePath:path]];
result(data, connectionError);
}];
}
我在代码中没有看到它,但请确保初始化缓存和操作队列。完全使用代码是行不通的。初始化MKTileOverlay时,设置其缓存和操作队列。然后一切正常。您是否在loadTileAtPath:result:
中设置了断点,并检查是否一切正常?数据抓取有效吗?我确实这样做了,看起来他总是进入“else”块并尝试通过NSURLConnection加载磁贴。所以问题是为什么他没有正确加载磁贴,以及为什么他没有缓存磁贴…后续问题:1。下载数据成功吗?2.下载的数据缓存在哪里?我刚刚从请求中记录了nsurl,所以这完全没问题。我只是不明白为什么没有加载瓷砖,因为url是完全正确的。磁贴通过“[self.cache setObject:data forKey:[self-URLForTilePath:path]”保存到缓存中我忘了在我的第一个问题中包括它。对不起,数据不是零,而connectionError是零。我无法解释为什么瓷砖加载不起作用。。。