From edd04d31eb591180b76969be971039b0cde00c88 Mon Sep 17 00:00:00 2001 From: Julian Rex Date: Tue, 11 Jun 2019 18:22:20 -0400 Subject: [ios] Added offline query parameter (#14857) --- platform/darwin/src/http_file_source.mm | 43 +++++++++++---- platform/darwin/test/MGLResourceTests.mm | 74 ++++++++++++++++++++++++++ platform/ios/ios.xcodeproj/project.pbxproj | 18 ++++--- platform/macos/macos.xcodeproj/project.pbxproj | 20 ++++--- 4 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 platform/darwin/test/MGLResourceTests.mm diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm index 0d14c44c01..79810546b3 100644 --- a/platform/darwin/src/http_file_source.mm +++ b/platform/darwin/src/http_file_source.mm @@ -196,24 +196,45 @@ HTTPFileSource::HTTPFileSource() HTTPFileSource::~HTTPFileSource() = default; +MGL_EXPORT +NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountType) { + + NSURL *url = [NSURL URLWithString:@(resource.url.c_str())]; + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + if (accountType == 0 && + ([url.host isEqualToString:@"mapbox.com"] || [url.host hasSuffix:@".mapbox.com"])) { + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + NSURLQueryItem *accountsQueryItem = [NSURLQueryItem queryItemWithName:@"sku" value:MGLAccountManager.skuToken]; + + NSMutableArray *queryItems = [NSMutableArray arrayWithObject:accountsQueryItem]; + + // offline here + if (resource.usage == Resource::Usage::Offline) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"offline" value:@"true"]]; + } + + if (components.queryItems) { + [queryItems addObjectsFromArray:components.queryItems]; + } + + components.queryItems = queryItems; + url = components.URL; + } +#else + (void)accountType; +#endif + return url; +} + 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. @autoreleasepool { - NSURL *url = [NSURL URLWithString:@(resource.url.c_str())]; + NSURL *url = resourceURLWithAccountType(resource, impl->accountType); MGLLogDebug(@"Requesting URI: %@", url.relativePath); -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - if (impl->accountType == 0 && - ([url.host isEqualToString:@"mapbox.com"] || [url.host hasSuffix:@".mapbox.com"])) { - NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; - NSURLQueryItem *accountsQueryItem = [NSURLQueryItem queryItemWithName:@"sku" value:MGLAccountManager.skuToken]; - components.queryItems = components.queryItems ? [components.queryItems arrayByAddingObject:accountsQueryItem] : @[accountsQueryItem]; - url = components.URL; - } -#endif - NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; if (resource.priorEtag) { [req addValue:@(resource.priorEtag->c_str()) diff --git a/platform/darwin/test/MGLResourceTests.mm b/platform/darwin/test/MGLResourceTests.mm new file mode 100644 index 0000000000..0420997c39 --- /dev/null +++ b/platform/darwin/test/MGLResourceTests.mm @@ -0,0 +1,74 @@ +#import +#import +#import + +namespace mbgl { + extern NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountType); +} + +@interface MGLResourceTests : XCTestCase +@end + +@implementation MGLResourceTests + +- (void)testOfflineQueryParameterIsAddedForOfflineResource { + + using namespace mbgl; + + std::string testURL = "test://mapbox.com/testing_offline_query?a=one&b=two"; + + // Is our test URL "correct" for subsequent checks? + { + NSURL *url = [NSURL URLWithString:@(testURL.c_str())]; + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + NSArray *items = components.queryItems; + XCTAssert(items.count == 2 ); + } + + Resource resource(Resource::Kind::Unknown, testURL); + + // By default, resource are NOT offline + { + NSURL *url = resourceURLWithAccountType(resource, 0); + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + for (NSURLQueryItem *item in components.queryItems) { + XCTAssertFalse([item.name isEqualToString:@"offline"]); + } + } + + // Now check offline + resource.setUsage(Resource::Usage::Offline); + + { + NSURL *url = resourceURLWithAccountType(resource, 0); + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + + // For offline, we expect a single offline param and a sku param + NSInteger foundCount = 0; + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + for (NSURLQueryItem *item in components.queryItems) { + if (([item.name isEqualToString:@"offline"] && [item.value isEqualToString:@"true"]) || + ([item.name isEqualToString:@"a"] && [item.value isEqualToString:@"one"]) || + ([item.name isEqualToString:@"b"] && [item.value isEqualToString:@"two"]) || + ([item.name isEqualToString:@"sku"])) { + foundCount++; + } + } + + XCTAssert(foundCount == 4); +#else + // NOTE: Currently the macOS SDK does not supply the sku or offline query parameters + for (NSURLQueryItem *item in components.queryItems) { + if (([item.name isEqualToString:@"a"] && [item.value isEqualToString:@"one"]) || + ([item.name isEqualToString:@"b"] && [item.value isEqualToString:@"two"])) { + foundCount++; + } + } + + XCTAssert(foundCount == 2); +#endif + } +} + +@end diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index be7d0e4249..ed9ac56f04 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -474,7 +474,6 @@ 9C6E284522A982670056B7BE /* MMEUINavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 406E99B31FFEFED600D9FFCC /* MMEUINavigation.h */; }; 9C6E284622A982670056B7BE /* MMEUniqueIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 40834BBF1FE05D6E00C1BD0D /* MMEUniqueIdentifier.h */; }; 9C6E284722A982670056B7BE /* MMEDispatchManager.h in Headers */ = {isa = PBXBuildFile; fileRef = ACA65F552140696B00537748 /* MMEDispatchManager.h */; }; - 9C6E284922A984120056B7BE /* Makefile in Sources */ = {isa = PBXBuildFile; fileRef = 9C6E284822A984120056B7BE /* Makefile */; }; A4F3FB1D2254865900A30170 /* missing_icon.json in Resources */ = {isa = PBXBuildFile; fileRef = A4F3FB1C2254865900A30170 /* missing_icon.json */; }; AC46EB59225E600A0039C013 /* MMECertPin.h in Headers */ = {isa = PBXBuildFile; fileRef = AC46EB57225E60090039C013 /* MMECertPin.h */; }; AC46EB5A225E600A0039C013 /* MMECertPin.h in Headers */ = {isa = PBXBuildFile; fileRef = AC46EB57225E60090039C013 /* MMECertPin.h */; }; @@ -512,6 +511,7 @@ CAA69DA4206DCD0E007279CD /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA4A26961CB6E795000B7809 /* Mapbox.framework */; }; CAA69DA5206DCD0E007279CD /* Mapbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DA4A26961CB6E795000B7809 /* Mapbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; CABE5DAD2072FAB40003AF3C /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA8847D21CBAF91600AB86E3 /* Mapbox.framework */; }; + CAD9D0AA22A86D6F001B25EE /* MGLResourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CAD9D0A922A86D6F001B25EE /* MGLResourceTests.mm */; }; CAE7AD5520F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */; }; DA00FC8E1D5EEB0D009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA00FC8F1D5EEB0D009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1181,6 +1181,7 @@ CA6914B420E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLAnnotationViewIntegrationTests.m; path = "Annotation Tests/MGLAnnotationViewIntegrationTests.m"; sourceTree = ""; }; CA88DC2F21C85D900059ED5A /* MGLStyleURLIntegrationTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLStyleURLIntegrationTest.m; sourceTree = ""; }; CA8FBC0821A47BB100D1203C /* MGLRendererConfigurationTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLRendererConfigurationTests.mm; path = ../../darwin/test/MGLRendererConfigurationTests.mm; sourceTree = ""; }; + CAD9D0A922A86D6F001B25EE /* MGLResourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLResourceTests.mm; path = ../../darwin/test/MGLResourceTests.mm; sourceTree = ""; }; CAE7AD5320F46EF5003B6782 /* integration-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "integration-Bridging-Header.h"; sourceTree = ""; }; CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MGLMapSnapshotterSwiftTests.swift; sourceTree = ""; }; DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo.h; sourceTree = ""; }; @@ -2005,9 +2006,8 @@ DA2E88521CC036F400F24E7B /* SDK Tests */ = { isa = PBXGroup; children = ( - 4031ACFD1E9FD26900A3EA26 /* Test Helpers */, - 409F43FB1E9E77D10048729D /* Swift Integration */, - 357579811D502AD4000B822E /* Styling */, + DA2E88551CC036F400F24E7B /* Info.plist */, + DA2784FB1DF02FF4001D5B8D /* Media.xcassets */, 3502D6CB22AE88D5006BDFCE /* MGLAccountManagerTests.m */, 353D23951D0B0DFE002BE09D /* MGLAnnotationViewTests.m */, DAEDC4331D603417000224FF /* MGLAttributionInfoTests.m */, @@ -2023,10 +2023,10 @@ DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */, DA5DB1291FABF1EE001C2326 /* MGLMapAccessibilityElementTests.m */, DA695425215B1E75002041A4 /* MGLMapCameraTests.m */, - 076171C22139C70900668A35 /* MGLMapViewTests.m */, 96ED34DD22374C0900E9FCA9 /* MGLMapViewDirectionTests.mm */, 16376B481FFEED010000563E /* MGLMapViewLayoutTests.m */, 9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */, + 076171C22139C70900668A35 /* MGLMapViewTests.m */, 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */, 96036A0520059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m */, DAE7DEC11E245455007505A6 /* MGLNSStringAdditionsTests.m */, @@ -2035,12 +2035,14 @@ 55E2AD121E5B125400E8C587 /* MGLOfflineStorageTests.mm */, 35B8E08B1D6C8B5100E768D2 /* MGLPredicateTests.mm */, CA8FBC0821A47BB100D1203C /* MGLRendererConfigurationTests.mm */, + CAD9D0A922A86D6F001B25EE /* MGLResourceTests.mm */, DA2E88601CC0382C00F24E7B /* MGLStyleTests.mm */, 556660D71E1D085500E2C41B /* MGLVersionNumber.m */, - DA2E88551CC036F400F24E7B /* Info.plist */, - DA2784FB1DF02FF4001D5B8D /* Media.xcassets */, DA35D0871E1A6309007DED41 /* one-liner.json */, 1F8A59F62165326C004DFE75 /* sideload_sat.db */, + 357579811D502AD4000B822E /* Styling */, + 409F43FB1E9E77D10048729D /* Swift Integration */, + 4031ACFD1E9FD26900A3EA26 /* Test Helpers */, ); name = "SDK Tests"; path = test; @@ -3190,7 +3192,6 @@ 40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */, 1F26B6C120E189C9007BCC21 /* MBXCustomLocationViewController.m in Sources */, 3E6465D62065767A00685536 /* LimeGreenStyleLayer.m in Sources */, - 9C6E284922A984120056B7BE /* Makefile in Sources */, 632281DF1E6F855900D75A5D /* MBXEmbeddedMapViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3228,6 +3229,7 @@ 1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */, DA695426215B1E76002041A4 /* MGLMapCameraTests.m in Sources */, CA8FBC0921A47BB100D1203C /* MGLRendererConfigurationTests.mm in Sources */, + CAD9D0AA22A86D6F001B25EE /* MGLResourceTests.mm in Sources */, DD58A4C61D822BD000E1F038 /* MGLExpressionTests.mm in Sources */, 3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.mm in Sources */, 9658C155204761FC00D8A674 /* MGLMapViewScaleBarTests.m in Sources */, diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index d2d367d7bb..93a0b616a7 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -132,6 +132,7 @@ CA4045C7216720D700B356E1 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA4045C4216720D700B356E1 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; CA8FBC0D21A4A74300D1203C /* MGLRendererConfigurationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA8FBC0C21A4A74300D1203C /* MGLRendererConfigurationTests.mm */; }; CA9461A620884CCB0015EB12 /* MGLAnnotationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA9461A520884CCB0015EB12 /* MGLAnnotationTests.m */; }; + CAD9D0AC22A88A32001B25EE /* MGLResourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CAD9D0AB22A88A32001B25EE /* MGLResourceTests.mm */; }; DA00FC8A1D5EEAC3009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC881D5EEAC3009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA00FC8B1D5EEAC3009AABC8 /* MGLAttributionInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA00FC891D5EEAC3009AABC8 /* MGLAttributionInfo.mm */; }; DA0CD58E1CF56F5800A5F5A5 /* MGLFeatureTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */; }; @@ -470,6 +471,7 @@ CA4045C4216720D700B356E1 /* MGLCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCluster.h; sourceTree = ""; }; CA8FBC0C21A4A74300D1203C /* MGLRendererConfigurationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLRendererConfigurationTests.mm; path = ../../darwin/test/MGLRendererConfigurationTests.mm; sourceTree = ""; }; CA9461A520884CCB0015EB12 /* MGLAnnotationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLAnnotationTests.m; path = test/MGLAnnotationTests.m; sourceTree = SOURCE_ROOT; }; + CAD9D0AB22A88A32001B25EE /* MGLResourceTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLResourceTests.mm; path = ../../darwin/test/MGLResourceTests.mm; sourceTree = ""; }; DA00FC881D5EEAC3009AABC8 /* MGLAttributionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo.h; sourceTree = ""; }; DA00FC891D5EEAC3009AABC8 /* MGLAttributionInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLAttributionInfo.mm; sourceTree = ""; }; DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFeatureTests.mm; path = ../../darwin/test/MGLFeatureTests.mm; sourceTree = ""; }; @@ -1174,37 +1176,38 @@ DAE6C3371CC30DB200DB3429 /* SDK Tests */ = { isa = PBXGroup; children = ( - 4031AD001E9FD61000A3EA26 /* Test Helpers */, - 4031ACFA1E9EB39A00A3EA26 /* Swift Integration */, - DA8F257D1D51C5F40010E6B5 /* Styling */, + DAE6C33A1CC30DB200DB3429 /* Info.plist */, + DA2784FD1DF03060001D5B8D /* Media.xcassets */, CA9461A520884CCB0015EB12 /* MGLAnnotationTests.m */, - DAEDC4311D6033F1000224FF /* MGLAttributionInfoTests.m */, DAEDC4361D606291000224FF /* MGLAttributionButtonTests.m */, + DAEDC4311D6033F1000224FF /* MGLAttributionInfoTests.m */, DA35A2C11CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m */, 3526EABC1DF9B19800006B43 /* MGLCodingTests.mm */, DA35A2B51CCA14D700E826B2 /* MGLCompassDirectionFormatterTests.m */, DA35A2A71CC9F41600E826B2 /* MGLCoordinateFormatterTests.m */, + 35C6DF861E214C1800ACA483 /* MGLDistanceFormatterTests.m */, DA2987591E1A4290002299F5 /* MGLDocumentationExampleTests.swift */, DA57D4B01EBC699800793288 /* MGLDocumentationGuideTests.swift */, DD58A4C71D822C6200E1F038 /* MGLExpressionTests.mm */, - 35C6DF861E214C1800ACA483 /* MGLDistanceFormatterTests.m */, - 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */, DA0CD58D1CF56F5800A5F5A5 /* MGLFeatureTests.mm */, DAE6C3C81CC34BD800DB3429 /* MGLGeometryTests.mm */, DA695423215B1E6C002041A4 /* MGLMapCameraTests.m */, 076171C4213A0DC200668A35 /* MGLMapViewTests.m */, + 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */, DAE7DEC31E24549F007505A6 /* MGLNSStringAdditionsTests.m */, DAE6C3C91CC34BD800DB3429 /* MGLOfflinePackTests.m */, DAE6C3CA1CC34BD800DB3429 /* MGLOfflineRegionTests.m */, 55E2AD101E5B0A6900E8C587 /* MGLOfflineStorageTests.mm */, 35C5D84B1D6DD75B00E95907 /* MGLPredicateTests.mm */, CA8FBC0C21A4A74300D1203C /* MGLRendererConfigurationTests.mm */, + CAD9D0AB22A88A32001B25EE /* MGLResourceTests.mm */, DAE6C3CC1CC34BD800DB3429 /* MGLStyleTests.mm */, 556660D51E1D07E400E2C41B /* MGLVersionNumber.m */, - DAE6C33A1CC30DB200DB3429 /* Info.plist */, - DA2784FD1DF03060001D5B8D /* Media.xcassets */, DA35D0891E1A631B007DED41 /* one-liner.json */, 1F8A59F921653483004DFE75 /* sideload_sat.db */, + DA8F257D1D51C5F40010E6B5 /* Styling */, + 4031ACFA1E9EB39A00A3EA26 /* Swift Integration */, + 4031AD001E9FD61000A3EA26 /* Test Helpers */, ); name = "SDK Tests"; path = test; @@ -1738,6 +1741,7 @@ 920A3E591E6F859D00C16EFC /* MGLSourceQueryTests.m in Sources */, DA35A2B61CCA14D700E826B2 /* MGLCompassDirectionFormatterTests.m in Sources */, 35C6DF871E214C1800ACA483 /* MGLDistanceFormatterTests.m in Sources */, + CAD9D0AC22A88A32001B25EE /* MGLResourceTests.mm in Sources */, DAE6C3D21CC34C9900DB3429 /* MGLGeometryTests.mm in Sources */, DA87A9A41DCACC5000810D09 /* MGLSymbolStyleLayerTests.mm in Sources */, 40E1601D1DF217D6005EA6D9 /* MGLStyleLayerTests.m in Sources */, -- cgit v1.2.1