From d94b8bbcec6466634c05d69ae07f5ebbae19e8cf Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 19 Feb 2014 23:09:48 -0800 Subject: [PATCH] make use of new tile-specific fetches to allow cancellation --- ios/MBXViewController.mm | 61 +++++++++++++++++++++++++++++++++++----- src/map/tile.cpp | 2 +- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/ios/MBXViewController.mm b/ios/MBXViewController.mm index 06f60b314..f79a853b0 100644 --- a/ios/MBXViewController.mm +++ b/ios/MBXViewController.mm @@ -16,6 +16,7 @@ #include #include +#include NSString *const MBXNeedsRenderNotification = @"MBXNeedsRenderNotification"; NSString *const MBXUpdateActivityNotification = @"MBXUpdateActivityNotification"; @@ -23,7 +24,6 @@ NSString *const MBXUpdateActivityNotification = @"MBXUpdateActivityNotification" @interface MBXViewController () @property (nonatomic) EAGLContext *context; -@property (nonatomic) NSUInteger activityCount; @property (nonatomic) CGPoint center; @property (nonatomic) CGFloat scale; @property (nonatomic) CGFloat angle; @@ -153,11 +153,14 @@ class MBXMapView - (void)updateNetworkActivity:(NSNotification *)notification { - NSInteger input = [[notification userInfo][@"count"] integerValue]; + [[NSURLSession sharedSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) + { + for (NSURLSessionDownloadTask *task in downloadTasks) + if (task.taskDescription) + return [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; - self.activityCount += input; - - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(self.activityCount > 0)]; + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; + }]; } - (void)updateRender @@ -391,7 +394,48 @@ namespace llmr { NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@(url.c_str())] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { - [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil userInfo:[NSDictionary dictionaryWithObject:@(-1) forKey:@"count"]]; + Response res; + + if ( ! error) + { + res.code = [(NSHTTPURLResponse *)response statusCode]; + res.body = { (const char *)[data bytes], [data length] }; + } + + background_function(res); + + dispatch_async(dispatch_get_main_queue(), ^(void) + { + foreground_callback(); + }); + }]; + + [task resume]; + } + + void request_http_tile(std::string url, tile_ptr tile_object, std::function background_function, std::function foreground_callback) + { + NSString *latestZoom = [@(tile_object->id.z) stringValue]; + + [[NSURLSession sharedSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) + { + for (NSURLSessionDownloadTask *task in downloadTasks) + { + if (task.taskDescription && ! [task.taskDescription isEqualToString:latestZoom]) + { + [task cancel]; + + [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil]; + } + } + }]; + + NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@(url.c_str())] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) + { + [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil]; + + if (error && [[error domain] isEqualToString:NSURLErrorDomain] && [error code] == NSURLErrorCancelled) + return; Response res; @@ -409,9 +453,12 @@ namespace llmr [[NSNotificationCenter defaultCenter] postNotificationName:MBXNeedsRenderNotification object:nil]; }); + }]; - [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil userInfo:[NSDictionary dictionaryWithObject:@1 forKey:@"count"]]; + task.taskDescription = [@(tile_object->id.z) stringValue]; + + [[NSNotificationCenter defaultCenter] postNotificationName:MBXUpdateActivityNotification object:nil]; [task resume]; } diff --git a/src/map/tile.cpp b/src/map/tile.cpp index 902c2c03b..9e9dc5aac 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -72,7 +72,7 @@ void Tile::request() { // Note: Somehow this feels slower than the change to request_http() std::shared_ptr tile = shared_from_this(); - platform::request_http(url, [=](platform::Response& res) { + platform::request_http_tile(url, tile, [=](platform::Response& res) { if (res.code == 200) { tile->data.swap(res.body); tile->parse();