diff --git a/platform/darwin/src/MGLNetworkConfiguration.h b/platform/darwin/src/MGLNetworkConfiguration.h index 6c56050aae..d48513a7db 100644 --- a/platform/darwin/src/MGLNetworkConfiguration.h +++ b/platform/darwin/src/MGLNetworkConfiguration.h @@ -4,6 +4,29 @@ NS_ASSUME_NONNULL_BEGIN +@class MGLNetworkConfiguration; + +@protocol MGLNetworkConfigurationDelegate +@optional + +/** + :nodoc: + Provides an `NSURLSession` object for the specified `MGLNetworkConfiguration`. + This API should be considered experimental, likely to be removed or changed in + future releases. + + This method is called from background threads, i.e. it is not called on the main + thread. + + @note Background sessions (i.e. created with + `-[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:]`) + and sessions created with a delegate that conforms to `NSURLSessionDataDelegate` + are not supported at this time. + */ +- (NSURLSession *)sessionForNetworkConfiguration:(MGLNetworkConfiguration *)configuration; +@end + + /** The `MGLNetworkConfiguration` object provides a global way to set a base `NSURLSessionConfiguration`, and other resources. @@ -11,6 +34,12 @@ NS_ASSUME_NONNULL_BEGIN MGL_EXPORT @interface MGLNetworkConfiguration : NSObject +/** + :nodoc: + Delegate for the `MGLNetworkConfiguration` class. + */ +@property (nonatomic, weak) id delegate; + /** Returns the shared instance of the `MGLNetworkConfiguration` class. */ @@ -23,12 +52,14 @@ MGL_EXPORT If this property is set to nil or if no session configuration is provided this property is set to the default session configuration. - Assign this object before instantiating any `MGLMapView` object. + Assign this object before instantiating any `MGLMapView` object, or using + `MGLOfflineStorage` - @note: `NSURLSession` objects store a copy of this configuration. Any further changes + @note `NSURLSession` objects store a copy of this configuration. Any further changes to mutable properties on this configuration object passed to a sessionā€™s initializer will not affect the behavior of that session. - + + @note Background sessions are not currently supported. */ @property (atomic, strong, null_resettable) NSURLSessionConfiguration *sessionConfiguration; diff --git a/platform/darwin/src/MGLNetworkConfiguration.m b/platform/darwin/src/MGLNetworkConfiguration.m index 391f67b636..de96d55420 100644 --- a/platform/darwin/src/MGLNetworkConfiguration.m +++ b/platform/darwin/src/MGLNetworkConfiguration.m @@ -1,14 +1,17 @@ #import "MGLNetworkConfiguration_Private.h" -#import "MGLNetworkIntegrationManager.h" +#import "MGLLoggingConfiguration_Private.h" +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR +#import "MGLAccountManager_Private.h" +#endif + #import "MGLReachability.h" static NSString * const MGLStartTime = @"start_time"; static NSString * const MGLResourceType = @"resource_type"; NSString * const kMGLDownloadPerformanceEvent = @"mobile.performance_trace"; -@interface MGLNetworkConfiguration () +@interface MGLNetworkConfiguration () -@property (strong) NSURLSessionConfiguration *sessionConfig; @property (nonatomic, strong) NSMutableDictionary *events; @property (nonatomic, weak) id metricsDelegate; @property (nonatomic) dispatch_queue_t eventsQueue; @@ -16,6 +19,9 @@ @interface MGLNetworkConfiguration () @end @implementation MGLNetworkConfiguration +{ + NSURLSessionConfiguration *_sessionConfig; +} - (instancetype)init { if (self = [super init]) { @@ -34,26 +40,51 @@ + (instancetype)sharedManager { _sharedManager = [[self alloc] init]; }); - [self setNativeNetworkManagerDelegateToDefault]; + // Notice, this is reset for each call. This is primarily for testing purposes. + // TODO: Consider only calling this for testing? + [_sharedManager resetNativeNetworkManagerDelegate]; return _sharedManager; } -+ (void)setNativeNetworkManagerDelegateToDefault { +- (void)resetNativeNetworkManagerDelegate { // Tell core about our network integration. `delegate` here is not (yet) // intended to be set to nil, except for testing. - [MGLNativeNetworkManager sharedManager].delegate = - MGLNetworkIntegrationManager.sharedManager; + [MGLNativeNetworkManager sharedManager].delegate = self; } -- (void)setSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { - @synchronized (self) { - if (sessionConfiguration == nil) { - _sessionConfig = [self defaultSessionConfiguration]; - } else { - _sessionConfig = sessionConfiguration; - } ++ (NSURLSessionConfiguration *)defaultSessionConfiguration { + NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; + + sessionConfiguration.timeoutIntervalForResource = 30; + sessionConfiguration.HTTPMaximumConnectionsPerHost = 8; + sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + sessionConfiguration.URLCache = nil; + + return sessionConfiguration; +} + +#pragma mark - MGLNativeNetworkDelegate + +- (NSURLSession *)sessionForNetworkManager:(MGLNativeNetworkManager *)networkManager { + // Note: this method is NOT called on the main thread. + NSURLSession *session; + if ([self.delegate respondsToSelector:@selector(sessionForNetworkConfiguration:)]) { + session = [self.delegate sessionForNetworkConfiguration:self]; + } + + // Check for a background session; string checking is fragile, but this is not + // a deal breaker as we're only doing this to provide more clarity to the + // developer + NSAssert(![session isKindOfClass:NSClassFromString(@"__NSURLBackgroundSession")], + @"Background NSURLSessions are not yet supported"); + + if (session.delegate) { + NSAssert(![session.delegate conformsToProtocol:@protocol(NSURLSessionDataDelegate)], + @"Session delegates conforming to NSURLSessionDataDelegate are not yet supported"); } + + return session; } - (NSURLSessionConfiguration *)sessionConfiguration { @@ -64,21 +95,27 @@ - (NSURLSessionConfiguration *)sessionConfiguration { return sessionConfig; } -- (NSURLSessionConfiguration *)defaultSessionConfiguration { - NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; - - sessionConfiguration.timeoutIntervalForResource = 30; - sessionConfiguration.HTTPMaximumConnectionsPerHost = 8; - sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; - sessionConfiguration.URLCache = nil; - - return sessionConfiguration; +- (void)setSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { + @synchronized (self) { + if (sessionConfiguration == nil) { + _sessionConfig = [MGLNetworkConfiguration defaultSessionConfiguration]; + } else { + _sessionConfig = sessionConfiguration; + } + } } +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR +- (NSString *)skuToken { + return MGLAccountManager.skuToken; +} +#endif + - (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType { - if (urlString && ![self eventDictionaryForKey:urlString]) { + if (urlString && resourceType && ![self eventDictionaryForKey:urlString]) { NSDate *startDate = [NSDate date]; - [self setEventDictionary:@{ MGLStartTime: startDate, MGLResourceType: resourceType } forKey:urlString]; + [self setEventDictionary:@{ MGLStartTime: startDate, MGLResourceType: resourceType } + forKey:urlString]; } } @@ -90,6 +127,16 @@ - (void)cancelDownloadEventForResponse:(NSURLResponse *)response { [self sendEventForURLResponse:response withAction:@"cancel"]; } +- (void)debugLog:(NSString *)format, ... { + MGLLogDebug(format); +} + +- (void)errorLog:(NSString *)format, ... { + MGLLogError(format); +} + +#pragma mark - Event management + - (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString *)action { if ([response isKindOfClass:[NSURLResponse class]]) { @@ -103,7 +150,6 @@ - (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString * }); } } - } - (NSDictionary *)eventAttributesForURL:(NSURLResponse *)response withAction:(NSString *)action diff --git a/platform/darwin/src/MGLNetworkConfiguration_Private.h b/platform/darwin/src/MGLNetworkConfiguration_Private.h index d250648f5c..43e184a63c 100644 --- a/platform/darwin/src/MGLNetworkConfiguration_Private.h +++ b/platform/darwin/src/MGLNetworkConfiguration_Private.h @@ -1,4 +1,5 @@ #import "MGLNetworkConfiguration.h" +#include NS_ASSUME_NONNULL_BEGIN @@ -16,7 +17,7 @@ extern NSString * const kMGLDownloadPerformanceEvent; @property (nonatomic, strong) NSMutableDictionary *events; @property (nonatomic, weak) id metricsDelegate; -+ (void)setNativeNetworkManagerDelegateToDefault; +- (void)resetNativeNetworkManagerDelegate; - (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType; - (void)stopDownloadEventForResponse:(NSURLResponse *)response; - (void)cancelDownloadEventForResponse:(NSURLResponse *)response; diff --git a/platform/darwin/src/MGLNetworkIntegrationManager.h b/platform/darwin/src/MGLNetworkIntegrationManager.h deleted file mode 100644 index 2c929e16f8..0000000000 --- a/platform/darwin/src/MGLNetworkIntegrationManager.h +++ /dev/null @@ -1,8 +0,0 @@ -#import -#include - -@interface MGLNetworkIntegrationManager : NSObject - -+ (MGLNetworkIntegrationManager *)sharedManager; - -@end diff --git a/platform/darwin/src/MGLNetworkIntegrationManager.m b/platform/darwin/src/MGLNetworkIntegrationManager.m deleted file mode 100644 index 79c7f15156..0000000000 --- a/platform/darwin/src/MGLNetworkIntegrationManager.m +++ /dev/null @@ -1,54 +0,0 @@ -#import "MGLNetworkIntegrationManager.h" - -#import "MGLLoggingConfiguration_Private.h" -#import "MGLNetworkConfiguration_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MGLAccountManager_Private.h" -#endif - -@implementation MGLNetworkIntegrationManager - -static MGLNetworkIntegrationManager *instance = nil; - -+ (MGLNetworkIntegrationManager *)sharedManager { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - instance = [[MGLNetworkIntegrationManager alloc] init]; - }); - return instance; -} - -#pragma mark - MGLNativeAppleInterfaceManager delegate - - -- (NSURLSessionConfiguration *)sessionConfiguration { - return [MGLNetworkConfiguration sharedManager].sessionConfiguration; -} - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -- (NSString *)skuToken { - return MGLAccountManager.skuToken; -} -#endif - -- (void)startDownloadEvent:(NSString *)event type:(NSString *)type { - [[MGLNetworkConfiguration sharedManager] startDownloadEvent:event type:@"tile"]; -} - -- (void)cancelDownloadEventForResponse:(NSURLResponse *)response { - [[MGLNetworkConfiguration sharedManager] cancelDownloadEventForResponse:response]; -} - -- (void)stopDownloadEventForResponse:(NSURLResponse *)response { - [[MGLNetworkConfiguration sharedManager] stopDownloadEventForResponse:response]; -} - -- (void)debugLog:(NSString *)format, ... { - MGLLogDebug(format); -} - -- (void)errorLog:(NSString *)format, ... { - MGLLogError(format); -} - -@end diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm index c391e20ac3..f7d72998d8 100644 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ b/platform/darwin/src/MGLOfflineStorage.mm @@ -69,8 +69,12 @@ + (instancetype)sharedOfflineStorage { [sharedOfflineStorage reloadPacks]; }); - // Always ensure the network delegate is setup - [MGLNetworkConfiguration setNativeNetworkManagerDelegateToDefault]; + // Always ensure the MGLNativeNetworkManager delegate is setup. Calling + // `resetNativeNetworkManagerDelegate` is not necessary here, since the shared + // manager already calls it. + // + // TODO: Consider only calling this for testing? + [MGLNetworkConfiguration sharedManager]; return sharedOfflineStorage; } @@ -217,8 +221,9 @@ + (NSString *)legacyCachePath { - (instancetype)init { // Ensure network configuration & appropriate delegate prior to starting the - // run loop - [MGLNetworkConfiguration setNativeNetworkManagerDelegateToDefault]; + // run loop. Calling `resetNativeNetworkManagerDelegate` is not necessary here, + // since the shared manager already calls it. + [MGLNetworkConfiguration sharedManager]; MGLInitializeRunLoop(); diff --git a/platform/ios/Integration Tests/MGLIntegrationTestCase.h b/platform/ios/Integration Tests/MGLIntegrationTestCase.h new file mode 100644 index 0000000000..bf6c268a86 --- /dev/null +++ b/platform/ios/Integration Tests/MGLIntegrationTestCase.h @@ -0,0 +1,28 @@ +#import +#import +#import "MGLTestUtility.h" + +#define MGLTestFail(myself, ...) \ +_XCTPrimitiveFail(myself, __VA_ARGS__) + +#define MGLTestAssert(myself, expression, ...) \ + _XCTPrimitiveAssertTrue(myself, expression, @#expression, __VA_ARGS__) + +#define MGLTestAssertEqualWithAccuracy(myself, expression1, expression2, accuracy, ...) \ + _XCTPrimitiveAssertEqualWithAccuracy(myself, expression1, @#expression1, expression2, @#expression2, accuracy, @#accuracy, __VA_ARGS__) +#define MGLTestAssertNil(myself, expression, ...) \ + _XCTPrimitiveAssertNil(myself, expression, @#expression, __VA_ARGS__) + +#define MGLTestAssertNotNil(myself, expression, ...) \ + _XCTPrimitiveAssertNotNil(myself, expression, @#expression, __VA_ARGS__) + +#define MGLTestWarning(expression, format, ...) \ + ({ \ + if (!(expression)) { \ + NSString *message = [NSString stringWithFormat:format, ##__VA_ARGS__]; \ + printf("warning: Test Case '%s' at line %d: '%s' %s\n", __PRETTY_FUNCTION__, __LINE__, #expression, message.UTF8String); \ + } \ + }) + +@interface MGLIntegrationTestCase: XCTestCase +@end diff --git a/platform/ios/Integration Tests/MGLIntegrationTestCase.m b/platform/ios/Integration Tests/MGLIntegrationTestCase.m new file mode 100644 index 0000000000..caafbec422 --- /dev/null +++ b/platform/ios/Integration Tests/MGLIntegrationTestCase.m @@ -0,0 +1,56 @@ +#import "MGLIntegrationTestCase.h" + +@implementation MGLIntegrationTestCase + ++ (XCTestSuite*)defaultTestSuite { + + XCTestSuite *defaultTestSuite = [super defaultTestSuite]; + + NSArray *tests = defaultTestSuite.tests; + + XCTestSuite *newTestSuite = [XCTestSuite testSuiteWithName:defaultTestSuite.name]; + + BOOL runPendingTests = [[[NSProcessInfo processInfo] environment][@"MAPBOX_RUN_PENDING_TESTS"] boolValue]; + NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; + + for (XCTest *test in tests) { + + // Check for pending tests + if ([test.name containsString:@"PENDING"] || + [test.name containsString:@"šŸ™"]) { + if (!runPendingTests) { + printf("warning: '%s' is a pending test - skipping\n", test.name.UTF8String); + continue; + } + } + + // Check for tests that require a valid access token + if ([test.name containsString:@"šŸ”’"]) { + if (!accessToken) { + printf("warning: MAPBOX_ACCESS_TOKEN env var is required for test '%s' - skipping.\n", test.name.UTF8String); + continue; + } + } + + [newTestSuite addTest:test]; + } + + return newTestSuite; +} + +- (void)setUp { + [super setUp]; + + NSString *accessToken; + + if ([self.name containsString:@"šŸ”’"]) { + accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; + + if (!accessToken) { + printf("warning: MAPBOX_ACCESS_TOKEN env var is required for test '%s' - trying anyway.\n", self.name.UTF8String); + } + } + + [MGLAccountManager setAccessToken:accessToken ?: @"pk.feedcafedeadbeefbadebede"]; +} +@end diff --git a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h index 08576e884a..2e983f49cb 100644 --- a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h +++ b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.h @@ -1,30 +1,6 @@ -#import -#import -#import "MGLTestUtility.h" +#import "MGLIntegrationTestCase.h" -#define MGLTestFail(myself, ...) \ - _XCTPrimitiveFail(myself, __VA_ARGS__) - -#define MGLTestAssert(myself, expression, ...) \ - _XCTPrimitiveAssertTrue(myself, expression, @#expression, __VA_ARGS__) - -#define MGLTestAssertEqualWithAccuracy(myself, expression1, expression2, accuracy, ...) \ - _XCTPrimitiveAssertEqualWithAccuracy(myself, expression1, @#expression1, expression2, @#expression2, accuracy, @#accuracy, __VA_ARGS__) -#define MGLTestAssertNil(myself, expression, ...) \ - _XCTPrimitiveAssertNil(myself, expression, @#expression, __VA_ARGS__) - -#define MGLTestAssertNotNil(myself, expression, ...) \ - _XCTPrimitiveAssertNotNil(myself, expression, @#expression, __VA_ARGS__) - -#define MGLTestWarning(expression, format, ...) \ -({ \ - if (!(expression)) { \ - NSString *message = [NSString stringWithFormat:format, ##__VA_ARGS__]; \ - printf("warning: Test Case '%s' at line %d: '%s' %s\n", __PRETTY_FUNCTION__, __LINE__, #expression, message.UTF8String); \ - } \ -}) - -@interface MGLMapViewIntegrationTest : XCTestCase +@interface MGLMapViewIntegrationTest : MGLIntegrationTestCase @property (nonatomic) MGLMapView *mapView; @property (nonatomic) UIWindow *window; @property (nonatomic) MGLStyle *style; diff --git a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m index 61b305d91e..3eb80186fe 100644 --- a/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m +++ b/platform/ios/Integration Tests/MGLMapViewIntegrationTest.m @@ -7,42 +7,6 @@ - (void)setNeedsRerender; @implementation MGLMapViewIntegrationTest -+ (XCTestSuite*)defaultTestSuite { - - XCTestSuite *defaultTestSuite = [super defaultTestSuite]; - - NSArray *tests = defaultTestSuite.tests; - - XCTestSuite *newTestSuite = [XCTestSuite testSuiteWithName:defaultTestSuite.name]; - - BOOL runPendingTests = [[[NSProcessInfo processInfo] environment][@"MAPBOX_RUN_PENDING_TESTS"] boolValue]; - NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; - - for (XCTest *test in tests) { - - // Check for pending tests - if ([test.name containsString:@"PENDING"] || - [test.name containsString:@"šŸ™"]) { - if (!runPendingTests) { - printf("warning: '%s' is a pending test - skipping\n", test.name.UTF8String); - continue; - } - } - - // Check for tests that require a valid access token - if ([test.name containsString:@"šŸ”’"]) { - if (!accessToken) { - printf("warning: MAPBOX_ACCESS_TOKEN env var is required for test '%s' - skipping.\n", test.name.UTF8String); - continue; - } - } - - [newTestSuite addTest:test]; - } - - return newTestSuite; -} - - (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL { return [[MGLMapView alloc] initWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL]; } @@ -50,18 +14,6 @@ - (MGLMapView *)mapViewForTestWithFrame:(CGRect)rect styleURL:(NSURL *)styleURL - (void)setUp { [super setUp]; - NSString *accessToken; - - if ([self.name containsString:@"šŸ”’"]) { - accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"]; - - if (!accessToken) { - printf("warning: MAPBOX_ACCESS_TOKEN env var is required for test '%s' - trying anyway.\n", self.name.UTF8String); - } - } - - [MGLAccountManager setAccessToken:accessToken ?: @"pk.feedcafedeadbeefbadebede"]; - NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"]; self.mapView = [self mapViewForTestWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL]; diff --git a/platform/ios/Integration Tests/MGLNetworkConfigurationIntegrationTests.mm b/platform/ios/Integration Tests/MGLNetworkConfigurationIntegrationTests.mm index d01e8a6b85..96de541bfc 100644 --- a/platform/ios/Integration Tests/MGLNetworkConfigurationIntegrationTests.mm +++ b/platform/ios/Integration Tests/MGLNetworkConfigurationIntegrationTests.mm @@ -1,9 +1,8 @@ #import -#import "MGLNetworkIntegrationManager.h" -#import "MGLNetworkConfiguration.h" +@import Mapbox; +#import "MGLMapViewIntegrationTest.h" #import "MGLNetworkConfiguration_Private.h" #import "MGLOfflineStorage_Private.h" -#import "MGLMapView.h" #import "MGLFoundation_Private.h" @interface MGLNetworkConfiguration (Testing) @@ -11,13 +10,26 @@ + (void)testing_clearNativeNetworkManagerDelegate; + (id)testing_nativeNetworkManagerDelegate; @end -@interface MGLNetworkConfigurationIntegrationTests : XCTestCase +@interface MGLNetworkConfigurationTestDelegate: NSObject +@property (nonatomic) NSURLSession *(^handler)(); @end -#define ASSERT_DELEGATE_IS_NIL() \ +@interface MGLNetworkConfigurationSessionDelegate: NSObject +@property (nonatomic) dispatch_block_t authHandler; +@end + +@interface MGLNetworkConfigurationSessionDataDelegate: NSObject +@property (nonatomic) void (^dataHandler)(NSURLSessionDataTask *, NSData *); +@end + + +@interface MGLNetworkConfigurationIntegrationTests : MGLIntegrationTestCase +@end + +#define ASSERT_NATIVE_DELEGATE_IS_NIL() \ XCTAssertNil([MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]) -#define ASSERT_DELEGATE_IS_NOT_NIL() \ +#define ASSERT_NATIVE_DELEGATE_IS_NOT_NIL() \ XCTAssertNotNil([MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]) // NOTE: These tests are currently assumed to run in this specific order. @@ -30,10 +42,11 @@ - (void)setUp { [MGLNetworkConfiguration testing_clearNativeNetworkManagerDelegate]; } -- (void)test1_NativeNetworkManagerDelegateIsSet +- (void)test0_NativeNetworkManagerDelegateIsSet { - ASSERT_DELEGATE_IS_NIL(); - [MGLNetworkConfiguration setNativeNetworkManagerDelegateToDefault]; + ASSERT_NATIVE_DELEGATE_IS_NIL(); + MGLNetworkConfiguration *config = [[MGLNetworkConfiguration alloc] init]; + [config resetNativeNetworkManagerDelegate]; id delegate = [MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]; @@ -43,42 +56,300 @@ - (void)test1_NativeNetworkManagerDelegateIsSet // Expected properties XCTAssertNotNil([manager skuToken]); XCTAssertNotNil([manager sessionConfiguration]); + + [MGLNetworkConfiguration sharedManager]; + id delegate2 = [MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]; + XCTAssert(delegate != delegate2); } -- (void)test2_NativeNetworkManagerDelegateIsSetBySharedManager +- (void)test1_NativeNetworkManagerDelegateIsSetBySharedManager { - ASSERT_DELEGATE_IS_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NIL(); // Just calling the shared manager is also sufficient (even though, it's a // singleton and created with a dispatch_once, the delegate is re-set for // each call. [MGLNetworkConfiguration sharedManager]; - ASSERT_DELEGATE_IS_NOT_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NOT_NIL(); + + id delegate = [MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]; + id manager = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(delegate, MGLNativeNetworkDelegate); + XCTAssertNotNil(manager); + + // Expected properties + XCTAssertNotNil([manager skuToken]); + XCTAssertNotNil([manager sessionConfiguration]); +} + +- (void)test2_NativeNetworkManagerDelegateIsSet +{ + ASSERT_NATIVE_DELEGATE_IS_NIL(); + [MGLNetworkConfiguration sharedManager]; + id delegate = [MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]; + + [[MGLNetworkConfiguration sharedManager] resetNativeNetworkManagerDelegate]; + id delegate2 = [MGLNetworkConfiguration testing_nativeNetworkManagerDelegate]; + XCTAssert(delegate == delegate2); } - (void)test3_NativeNetworkManagerDelegateIsSetBySharedOfflineStorage { - ASSERT_DELEGATE_IS_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NIL(); // Similar to `[MGLNetworkConfiguration sharedManager]`, // `[MGLOfflineStorage sharedOfflineStorage]` also sets the delegate. [MGLOfflineStorage sharedOfflineStorage]; - ASSERT_DELEGATE_IS_NOT_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NOT_NIL(); } - (void)test4_NativeNetworkManagerDelegateIsSetBySharedOfflineStorageASecondTime { // Testing a second time... - ASSERT_DELEGATE_IS_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NIL(); [MGLOfflineStorage sharedOfflineStorage]; - ASSERT_DELEGATE_IS_NOT_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NOT_NIL(); } - (void)test5_NativeNetworkManagerDelegateIsSetByMapViewInit { - ASSERT_DELEGATE_IS_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NIL(); (void)[[MGLMapView alloc] init]; - ASSERT_DELEGATE_IS_NOT_NIL(); + ASSERT_NATIVE_DELEGATE_IS_NOT_NIL(); +} + +- (void)testNetworkConfigurationDelegateIsNil +{ + MGLNetworkConfiguration *manager = [MGLNetworkConfiguration sharedManager]; + XCTAssertNil(manager.delegate); +} + +- (void)internalTestNetworkConfigurationWithSession:(NSURLSession*)session shouldDownload:(BOOL)shouldDownload { + + __block BOOL didCallSessionDelegate = NO; + __block BOOL isMainThread = YES; + + // Setup delegate object that provides a NSURLSession + MGLNetworkConfiguration *manager = [MGLNetworkConfiguration sharedManager]; + MGLNetworkConfigurationTestDelegate *delegate = [[MGLNetworkConfigurationTestDelegate alloc] init]; + delegate.handler = ^{ + NSURLSession *internalSession; + @synchronized (self) { + didCallSessionDelegate = YES; + isMainThread = [NSThread isMainThread]; + internalSession = session; + } + return internalSession; + }; + + manager.delegate = delegate; + + // The following is modified/taken from MGLOfflineStorageTests as we do not yet have a + // good mechanism to test FileSource (in this SDK) + // + // Want to ensure we download from the network; nuclear option + { + XCTestExpectation *expectation = [self expectationWithDescription:@"Expect database to be reset without an error."]; + [[MGLOfflineStorage sharedOfflineStorage] resetDatabaseWithCompletionHandler:^(NSError * _Nullable error) { + XCTAssertNil(error); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:10 handler:nil]; + } + + // Boston + MGLCoordinateBounds bounds = { + { .latitude = 42.360, .longitude = -71.056 }, + { .latitude = 42.358, .longitude = -71.053 }, + }; + NSURL *styleURL = [MGLStyle lightStyleURLWithVersion:8]; + MGLTilePyramidOfflineRegion *region = [[MGLTilePyramidOfflineRegion alloc] initWithStyleURL:styleURL + bounds:bounds + fromZoomLevel:20 + toZoomLevel:20]; + + NSData *context = [NSKeyedArchiver archivedDataWithRootObject:@{ + @"Name": @"Faneuil Hall" + }]; + + __block MGLOfflinePack *pack = nil; + + // Add pack + { + XCTestExpectation *additionCompletionHandlerExpectation = [self expectationWithDescription:@"add pack completion handler"]; + + [[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region + withContext:context + completionHandler:^(MGLOfflinePack * _Nullable completionHandlerPack, NSError * _Nullable error) { + pack = completionHandlerPack; + [additionCompletionHandlerExpectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5 handler:nil]; + } + + XCTAssert(pack.state == MGLOfflinePackStateInactive); + + // Download + { + XCTestExpectation *expectation = [self expectationForNotification:MGLOfflinePackProgressChangedNotification object:pack handler:^BOOL(NSNotification * _Nonnull notification) { + return pack.state == MGLOfflinePackStateComplete; + }]; + + expectation.inverted = !shouldDownload; + [pack resume]; + + [self waitForExpectations:@[expectation] timeout:15]; + } + + XCTAssert(didCallSessionDelegate); + XCTAssertFalse(isMainThread); + + // Remove pack, so we don't affect other tests + { + XCTestExpectation *expectation = [self expectationWithDescription:@"remove pack completion handler"]; + [[MGLOfflineStorage sharedOfflineStorage] removePack:pack withCompletionHandler:^(NSError * _Nullable error) { + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5 handler:nil]; + } +} + +- (void)testNetworkConfigurationWithSharedSessionšŸ”’ { + NSURLSession *session = [NSURLSession sharedSession]; + [self internalTestNetworkConfigurationWithSession:session shouldDownload:YES]; +} + +- (void)testNetworkConfigurationWithBackgroundSessionConfiguration { + // Background session configurations are NOT supported, we expect this test + // trigger an exception + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:NSStringFromSelector(_cmd)]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig]; + + XCTAssert([session isKindOfClass:NSClassFromString(@"__NSURLBackgroundSession")]); + + // We cannot do this yet, as it requires intecepting the exception in gl-native + // It makes more sense to support background configs (requiring delegation + // rather than blocks in gl-native) + // [self internalTestNetworkConfigurationWithSession:session], NSException, NSInvalidArgumentException); +} + +- (void)testNetworkConfigurationWithDefaultSessionConfigurationšŸ”’ { + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig]; + [self internalTestNetworkConfigurationWithSession:session shouldDownload:YES]; +} + +- (void)testNetworkConfigurationWithEmphemeralSessionConfigurationšŸ”’ { + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig]; + [self internalTestNetworkConfigurationWithSession:session shouldDownload:YES]; +} + +- (void)testNetworkConfigurationWithSessionConfigurationWithDelegatešŸ”’ { + __block BOOL didCallAuthChallenge = NO; + __block BOOL isMainThread = YES; + + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + MGLNetworkConfigurationSessionDelegate *delegate = [[MGLNetworkConfigurationSessionDelegate alloc] init]; + delegate.authHandler = ^{ + @synchronized (self) { + didCallAuthChallenge = YES; + isMainThread = [NSThread isMainThread]; + } + }; + + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:delegate + delegateQueue:nil]; + [self internalTestNetworkConfigurationWithSession:session shouldDownload:NO]; + + [session finishTasksAndInvalidate]; + + XCTAssertFalse(isMainThread); + XCTAssert(didCallAuthChallenge); +} + +- (void)testFailureForNetworkConfigurationWithSessionWithDataDelegatešŸ”’ { + __block BOOL didCallReceiveData = NO; + + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + MGLNetworkConfigurationSessionDataDelegate *delegate = [[MGLNetworkConfigurationSessionDataDelegate alloc] init]; + delegate.dataHandler = ^(NSURLSessionDataTask *task, NSData *data) { + @synchronized (self) { + didCallReceiveData = YES; + } + }; + + // NOTE: Sessions with a delegate that conforms to NSURLSessionDataDelegate + // are NOT supported. + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:delegate + delegateQueue:nil]; + + BOOL conforms = [session.delegate conformsToProtocol:@protocol(NSURLSessionDataDelegate)]; + XCTAssert(conforms); +#ifdef DEBUG + if (conforms) { + NSLog(@"Session delegates conforming to NSURLSessionDataDelegate are not supported"); + } +#else + [self internalTestNetworkConfigurationWithSession:session shouldDownload:YES]; +#endif + [session finishTasksAndInvalidate]; + + XCTAssertFalse(didCallReceiveData); +} + +- (void)testNetworkConfigurationWithSessionConfigurationWithCustomHeadersšŸ”’ { + // Custom session configuration, based on `MGLNetworkConfiguration.defaultSessionConfiguration` + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + sessionConfig.HTTPAdditionalHeaders = @{ @"testing" : @YES }; + sessionConfig.HTTPMaximumConnectionsPerHost = 1; + sessionConfig.timeoutIntervalForResource = 30; + sessionConfig.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + sessionConfig.URLCache = nil; + + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig]; + + [self internalTestNetworkConfigurationWithSession:session shouldDownload:YES]; } @end + +#pragma mark - MGLNetworkConfiguration delegate + +@implementation MGLNetworkConfigurationTestDelegate +- (NSURLSession *)sessionForNetworkConfiguration:(MGLNetworkConfiguration *)configuration { + if (self.handler) { + return self.handler(); + } + + return nil; +} +@end + +#pragma mark - NSURLSession delegate + +@implementation MGLNetworkConfigurationSessionDelegate +- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler { + if (self.authHandler) { + self.authHandler(); + } + + // Cancel the challenge + completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil); +} +@end + +#pragma mark - NSURLSession data delegate + +@implementation MGLNetworkConfigurationSessionDataDelegate +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { + if (self.dataHandler) { + self.dataHandler(dataTask, data); + } +} +@end + + + + diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 4fd3aa5177..a0649ee9cc 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -393,10 +393,6 @@ CA0FAA07237B3BC600C9F3C9 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA8847D21CBAF91600AB86E3 /* Mapbox.framework */; }; CA0FAA08237B3BC600C9F3C9 /* MapboxMobileEvents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA96299B23731199004F1330 /* MapboxMobileEvents.framework */; }; CA0FAA09237B3BEA00C9F3C9 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA8847D21CBAF91600AB86E3 /* Mapbox.framework */; }; - CA17464923D81581008B7A43 /* MGLNetworkIntegrationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A490C46B23C688CC009AC158 /* MGLNetworkIntegrationManager.m */; }; - CA17464A23D81587008B7A43 /* MGLNetworkIntegrationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A490C46C23C688CC009AC158 /* MGLNetworkIntegrationManager.h */; }; - CA17464B23D81589008B7A43 /* MGLNetworkIntegrationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = A490C46C23C688CC009AC158 /* MGLNetworkIntegrationManager.h */; }; - CA17464C23D81595008B7A43 /* MGLNetworkIntegrationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A490C46B23C688CC009AC158 /* MGLNetworkIntegrationManager.m */; }; CA17464E23D8A93C008B7A43 /* MGLNetworkConfigurationIntegrationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA17464D23D8A93C008B7A43 /* MGLNetworkConfigurationIntegrationTests.mm */; }; CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */; }; CA488BAB23FCE6B900AEE226 /* MapboxMobileEvents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA96299B23731199004F1330 /* MapboxMobileEvents.framework */; }; @@ -408,6 +404,7 @@ CA4F3BE4231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA4F3BE3231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm */; }; CA55CD41202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA55CD42202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CA600149242BD8360041BBEC /* MGLIntegrationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = CA600148242BD8360041BBEC /* MGLIntegrationTestCase.m */; }; CA65C4F821E9BB080068B0D4 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA65C4F721E9BB080068B0D4 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA65C4F921E9BB080068B0D4 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA65C4F721E9BB080068B0D4 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA6914B520E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA6914B420E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.mm */; }; @@ -1040,8 +1037,6 @@ 9C6E286522A9849E0056B7BE /* release-notes-jazzy.md.ejs */ = {isa = PBXFileReference; lastKnownFileType = text; path = "release-notes-jazzy.md.ejs"; sourceTree = ""; }; 9C6E286622A9849E0056B7BE /* deploy-snapshot.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "deploy-snapshot.sh"; sourceTree = ""; }; 9C6E286722A9849E0056B7BE /* release-notes.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "release-notes.js"; sourceTree = ""; }; - A490C46B23C688CC009AC158 /* MGLNetworkIntegrationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkIntegrationManager.m; sourceTree = ""; }; - A490C46C23C688CC009AC158 /* MGLNetworkIntegrationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNetworkIntegrationManager.h; sourceTree = ""; }; A4DE3DC823038A07005B3473 /* MGLMockGestureRecognizers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLMockGestureRecognizers.m; sourceTree = ""; }; A4DE3DCA23038A7F005B3473 /* MGLMockGestureRecognizers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMockGestureRecognizers.h; sourceTree = ""; }; A4F3FB1C2254865900A30170 /* missing_icon.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = missing_icon.json; sourceTree = ""; }; @@ -1059,6 +1054,8 @@ CA4F3BE3231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionFinishTests.mm; sourceTree = ""; }; CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCameraChangeReason.h; sourceTree = ""; }; CA5E5042209BDC5F001A8A81 /* MGLTestUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MGLTestUtility.h; path = ../../darwin/test/MGLTestUtility.h; sourceTree = ""; }; + CA600148242BD8360041BBEC /* MGLIntegrationTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLIntegrationTestCase.m; sourceTree = ""; }; + CA60014A242BD8710041BBEC /* MGLIntegrationTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLIntegrationTestCase.h; sourceTree = ""; }; CA65C4F721E9BB080068B0D4 /* MGLCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCluster.h; sourceTree = ""; }; CA6914B420E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLAnnotationViewIntegrationTests.mm; path = "Annotation Tests/MGLAnnotationViewIntegrationTests.mm"; sourceTree = ""; }; CA86FF0D22D8D5A0009EB14A /* MGLNetworkConfigurationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfigurationTests.m; sourceTree = ""; }; @@ -1437,6 +1434,8 @@ CA4F3BDD230F74C3008BAFEA /* MGLMapViewPendingBlockTests.m */, CA4C54FD2324948100A81659 /* MGLSourceTests.swift */, CA17464D23D8A93C008B7A43 /* MGLNetworkConfigurationIntegrationTests.mm */, + CA600148242BD8360041BBEC /* MGLIntegrationTestCase.m */, + CA60014A242BD8710041BBEC /* MGLIntegrationTestCase.h */, ); path = "Integration Tests"; sourceTree = ""; @@ -1943,8 +1942,6 @@ DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */, 1F2B94BF221636D800210640 /* MGLNetworkConfiguration_Private.h */, DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */, - A490C46C23C688CC009AC158 /* MGLNetworkIntegrationManager.h */, - A490C46B23C688CC009AC158 /* MGLNetworkIntegrationManager.m */, DA35D9BF240916290013ECB0 /* MGLReachability.h */, DA35D9BE240916290013ECB0 /* MGLReachability.m */, 3EA9337830C7738BF7F5493C /* MGLRendererConfiguration.h */, @@ -2289,7 +2286,6 @@ DA27C24F1CBB4C11000B0ECD /* MGLAccountManager_Private.h in Headers */, DA8847FC1CBAFA5100AB86E3 /* MGLStyle.h in Headers */, DD9BE4F71EB263C50079A3AF /* UIViewController+MGLAdditions.h in Headers */, - CA17464A23D81587008B7A43 /* MGLNetworkIntegrationManager.h in Headers */, DAF0D8131DFE0EC500B28378 /* MGLVectorTileSource_Private.h in Headers */, 354B83961D2E873E005D9406 /* MGLUserLocationAnnotationView.h in Headers */, 74CB5EC3219B282500102936 /* MGLCircleStyleLayer_Private.h in Headers */, @@ -2454,7 +2450,6 @@ 1F6A82A92138871900BA5B41 /* MGLLoggingConfiguration_Private.h in Headers */, DABFB8661CBE99E500D62B32 /* MGLPointAnnotation.h in Headers */, 96E6145A22CC169000109F14 /* MGLCompassButton.h in Headers */, - CA17464B23D81589008B7A43 /* MGLNetworkIntegrationManager.h in Headers */, 96E516E42000560B00A02306 /* MGLComputedShapeSource_Private.h in Headers */, 96E516E92000560B00A02306 /* MGLAnnotationImage_Private.h in Headers */, 96E516E52000560B00A02306 /* MGLOfflinePack_Private.h in Headers */, @@ -2969,6 +2964,7 @@ CA4C54FE2324948100A81659 /* MGLSourceTests.swift in Sources */, CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */, CA4F3BE4231077B9008BAFEA /* MGLCameraTransitionFinishTests.mm in Sources */, + CA600149242BD8360041BBEC /* MGLIntegrationTestCase.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3084,7 +3080,6 @@ DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */, 30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */, 550570C622958FB400228ECF /* MGLMapView+Impl.mm in Sources */, - CA17464923D81581008B7A43 /* MGLNetworkIntegrationManager.m in Sources */, 40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */, DA8848541CBAFB9800AB86E3 /* MGLCompactCalloutView.m in Sources */, DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.mm in Sources */, @@ -3185,7 +3180,6 @@ DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */, 30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */, 40EDA1C21CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */, - CA17464C23D81595008B7A43 /* MGLNetworkIntegrationManager.m in Sources */, 550570C722958FB400228ECF /* MGLMapView+Impl.mm in Sources */, DAA4E4291CBB730400178DFB /* NSBundle+MGLAdditions.m in Sources */, 35136D3D1D42272500C20EFD /* MGLCircleStyleLayer.mm in Sources */, diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 5bf5ce756d..56ede0bb9b 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -68,7 +68,6 @@ #import "MGLLocationManager_Private.h" #import "MGLLoggingConfiguration_Private.h" #import "MGLNetworkConfiguration_Private.h" -#import "MGLNetworkIntegrationManager.h" #import "MGLReachability.h" #import @@ -452,12 +451,12 @@ - (void)commonInit _opaque = NO; // setup accessibility - // -// self.isAccessibilityElement = YES; - MGLNativeNetworkManager.sharedManager.delegate = MGLNetworkIntegrationManager.sharedManager; +// self.isAccessibilityElement = YES; - // Ensure network configuration is set up - [MGLNetworkConfiguration setNativeNetworkManagerDelegateToDefault]; + // Ensure network configuration is set up (connect gl-native networking to + // platform SDK via delegation). Calling `resetNativeNetworkManagerDelegate` + // is not necessary here, since the shared manager already calls it. + [MGLNetworkConfiguration sharedManager]; self.accessibilityLabel = NSLocalizedStringWithDefaultValue(@"MAP_A11Y_LABEL", nil, nil, @"Map", @"Accessibility label"); self.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction | UIAccessibilityTraitAdjustable; diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 18b5d8a8a1..9fc46195b8 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -290,8 +290,6 @@ DAE6C3D41CC34C9900DB3429 /* MGLOfflineRegionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3CA1CC34BD800DB3429 /* MGLOfflineRegionTests.m */; }; DAE6C3D61CC34C9900DB3429 /* MGLStyleTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3CC1CC34BD800DB3429 /* MGLStyleTests.mm */; }; DAE7DEC41E24549F007505A6 /* MGLNSStringAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE7DEC31E24549F007505A6 /* MGLNSStringAdditionsTests.m */; }; - DAEC2FB624087D360090E94E /* MGLNetworkIntegrationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEC2FB424087D360090E94E /* MGLNetworkIntegrationManager.m */; }; - DAEC2FB724087D360090E94E /* MGLNetworkIntegrationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DAEC2FB524087D360090E94E /* MGLNetworkIntegrationManager.h */; }; DAED385F1D62CED700D7640F /* NSURL+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DAED385D1D62CED700D7640F /* NSURL+MGLAdditions.h */; }; DAED38601D62CED700D7640F /* NSURL+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DAED385E1D62CED700D7640F /* NSURL+MGLAdditions.m */; }; DAEDC4321D6033F1000224FF /* MGLAttributionInfoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEDC4311D6033F1000224FF /* MGLAttributionInfoTests.m */; }; @@ -721,8 +719,6 @@ DAE9ED54223897ED00C01291 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Foundation.strings; sourceTree = ""; }; DAE9ED55223898B200C01291 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gl; path = gl.lproj/Foundation.stringsdict; sourceTree = ""; }; DAE9ED56223898CF00C01291 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Localizable.strings; sourceTree = ""; }; - DAEC2FB424087D360090E94E /* MGLNetworkIntegrationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkIntegrationManager.m; sourceTree = ""; }; - DAEC2FB524087D360090E94E /* MGLNetworkIntegrationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNetworkIntegrationManager.h; sourceTree = ""; }; DAED385D1D62CED700D7640F /* NSURL+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+MGLAdditions.h"; sourceTree = ""; }; DAED385E1D62CED700D7640F /* NSURL+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+MGLAdditions.m"; sourceTree = ""; }; DAEDC4311D6033F1000224FF /* MGLAttributionInfoTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLAttributionInfoTests.m; path = ../../darwin/test/MGLAttributionInfoTests.m; sourceTree = ""; }; @@ -1263,8 +1259,6 @@ DD0902B01DB1AC6400C5BDCE /* MGLNetworkConfiguration.h */, 1F2B94C2221E22E500210640 /* MGLNetworkConfiguration_Private.h */, DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */, - DAEC2FB524087D360090E94E /* MGLNetworkIntegrationManager.h */, - DAEC2FB424087D360090E94E /* MGLNetworkIntegrationManager.m */, DA35D9C4240916370013ECB0 /* MGLReachability.h */, DA35D9C5240916380013ECB0 /* MGLReachability.m */, 3EA9369A4C46957566058822 /* MGLRendererConfiguration.h */, @@ -1380,7 +1374,6 @@ DA7DC9811DED5F5C0027472F /* MGLVectorTileSource_Private.h in Headers */, DAE6C3861CC31E2A00DB3429 /* MGLGeometry_Private.h in Headers */, DAE6C3841CC31E2A00DB3429 /* MGLAccountManager_Private.h in Headers */, - DAEC2FB724087D360090E94E /* MGLNetworkIntegrationManager.h in Headers */, DACA8622201920BE00E9693A /* MGLRasterDEMSource.h in Headers */, DAE6C3691CC31E0400DB3429 /* MGLTypes.h in Headers */, 07D9474D1F67441B00E37934 /* MGLComputedShapeSource_Private.h in Headers */, @@ -1714,7 +1707,6 @@ 408AA86A1DAEEE5D00022900 /* NSDictionary+MGLAdditions.mm in Sources */, DA8F25881D51C9E10010E6B5 /* MGLBackgroundStyleLayer.mm in Sources */, DA551B841DB496AC0009AFAF /* MGLTileSource.mm in Sources */, - DAEC2FB624087D360090E94E /* MGLNetworkIntegrationManager.m in Sources */, DAE6C3B81CC31EF300DB3429 /* MGLMapView+IBAdditions.mm in Sources */, DA35A2D01CCAAED300E826B2 /* NSValue+MGLAdditions.m in Sources */, 3538AA241D542685008EC33D /* MGLStyleLayer.mm in Sources */, diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 8d1d91f02a..a234199d4e 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -55,8 +55,8 @@ #import "NSColor+MGLAdditions.h" #import "NSImage+MGLAdditions.h" #import "NSPredicate+MGLPrivateAdditions.h" +#import "MGLNetworkConfiguration_Private.h" #import "MGLLoggingConfiguration_Private.h" -#import "MGLNetworkIntegrationManager.h" #import "MGLReachability.h" class MGLAnnotationContext; @@ -259,7 +259,8 @@ + (NSArray *)restorableStateKeyPaths { } - (void)commonInit { - MGLNativeNetworkManager.sharedManager.delegate = MGLNetworkIntegrationManager.sharedManager; + [MGLNetworkConfiguration sharedManager]; + _isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent; // Set up cross-platform controllers and resources.