Skip to content
This repository has been archived by the owner on Jun 21, 2023. It is now read-only.

Commit

Permalink
Adds delegate to MGLNetworkConfiguration (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian Rex authored Mar 27, 2020
1 parent be6574d commit 171ff94
Show file tree
Hide file tree
Showing 15 changed files with 506 additions and 216 deletions.
37 changes: 34 additions & 3 deletions platform/darwin/src/MGLNetworkConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,42 @@

NS_ASSUME_NONNULL_BEGIN

@class MGLNetworkConfiguration;

@protocol MGLNetworkConfigurationDelegate <NSObject>
@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.
*/
MGL_EXPORT
@interface MGLNetworkConfiguration : NSObject

/**
:nodoc:
Delegate for the `MGLNetworkConfiguration` class.
*/
@property (nonatomic, weak) id<MGLNetworkConfigurationDelegate> delegate;

/**
Returns the shared instance of the `MGLNetworkConfiguration` class.
*/
Expand All @@ -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;

Expand Down
98 changes: 72 additions & 26 deletions platform/darwin/src/MGLNetworkConfiguration.m
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
#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 () <MGLNativeNetworkDelegate>

@property (strong) NSURLSessionConfiguration *sessionConfig;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary*> *events;
@property (nonatomic, weak) id<MGLNetworkConfigurationMetricsDelegate> metricsDelegate;
@property (nonatomic) dispatch_queue_t eventsQueue;

@end

@implementation MGLNetworkConfiguration
{
NSURLSessionConfiguration *_sessionConfig;
}

- (instancetype)init {
if (self = [super init]) {
Expand All @@ -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 {
Expand All @@ -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];
}
}

Expand All @@ -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]]) {
Expand All @@ -103,7 +150,6 @@ - (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString *
});
}
}

}

- (NSDictionary *)eventAttributesForURL:(NSURLResponse *)response withAction:(NSString *)action
Expand Down
3 changes: 2 additions & 1 deletion platform/darwin/src/MGLNetworkConfiguration_Private.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#import "MGLNetworkConfiguration.h"
#include <mbgl/interface/native_apple_interface.h>

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -16,7 +17,7 @@ extern NSString * const kMGLDownloadPerformanceEvent;
@property (nonatomic, strong) NSMutableDictionary<NSString*, NSDictionary*> *events;
@property (nonatomic, weak) id<MGLNetworkConfigurationMetricsDelegate> metricsDelegate;

+ (void)setNativeNetworkManagerDelegateToDefault;
- (void)resetNativeNetworkManagerDelegate;
- (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType;
- (void)stopDownloadEventForResponse:(NSURLResponse *)response;
- (void)cancelDownloadEventForResponse:(NSURLResponse *)response;
Expand Down
8 changes: 0 additions & 8 deletions platform/darwin/src/MGLNetworkIntegrationManager.h

This file was deleted.

54 changes: 0 additions & 54 deletions platform/darwin/src/MGLNetworkIntegrationManager.m

This file was deleted.

13 changes: 9 additions & 4 deletions platform/darwin/src/MGLOfflineStorage.mm
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();

Expand Down
28 changes: 28 additions & 0 deletions platform/ios/Integration Tests/MGLIntegrationTestCase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#import <XCTest/XCTest.h>
#import <Mapbox/Mapbox.h>
#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
Loading

0 comments on commit 171ff94

Please sign in to comment.