From 5ac1c787f289899b559f4dc1ba872fbe44560b95 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Date: Thu, 19 Sep 2019 10:28:33 -0700 Subject: [ios] Use NetworkStatus::Status for stopping network requests. --- platform/darwin/filesource-files.json | 2 +- platform/darwin/src/MGLNetworkConfiguration.m | 162 ---------------------- platform/darwin/src/MGLNetworkConfiguration.mm | 180 +++++++++++++++++++++++++ platform/darwin/src/http_file_source.mm | 4 - platform/ios/ios.xcodeproj/project.pbxproj | 12 +- 5 files changed, 187 insertions(+), 173 deletions(-) delete mode 100644 platform/darwin/src/MGLNetworkConfiguration.m create mode 100644 platform/darwin/src/MGLNetworkConfiguration.mm diff --git a/platform/darwin/filesource-files.json b/platform/darwin/filesource-files.json index 62043a0dcd..6600f9691d 100644 --- a/platform/darwin/filesource-files.json +++ b/platform/darwin/filesource-files.json @@ -2,7 +2,7 @@ "//": "This file can be edited manually and is the canonical source.", "sources": [ "platform/darwin/src/MGLLoggingConfiguration.mm", - "platform/darwin/src/MGLNetworkConfiguration.m", + "platform/darwin/src/MGLNetworkConfiguration.mm", "platform/darwin/src/http_file_source.mm", "platform/default/src/mbgl/storage/file_source.cpp", "platform/default/src/mbgl/storage/sqlite3.cpp" diff --git a/platform/darwin/src/MGLNetworkConfiguration.m b/platform/darwin/src/MGLNetworkConfiguration.m deleted file mode 100644 index 0e5046e7a3..0000000000 --- a/platform/darwin/src/MGLNetworkConfiguration.m +++ /dev/null @@ -1,162 +0,0 @@ -#import "MGLNetworkConfiguration_Private.h" - -#include - -static NSString * const MGLStartTime = @"start_time"; -static NSString * const MGLResourceType = @"resource_type"; -NSString * const kMGLDownloadPerformanceEvent = @"mobile.performance_trace"; - -@interface MGLNetworkConfiguration () - -@property (strong) NSURLSessionConfiguration *sessionConfig; -@property (nonatomic, strong) NSMutableDictionary *events; -@property (nonatomic, weak) id metricsDelegate; -@property (nonatomic) dispatch_queue_t eventsQueue; - -@end - -@implementation MGLNetworkConfiguration - -- (instancetype)init { - if (self = [super init]) { - self.sessionConfiguration = nil; - _events = [NSMutableDictionary dictionary]; - _eventsQueue = dispatch_queue_create("com.mapbox.network-configuration", DISPATCH_QUEUE_CONCURRENT); - } - - return self; -} - -+ (instancetype)sharedManager { - static dispatch_once_t onceToken; - static MGLNetworkConfiguration *_sharedManager; - dispatch_once(&onceToken, ^{ - _sharedManager = [[self alloc] init]; - }); - - return _sharedManager; -} - -- (void)setSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { - @synchronized (self) { - if (sessionConfiguration == nil) { - _sessionConfig = [self defaultSessionConfiguration]; - } else { - _sessionConfig = sessionConfiguration; - } - } -} - -- (NSURLSessionConfiguration *)sessionConfiguration { - NSURLSessionConfiguration *sessionConfig = nil; - @synchronized (self) { - sessionConfig = _sessionConfig; - } - return sessionConfig; -} - -- (NSURLSessionConfiguration *)defaultSessionConfiguration { - NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; - - sessionConfiguration.timeoutIntervalForResource = 30; - sessionConfiguration.HTTPMaximumConnectionsPerHost = 8; - sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; - sessionConfiguration.URLCache = nil; - - return sessionConfiguration; -} - -- (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType { - if (urlString && ![self eventDictionaryForKey:urlString]) { - NSDate *startDate = [NSDate date]; - [self setEventDictionary:@{ MGLStartTime: startDate, MGLResourceType: resourceType } forKey:urlString]; - } -} - -- (void)stopDownloadEventForResponse:(NSURLResponse *)response { - [self sendEventForURLResponse:response withAction:nil]; -} - -- (void)cancelDownloadEventForResponse:(NSURLResponse *)response { - [self sendEventForURLResponse:response withAction:@"cancel"]; -} - -- (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString *)action -{ - if ([response isKindOfClass:[NSURLResponse class]]) { - NSString *urlString = response.URL.relativePath; - if (urlString && [self eventDictionaryForKey:urlString]) { - NSDictionary *eventAttributes = [self eventAttributesForURL:response withAction:action]; - [self removeEventDictionaryForKey:urlString]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self.metricsDelegate networkConfiguration:self didGenerateMetricEvent:eventAttributes]; - }); - } - } - -} - -- (NSDictionary *)eventAttributesForURL:(NSURLResponse *)response withAction:(NSString *)action -{ - NSString *urlString = response.URL.relativePath; - NSDictionary *parameters = [self eventDictionaryForKey:urlString]; - NSDate *startDate = [parameters objectForKey:MGLStartTime]; - NSDate *endDate = [NSDate date]; - NSTimeInterval elapsedTime = [endDate timeIntervalSinceDate:startDate]; - NSDateFormatter* iso8601Formatter = [[NSDateFormatter alloc] init]; - iso8601Formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; - NSString *createdDate = [iso8601Formatter stringFromDate:[NSDate date]]; - - NSMutableArray *attributes = [NSMutableArray array]; - [attributes addObject:@{ @"name" : @"requestUrl" , @"value" : urlString }]; - [attributes addObject:@{ @"name" : MGLResourceType , @"value" : [parameters objectForKey:MGLResourceType] }]; - - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode]; - [attributes addObject:@{ @"name" : @"responseCode", @"value" : @(responseCode)}]; - } - - BOOL isWIFIOn = [[MGLReachability reachabilityWithHostName:response.URL.host] isReachableViaWiFi]; - [attributes addObject:@{ @"name" : @"wifiOn", @"value" : @(isWIFIOn)}]; - - if (action) { - [attributes addObject:@{ @"name" : @"action" , @"value" : action }]; - } - - double elapsedTimeInMS = elapsedTime * 1000.0; - - return @{ - @"event" : kMGLDownloadPerformanceEvent, - @"created" : createdDate, - @"sessionId" : [NSUUID UUID].UUIDString, - @"counters" : @[ @{ @"name" : @"elapsedMS" , @"value" : @(elapsedTimeInMS) } ], - @"attributes" : attributes - }; -} - -#pragma mark - Events dictionary access - -- (nullable NSDictionary*)eventDictionaryForKey:(nonnull NSString*)key { - __block NSDictionary *dictionary; - - dispatch_sync(self.eventsQueue, ^{ - dictionary = [self.events objectForKey:key]; - }); - - return dictionary; -} - -- (void)setEventDictionary:(nonnull NSDictionary*)dictionary forKey:(nonnull NSString*)key { - dispatch_barrier_async(self.eventsQueue, ^{ - [self.events setObject:dictionary forKey:key]; - }); -} - -- (void)removeEventDictionaryForKey:(nonnull NSString*)key { - dispatch_barrier_async(self.eventsQueue, ^{ - [self.events removeObjectForKey:key]; - }); -} - -@end diff --git a/platform/darwin/src/MGLNetworkConfiguration.mm b/platform/darwin/src/MGLNetworkConfiguration.mm new file mode 100644 index 0000000000..fba78e4e81 --- /dev/null +++ b/platform/darwin/src/MGLNetworkConfiguration.mm @@ -0,0 +1,180 @@ +#import "MGLNetworkConfiguration_Private.h" + +#include +#include + +static NSString * const MGLStartTime = @"start_time"; +static NSString * const MGLResourceType = @"resource_type"; +NSString * const kMGLDownloadPerformanceEvent = @"mobile.performance_trace"; + +@interface MGLNetworkConfiguration () + +@property (strong) NSURLSessionConfiguration *sessionConfig; +@property (nonatomic, strong) NSMutableDictionary *events; +@property (nonatomic, weak) id metricsDelegate; +@property (nonatomic) dispatch_queue_t eventsQueue; + +@end + +@implementation MGLNetworkConfiguration + +- (instancetype)init { + if (self = [super init]) { + self.sessionConfiguration = nil; + _events = [NSMutableDictionary dictionary]; + _eventsQueue = dispatch_queue_create("com.mapbox.network-configuration", DISPATCH_QUEUE_CONCURRENT); + } + + return self; +} + ++ (instancetype)sharedManager { + static dispatch_once_t onceToken; + static MGLNetworkConfiguration *_sharedManager; + dispatch_once(&onceToken, ^{ + _sharedManager = [[self alloc] init]; + }); + + return _sharedManager; +} + +- (void)setSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { + @synchronized (self) { + if (sessionConfiguration == nil) { + _sessionConfig = [self defaultSessionConfiguration]; + } else { + _sessionConfig = sessionConfiguration; + } + } +} + +- (NSURLSessionConfiguration *)sessionConfiguration { + NSURLSessionConfiguration *sessionConfig = nil; + @synchronized (self) { + sessionConfig = _sessionConfig; + } + return sessionConfig; +} + +- (NSURLSessionConfiguration *)defaultSessionConfiguration { + NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + + sessionConfiguration.timeoutIntervalForResource = 30; + sessionConfiguration.HTTPMaximumConnectionsPerHost = 8; + sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + sessionConfiguration.URLCache = nil; + + return sessionConfiguration; +} + +- (void)setStopsRequests:(BOOL)stopsRequests { + if (stopsRequests) { + mbgl::NetworkStatus::Set(mbgl::NetworkStatus::Status::Offline); + } else { + mbgl::NetworkStatus::Set(mbgl::NetworkStatus::Status::Online); + } +} + +- (BOOL)stopsRequests { + auto status = mbgl::NetworkStatus::Get(); + if (status == mbgl::NetworkStatus::Status::Offline) { + return YES; + } else { + return NO; + } +} + +- (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType { + if (urlString && ![self eventDictionaryForKey:urlString]) { + NSDate *startDate = [NSDate date]; + [self setEventDictionary:@{ MGLStartTime: startDate, MGLResourceType: resourceType } forKey:urlString]; + } +} + +- (void)stopDownloadEventForResponse:(NSURLResponse *)response { + [self sendEventForURLResponse:response withAction:nil]; +} + +- (void)cancelDownloadEventForResponse:(NSURLResponse *)response { + [self sendEventForURLResponse:response withAction:@"cancel"]; +} + +- (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString *)action +{ + if ([response isKindOfClass:[NSURLResponse class]]) { + NSString *urlString = response.URL.relativePath; + if (urlString && [self eventDictionaryForKey:urlString]) { + NSDictionary *eventAttributes = [self eventAttributesForURL:response withAction:action]; + [self removeEventDictionaryForKey:urlString]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self.metricsDelegate networkConfiguration:self didGenerateMetricEvent:eventAttributes]; + }); + } + } + +} + +- (NSDictionary *)eventAttributesForURL:(NSURLResponse *)response withAction:(NSString *)action +{ + NSString *urlString = response.URL.relativePath; + NSDictionary *parameters = [self eventDictionaryForKey:urlString]; + NSDate *startDate = [parameters objectForKey:MGLStartTime]; + NSDate *endDate = [NSDate date]; + NSTimeInterval elapsedTime = [endDate timeIntervalSinceDate:startDate]; + NSDateFormatter* iso8601Formatter = [[NSDateFormatter alloc] init]; + iso8601Formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; + NSString *createdDate = [iso8601Formatter stringFromDate:[NSDate date]]; + + NSMutableArray *attributes = [NSMutableArray array]; + [attributes addObject:@{ @"name" : @"requestUrl" , @"value" : urlString }]; + [attributes addObject:@{ @"name" : MGLResourceType , @"value" : [parameters objectForKey:MGLResourceType] }]; + + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode]; + [attributes addObject:@{ @"name" : @"responseCode", @"value" : @(responseCode)}]; + } + + BOOL isWIFIOn = [[MGLReachability reachabilityWithHostName:response.URL.host] isReachableViaWiFi]; + [attributes addObject:@{ @"name" : @"wifiOn", @"value" : @(isWIFIOn)}]; + + if (action) { + [attributes addObject:@{ @"name" : @"action" , @"value" : action }]; + } + + double elapsedTimeInMS = elapsedTime * 1000.0; + + return @{ + @"event" : kMGLDownloadPerformanceEvent, + @"created" : createdDate, + @"sessionId" : [NSUUID UUID].UUIDString, + @"counters" : @[ @{ @"name" : @"elapsedMS" , @"value" : @(elapsedTimeInMS) } ], + @"attributes" : attributes + }; +} + +#pragma mark - Events dictionary access + +- (nullable NSDictionary*)eventDictionaryForKey:(nonnull NSString*)key { + __block NSDictionary *dictionary; + + dispatch_sync(self.eventsQueue, ^{ + dictionary = [self.events objectForKey:key]; + }); + + return dictionary; +} + +- (void)setEventDictionary:(nonnull NSDictionary*)dictionary forKey:(nonnull NSString*)key { + dispatch_barrier_async(self.eventsQueue, ^{ + [self.events setObject:dictionary forKey:key]; + }); +} + +- (void)removeEventDictionaryForKey:(nonnull NSString*)key { + dispatch_barrier_async(self.eventsQueue, ^{ + [self.events removeObjectForKey:key]; + }); +} + +@end diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm index 09562e0347..b0f69f4a7f 100644 --- a/platform/darwin/src/http_file_source.mm +++ b/platform/darwin/src/http_file_source.mm @@ -229,10 +229,6 @@ NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountTyp std::unique_ptr HTTPFileSource::request(const Resource& resource, Callback callback) { auto request = std::make_unique(callback); auto shared = request->shared; // Explicit copy so that it also gets copied into the completion handler block below. - - if ([MGLNetworkConfiguration sharedManager].stopsRequests) { - return std::move(request); - } @autoreleasepool { NSURL *url = resourceURLWithAccountType(resource, impl->accountType); diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 350a8014fd..a5a7785e7d 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -762,8 +762,8 @@ DAF2571B201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAF2571C201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAF25720201902BC00367EF5 /* MGLHillshadeStyleLayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF2571F201902BB00367EF5 /* MGLHillshadeStyleLayerTests.mm */; }; - DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; }; - DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; }; + DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.mm */; }; + DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.mm */; }; DD0902AB1DB192A800C5BDCE /* MGLNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; DD4823751D94AE6C00EB71B7 /* fill_filter_style.json in Resources */ = {isa = PBXBuildFile; fileRef = DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */; }; DD4823761D94AE6C00EB71B7 /* line_filter_style.json in Resources */ = {isa = PBXBuildFile; fileRef = DD4823731D94AE6C00EB71B7 /* line_filter_style.json */; }; @@ -1470,7 +1470,7 @@ DAFEB3762093AE6800A86A83 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Foundation.stringsdict; sourceTree = ""; }; DAFEB3772093AE7900A86A83 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; DAFEB3782093AE9200A86A83 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Localizable.stringsdict; sourceTree = ""; }; - DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfiguration.m; sourceTree = ""; }; + DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLNetworkConfiguration.mm; sourceTree = ""; }; DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNetworkConfiguration.h; sourceTree = ""; }; DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = fill_filter_style.json; sourceTree = ""; }; DD4823731D94AE6C00EB71B7 /* line_filter_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = line_filter_style.json; sourceTree = ""; }; @@ -2164,7 +2164,7 @@ 927FBCFE1F4DB05500F8BF1F /* MGLMapSnapshotter.mm */, DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */, 1F2B94BF221636D800210640 /* MGLNetworkConfiguration_Private.h */, - DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */, + DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.mm */, 3EA9337830C7738BF7F5493C /* MGLRendererConfiguration.h */, 3EA931BC4F087E166D538F21 /* MGLRendererConfiguration.mm */, 92F2C3EC1F0E3C3A00268EC0 /* MGLRendererFrontend.h */, @@ -3418,7 +3418,7 @@ 40834BF01FE05E1800C1BD0D /* MMELocationManager.m in Sources */, DA8848281CBAFA6200AB86E3 /* MGLShape.mm in Sources */, DA35A2B31CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */, - DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */, + DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.mm in Sources */, 35D13AB91D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */, 74CB5EB3219B252C00102936 /* MGLStyleLayerManager.mm in Sources */, DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */, @@ -3539,7 +3539,7 @@ 9C6E282C22A981580056B7BE /* MGLMapboxEvents.m in Sources */, DAA4E41F1CBB730400178DFB /* MGLMultiPoint.mm in Sources */, 96E6145C22CC169000109F14 /* MGLCompassButton.mm in Sources */, - DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */, + DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.mm in Sources */, 40834C041FE05E1800C1BD0D /* MMELocationManager.m in Sources */, 9C6E281F22A980AC0056B7BE /* CLLocation+MMEMobileEvents.m in Sources */, DA35A2B41CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */, -- cgit v1.2.1