summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2019-12-16 12:46:43 +0200
committerzmiao <miao.zhao@mapbox.com>2020-01-21 16:55:02 +0200
commit92e8530361cbcd1713a5f61fc892d7bd4301daae (patch)
tree6ffb0978ef0c555799f8418a848b8cfefae75cf8
parent6dc435f66465eff76e730053d80efae90fa249c5 (diff)
downloadqtlocation-mapboxgl-92e8530361cbcd1713a5f61fc892d7bd4301daae.tar.gz
[test-runner] Setup ios testrunner, can run with simulator now
-rw-r--r--next/platform/ios/ios.cmake126
-rw-r--r--platform/darwin/src/http_file_source.mm139
-rw-r--r--platform/darwin/src/native_apple_interface.m1
-rw-r--r--platform/ios/CHANGELOG.md2
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj10
-rw-r--r--platform/ios/sdk-files.json2
-rw-r--r--platform/ios/src/MGLNativeInterfaceReceiver.h8
-rw-r--r--platform/ios/src/MGLNativeInterfaceReceiver.m50
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj6
-rw-r--r--platform/macos/sdk-files.json2
-rw-r--r--platform/macos/src/MGLNativeInterfaceReceiver.h8
-rw-r--r--platform/macos/src/MGLNativeInterfaceReceiver.m40
-rw-r--r--render-test/ios-manifest.json7
-rw-r--r--render-test/ios/AppDelegate.h7
-rw-r--r--render-test/ios/AppDelegate.m38
-rw-r--r--render-test/ios/Info.plist66
-rw-r--r--render-test/ios/LaunchScreen.storyboard27
-rw-r--r--render-test/ios/Main.storyboard27
-rw-r--r--render-test/ios/Prefix.pch7
-rw-r--r--render-test/ios/ViewController.h9
-rw-r--r--render-test/ios/ViewController.m22
-rw-r--r--render-test/ios/iosTestRunner.h5
-rw-r--r--render-test/ios/iosTestRunner.mm34
-rw-r--r--render-test/ios/ios_test_runner.cpp44
-rw-r--r--render-test/ios/ios_test_runner.hpp21
-rw-r--r--render-test/ios/main.m11
26 files changed, 676 insertions, 43 deletions
diff --git a/next/platform/ios/ios.cmake b/next/platform/ios/ios.cmake
index 0de0fc1ddc..c1162eac18 100644
--- a/next/platform/ios/ios.cmake
+++ b/next/platform/ios/ios.cmake
@@ -23,6 +23,7 @@ target_sources(
${MBGL_ROOT}/platform/darwin/src/collator.mm
${MBGL_ROOT}/platform/darwin/src/gl_functions.cpp
${MBGL_ROOT}/platform/darwin/src/headless_backend_eagl.mm
+ ${MBGL_ROOT}/platform/darwin/src/native_apple_interface.m
${MBGL_ROOT}/platform/darwin/src/http_file_source.mm
${MBGL_ROOT}/platform/darwin/src/native_apple_interface.m
${MBGL_ROOT}/platform/darwin/src/image.mm
@@ -56,6 +57,8 @@ target_sources(
${MBGL_ROOT}/platform/default/src/mbgl/util/png_writer.cpp
${MBGL_ROOT}/platform/default/src/mbgl/util/thread_local.cpp
${MBGL_ROOT}/platform/default/src/mbgl/util/utf.cpp
+ ${MBGL_ROOT}/platform/default/src/mbgl/util/thread_local.cpp
+ ${MBGL_ROOT}/platform/default/src/mbgl/layermanager/layer_manager.cpp
)
target_include_directories(
@@ -90,4 +93,127 @@ target_link_libraries(
z
)
+# add_custom_command(
+# TARGET RenderTestAPP PRE_BUILD
+# COMMAND
+# ${CMAKE_COMMAND} -E
+# copy_directory
+# ${MBGL_ROOT}/mapbox-gl-js/test/integration/
+# ${MBGL_ROOT}/test-data/mapbox-gl-js/test/integration/
+# COMMAND
+# ${CMAKE_COMMAND}
+# -E
+# copy_directory
+# ${MBGL_ROOT}/vendor/mapbox-gl-styles
+# ${MBGL_ROOT}/test-data/vendor/mapbox-gl-styles
+# COMMAND
+# ${CMAKE_COMMAND}
+# -E
+# copy_directory
+# ${MBGL_ROOT}/render-test/ignores
+# ${MBGL_ROOT}/test-data/render-test/ignores
+# COMMAND
+# ${CMAKE_COMMAND}
+# -E
+# copy_directory
+# ${MBGL_ROOT}/render-test/expected
+# ${MBGL_ROOT}/test-data/render-test/expected
+# COMMAND
+# ${CMAKE_COMMAND}
+# -E
+# copy
+# ${MBGL_ROOT}/platform/node/test/ignores.json
+# ${MBGL_ROOT}test-data/platform/node/test/ignores.json
+# COMMAND
+# ${CMAKE_COMMAND}
+# -E
+# copy
+# ${MBGL_ROOT}/render-test/mac-manifest.json
+# ${MBGL_ROOT}/test-data/render-test/mac-manifest.json
+# WORKING_DIRECTORY ${MBGL_ROOT}
+# )
+
+set(
+ RESOURCES
+ ${MBGL_ROOT}/render-test/ios/Main.storyboard
+ ${MBGL_ROOT}/render-test/ios/LaunchScreen.storyboard
+ # ${MBGL_ROOT}/test-data
+ ${MBGL_ROOT}/mapbox-gl-js/test/integration
+ ${MBGL_ROOT}/vendor/mapbox-gl-styles
+ ${MBGL_ROOT}/render-test/ignores
+ ${MBGL_ROOT}/render-test/expected
+ ${MBGL_ROOT}/platform/node/test/ignores.json
+ ${MBGL_ROOT}/render-test/mac-ignores.json
+ ${MBGL_ROOT}/render-test/ios-manifest.json
+)
+
+add_executable(
+ RenderTestAPP
+ ${MBGL_ROOT}/render-test/ios/ios_test_runner.hpp
+ ${MBGL_ROOT}/render-test/ios/ios_test_runner.cpp
+ ${MBGL_ROOT}/render-test/ios/AppDelegate.h
+ ${MBGL_ROOT}/render-test/ios/AppDelegate.m
+ ${MBGL_ROOT}/render-test/ios/ViewController.h
+ ${MBGL_ROOT}/render-test/ios/ViewController.m
+ ${MBGL_ROOT}/render-test/ios/iosTestRunner.h
+ ${MBGL_ROOT}/render-test/ios/iosTestRunner.mm
+ ${MBGL_ROOT}/render-test/ios/Prefix.pch
+ ${MBGL_ROOT}/render-test/ios/main.m
+ ${RESOURCES}
+)
+
+initialize_ios_target(RenderTestAPP)
+
+set(DEPLOYMENT_TARGET 8.0)
+
+set(MACOSX_BUNDLE_INFO_STRING "com.mapbox.RenderTestAPP")
+set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.mapbox.RenderTestAPP")
+set(MACOSX_BUNDLE_BUNDLE_NAME "com.mapbox.RenderTestAPP")
+set(MACOSX_BUNDLE_ICON_FILE "")
+set(MACOSX_BUNDLE_LONG_VERSION_STRING "1.0")
+set(MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0")
+set(MACOSX_BUNDLE_BUNDLE_VERSION "1.0")
+set(MACOSX_BUNDLE_COPYRIGHT "Copyright YOU")
+set(MACOSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET})
+
+set_target_properties(
+ RenderTestAPP
+ PROPERTIES
+ MACOSX_BUNDLE
+ TRUE
+ MACOSX_BUNDLE_IDENTIFIER
+ com.mapbox.RenderTestAPP
+ MACOSX_BUNDLE_INFO_PLIST
+ ${MBGL_ROOT}/render-test/ios/Info.plist
+ RESOURCE
+ "${RESOURCES}"
+)
+
+target_include_directories(
+ RenderTestAPP
+ PUBLIC {MBGL_ROOT}/render-test/include ${MBGL_ROOT}/include
+)
+
+target_include_directories(
+ RenderTestAPP
+ PRIVATE
+ ${MBGL_ROOT}/platform/darwin/src
+ ${MBGL_ROOT}/platform/darwin/include
+ ${MBGL_ROOT}/platform/darwin/include/mbgl/interface/
+ ${MBGL_ROOT}/platform/default/include
+ ${MBGL_ROOT}/src
+)
+
+target_link_libraries(
+ RenderTestAPP
+ PRIVATE
+ "-framework CoreGraphics"
+ "-framework CoreLocation"
+ "-framework Foundation"
+ "-framework OpenGLES"
+ "-framework QuartzCore"
+ "-framework UIKit"
+ mbgl-render-test
+)
+
unset(IOS_DEPLOYMENT_TARGET CACHE)
diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm
index a72a97e299..0abae701d7 100644
--- a/platform/darwin/src/http_file_source.mm
+++ b/platform/darwin/src/http_file_source.mm
@@ -26,10 +26,10 @@ namespace mbgl {
class HTTPRequestShared {
public:
HTTPRequestShared(Response& response_, util::AsyncTask& async_)
- : response(response_),
- async(async_) {
+ : response(response_),
+ async(async_) {
}
-
+
void notify(const Response& response_) {
std::lock_guard<std::mutex> lock(mutex);
if (!cancelled) {
@@ -37,16 +37,16 @@ public:
async.send();
}
}
-
+
void cancel() {
std::lock_guard<std::mutex> lock(mutex);
cancelled = true;
}
-
+
private:
std::mutex mutex;
bool cancelled = false;
-
+
Response& response;
util::AsyncTask& async;
};
@@ -54,24 +54,24 @@ private:
class HTTPRequest : public AsyncRequest {
public:
HTTPRequest(FileSource::Callback callback_)
- : shared(std::make_shared<HTTPRequestShared>(response, async)),
- callback(callback_) {
+ : shared(std::make_shared<HTTPRequestShared>(response, async)),
+ callback(callback_) {
}
-
+
~HTTPRequest() override {
shared->cancel();
if (task) {
[task cancel];
}
}
-
+
std::shared_ptr<HTTPRequestShared> shared;
NSURLSessionDataTask* task = nil;
-
+
private:
FileSource::Callback callback;
Response response;
-
+
util::AsyncTask async { [this] {
// Calling `callback` may result in deleting `this`. Copy data to temporaries first.
auto callback_ = callback;
@@ -86,15 +86,15 @@ public:
@autoreleasepool {
NSURLSessionConfiguration *sessionConfig = MGLNativeNetworkManager.sharedManager.sessionConfiguration;
session = [NSURLSession sessionWithConfiguration:sessionConfig];
-
+
userAgent = getUserAgent();
}
}
-
+
NSURLSession* session = nil;
NSString* userAgent = nil;
NSInteger accountType = 0;
-
+
private:
NSString* getUserAgent() const;
NSBundle* getSDKBundle() const;
@@ -102,7 +102,7 @@ private:
NSString *HTTPFileSource::Impl::getUserAgent() const {
NSMutableArray *userAgentComponents = [NSMutableArray array];
-
+
NSBundle *appBundle = [NSBundle mainBundle];
if (appBundle) {
NSString *appName = appBundle.infoDictionary[@"CFBundleName"];
@@ -112,7 +112,7 @@ NSString *HTTPFileSource::Impl::getUserAgent() const {
} else {
[userAgentComponents addObject:[NSProcessInfo processInfo].processName];
}
-
+
NSBundle *sdkBundle = HTTPFileSource::Impl::getSDKBundle();
if (sdkBundle) {
NSString *versionString = sdkBundle.infoDictionary[@"MGLSemanticVersionString"];
@@ -124,12 +124,12 @@ NSString *HTTPFileSource::Impl::getUserAgent() const {
sdkBundle.infoDictionary[@"CFBundleName"], versionString]];
}
}
-
+
// Avoid %s here because it inserts hidden bidirectional markers on macOS when the system
// language is set to a right-to-left language.
[userAgentComponents addObject:[NSString stringWithFormat:@"MapboxGL/0.0.0 (%@)",
@(mbgl::version::revision)]];
-
+
NSString *systemName = @"Darwin";
#if TARGET_OS_IPHONE
systemName = @"iOS";
@@ -152,7 +152,7 @@ NSString *HTTPFileSource::Impl::getUserAgent() const {
if (systemVersion) {
[userAgentComponents addObject:[NSString stringWithFormat:@"%@/%@", systemName, systemVersion]];
}
-
+
NSString *cpu = nil;
#if TARGET_CPU_X86
cpu = @"x86";
@@ -166,7 +166,7 @@ NSString *HTTPFileSource::Impl::getUserAgent() const {
if (cpu) {
[userAgentComponents addObject:[NSString stringWithFormat:@"(%@)", cpu]];
}
-
+
return [userAgentComponents componentsJoinedByString:@" "];
}
@@ -182,7 +182,7 @@ NSBundle *HTTPFileSource::Impl::getSDKBundle() const {
}
HTTPFileSource::HTTPFileSource()
- : impl(std::make_unique<Impl>()) {
+: impl(std::make_unique<Impl>()) {
}
HTTPFileSource::~HTTPFileSource() = default;
@@ -204,7 +204,7 @@ NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountTyp
if (accountType == 0 && isValidMapboxEndpoint(url)) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
NSMutableArray *queryItems = [NSMutableArray array];
-
+
if (resource.usage == Resource::Usage::Offline) {
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"offline" value:@"true"]];
} else {
@@ -224,11 +224,11 @@ NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountTyp
#endif
return url;
}
-
+
std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, Callback callback) {
auto request = std::make_unique<HTTPRequest>(callback);
auto shared = request->shared; // Explicit copy so that it also gets copied into the completion handler block below.
-
+
@autoreleasepool {
NSURL *url = resourceURLWithAccountType(resource, impl->accountType);
[MGLNativeNetworkManager.sharedManager debugLog:@"Requesting URI: %@", url.relativePath];
@@ -236,16 +236,16 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
if (resource.priorEtag) {
[req addValue:@(resource.priorEtag->c_str())
- forHTTPHeaderField:@"If-None-Match"];
+ forHTTPHeaderField:@"If-None-Match"];
} else if (resource.priorModified) {
[req addValue:@(util::rfc1123(*resource.priorModified).c_str())
- forHTTPHeaderField:@"If-Modified-Since"];
+ forHTTPHeaderField:@"If-Modified-Since"];
}
-
+
[req addValue:impl->userAgent forHTTPHeaderField:@"User-Agent"];
-
+
const bool isTile = resource.kind == mbgl::Resource::Kind::Tile;
-
+
if (isTile) {
[MGLNativeNetworkManager.sharedManager startDownloadEvent:url.relativePath type:@"tile"];
}
@@ -272,9 +272,9 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
switch ([error code]) {
case NSURLErrorBadServerResponse: // 5xx errors
response.error = std::make_unique<Error>(
- Error::Reason::Server, [[error localizedDescription] UTF8String]);
+ Error::Reason::Server, [[error localizedDescription] UTF8String]);
break;
-
+
case NSURLErrorNetworkConnectionLost:
case NSURLErrorCannotFindHost:
case NSURLErrorCannotConnectToHost:
@@ -285,13 +285,55 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
case NSURLErrorDataNotAllowed:
case NSURLErrorTimedOut:
response.error = std::make_unique<Error>(
- Error::Reason::Connection, [[error localizedDescription] UTF8String]);
+ Error::Reason::Connection, [[error localizedDescription] UTF8String]);
break;
-
+
default:
response.error = std::make_unique<Error>(
- Error::Reason::Other, [[error localizedDescription] UTF8String]);
+ Error::Reason::Other, [[error localizedDescription] UTF8String]);
break;
+ }
+ } else if ([res isKindOfClass:[NSHTTPURLResponse class]]) {
+ const long responseCode = [(NSHTTPURLResponse *)res statusCode];
+
+ NSDictionary *headers = [(NSHTTPURLResponse *)res allHeaderFields];
+ NSString *cache_control = [headers objectForKey:@"Cache-Control"];
+ if (cache_control) {
+ const auto cc = http::CacheControl::parse([cache_control UTF8String]);
+ response.expires = cc.toTimePoint();
+ response.mustRevalidate = cc.mustRevalidate;
+ }
+
+ NSString *expires = [headers objectForKey:@"Expires"];
+ if (expires) {
+ response.expires = util::parseTimestamp([expires UTF8String]);
+ }
+
+ NSString *last_modified = [headers objectForKey:@"Last-Modified"];
+ if (last_modified) {
+ response.modified = util::parseTimestamp([last_modified UTF8String]);
+ }
+
+ NSString *etag = [headers objectForKey:@"ETag"];
+ if (etag) {
+ response.etag = std::string([etag UTF8String]);
+ }
+
+ if (responseCode == 200) {
+ response.data = std::make_shared<std::string>((const char *)[data bytes], [data length]);
+ } else if (responseCode == 204 || (responseCode == 404 && isTile)) {
+ response.noContent = true;
+ } else if (responseCode == 304) {
+ response.notModified = true;
+ } else if (responseCode == 404) {
+ response.error =
+ std::make_unique<Error>(Error::Reason::NotFound, "HTTP status code 404");
+ } else if (responseCode == 429) {
+ // Get the standard header
+ optional<std::string> retryAfter;
+ NSString *retryAfterHeader = headers[@"Retry-After"];
+ if (retryAfterHeader) {
+ retryAfter = std::string([retryAfterHeader UTF8String]);
}
} else if ([res isKindOfClass:[NSHTTPURLResponse class]]) {
const long responseCode = [(NSHTTPURLResponse *)res statusCode];
@@ -354,18 +396,29 @@ std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource,
std::make_unique<Error>(Error::Reason::Other, std::string{ "HTTP status code " } +
std::to_string(responseCode));
}
+
+ response.error = std::make_unique<Error>(Error::Reason::RateLimit, "HTTP status code 429", http::parseRetryHeaders(retryAfter, xRateLimitReset));
+ } else if (responseCode >= 500 && responseCode < 600) {
+ response.error =
+ std::make_unique<Error>(Error::Reason::Server, std::string{ "HTTP status code " } +
+ std::to_string(responseCode));
} else {
- // This should never happen.
- response.error = std::make_unique<Error>(Error::Reason::Other,
- "Response class is not NSHTTPURLResponse");
+ response.error =
+ std::make_unique<Error>(Error::Reason::Other, std::string{ "HTTP status code " } +
+ std::to_string(responseCode));
}
-
- shared->notify(response);
- }];
-
+ } else {
+ // This should never happen.
+ response.error = std::make_unique<Error>(Error::Reason::Other,
+ "Response class is not NSHTTPURLResponse");
+ }
+
+ shared->notify(response);
+ }];
+
[request->task resume];
}
-
+
return std::move(request);
}
diff --git a/platform/darwin/src/native_apple_interface.m b/platform/darwin/src/native_apple_interface.m
index 07dce0d5b0..82ec4aa390 100644
--- a/platform/darwin/src/native_apple_interface.m
+++ b/platform/darwin/src/native_apple_interface.m
@@ -53,6 +53,7 @@ static MGLNativeNetworkManager *instance = nil;
}
- (void)stopDownloadEventForResponse:(NSURLResponse *)response {
+
if (_delegate && [_delegate respondsToSelector:@selector(stopDownloadEventForResponse:)]) {
return [_delegate stopDownloadEventForResponse:response];
}
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index fcb581a0e0..f1eeef17a4 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -6,8 +6,10 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Added support for [image expression](https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-image) in core library. Runtime APIs for image expression will be implemented separately. ([#15877](https://github.com/mapbox/mapbox-gl-native/pull/15877))
* Make network requests for expired resources lower priority than requests for new resources. ([#15950](https://github.com/mapbox/mapbox-gl-native/pull/15950))
+
### Other changes
* Convert GeoJSON features to tiles for the loaded source description in a background thread and thus unblock the UI thread ([#15885](https://github.com/mapbox/mapbox-gl-native/pull/15885))
+* Separate platform codes from native codes. ([#16031](https://github.com/mapbox/mapbox-gl-native/pull/16031))
### Bug fixes
* Fixed the rendering bug caused by redundant pending requests for already requested images [#15864](https://github.com/mapbox/mapbox-gl-native/pull/15864)
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 4db9409081..5e1e311496 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -532,6 +532,10 @@
CAE7AD5520F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */; };
CAFB3C14234505D500399265 /* MGLMapSnapshotter_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CAFB3C13234505D500399265 /* MGLMapSnapshotter_Private.h */; };
CAFB3C15234505D500399265 /* MGLMapSnapshotter_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CAFB3C13234505D500399265 /* MGLMapSnapshotter_Private.h */; };
+ CF0E9076239EA6950074A30D /* MGLNativeInterfaceReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = CF0E9074239EA6950074A30D /* MGLNativeInterfaceReceiver.h */; };
+ CF0E9077239EA6950074A30D /* MGLNativeInterfaceReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = CF0E9074239EA6950074A30D /* MGLNativeInterfaceReceiver.h */; };
+ CF0E9078239EA6950074A30D /* MGLNativeInterfaceReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0E9075239EA6950074A30D /* MGLNativeInterfaceReceiver.m */; };
+ CF0E9079239EA6950074A30D /* MGLNativeInterfaceReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0E9075239EA6950074A30D /* MGLNativeInterfaceReceiver.m */; };
CF75A91522D85E860058A5C4 /* MGLLoggingConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */; };
CF75A91622D85E860058A5C4 /* MGLLoggingConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */; };
CFF9F98623A24BF500B0DE92 /* MGLNetworkIntegrationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CFF9F98423A24BF400B0DE92 /* MGLNetworkIntegrationManager.h */; };
@@ -1229,6 +1233,8 @@
CAE7AD5320F46EF5003B6782 /* integration-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "integration-Bridging-Header.h"; sourceTree = "<group>"; };
CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MGLMapSnapshotterSwiftTests.swift; sourceTree = "<group>"; };
CAFB3C13234505D500399265 /* MGLMapSnapshotter_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapSnapshotter_Private.h; sourceTree = "<group>"; };
+ CF0E9074239EA6950074A30D /* MGLNativeInterfaceReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNativeInterfaceReceiver.h; sourceTree = "<group>"; };
+ CF0E9075239EA6950074A30D /* MGLNativeInterfaceReceiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNativeInterfaceReceiver.m; sourceTree = "<group>"; };
CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLoggingConfiguration.mm; sourceTree = "<group>"; };
CFF9F98423A24BF400B0DE92 /* MGLNetworkIntegrationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLNetworkIntegrationManager.h; path = ../../darwin/src/MGLNetworkIntegrationManager.h; sourceTree = "<group>"; };
CFF9F98523A24BF400B0DE92 /* MGLNetworkIntegrationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLNetworkIntegrationManager.m; path = ../../darwin/src/MGLNetworkIntegrationManager.m; sourceTree = "<group>"; };
@@ -2634,6 +2640,7 @@
350098BB1D480108004B2AF0 /* MGLVectorTileSource.h in Headers */,
DA8847F61CBAFA5100AB86E3 /* MGLOfflineStorage.h in Headers */,
DAD1656E1CF41981001FF4B9 /* MGLFeature_Private.h in Headers */,
+ CF0E9076239EA6950074A30D /* MGLNativeInterfaceReceiver.h in Headers */,
DA88483C1CBAFB8500AB86E3 /* MGLMapView.h in Headers */,
3EA9363147E77DD29FA06063 /* MGLRendererConfiguration.h in Headers */,
55E5665121C2A1C20008B8B5 /* MMEReachability.h in Headers */,
@@ -2829,6 +2836,7 @@
74CB5EB2219B252C00102936 /* MGLStyleLayerManager.h in Headers */,
9221BAB020699F8A0054BDF4 /* MGLTilePyramidOfflineRegion_Private.h in Headers */,
96E516F5200059B100A02306 /* MGLNetworkConfiguration.h in Headers */,
+ CF0E9077239EA6950074A30D /* MGLNativeInterfaceReceiver.h in Headers */,
96E516DD200054F200A02306 /* MGLPolygon_Private.h in Headers */,
353933F91D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
9C6E282622A980AC0056B7BE /* UIKit+MMEMobileEvents.h in Headers */,
@@ -3373,6 +3381,7 @@
9620BB3A1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */,
354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */,
40834BEE1FE05E1800C1BD0D /* MMEEventsConfiguration.m in Sources */,
+ CF0E9078239EA6950074A30D /* MGLNativeInterfaceReceiver.m in Sources */,
DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */,
DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */,
30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
@@ -3501,6 +3510,7 @@
DAA4E4221CBB730400178DFB /* MGLPointAnnotation.mm in Sources */,
40834C021FE05E1800C1BD0D /* MMEEventsConfiguration.m in Sources */,
DAED38661D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */,
+ CF0E9079239EA6950074A30D /* MGLNativeInterfaceReceiver.m in Sources */,
DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */,
30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
ACD0245B2187EABA00D8C8A7 /* MMEMetricsManager.m in Sources */,
diff --git a/platform/ios/sdk-files.json b/platform/ios/sdk-files.json
index 47dacb7cce..45cc0088f1 100644
--- a/platform/ios/sdk-files.json
+++ b/platform/ios/sdk-files.json
@@ -9,6 +9,7 @@
"platform/ios/src/MGLSDKUpdateChecker.mm",
"platform/ios/src/MGLUserLocationAnnotationView.m",
"platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/MMEEventsConfiguration.m",
+ "platform/ios/src/MGLNativeInterfaceReceiver.m",
"platform/ios/src/MGLFaux3DUserLocationAnnotationView.m",
"platform/darwin/src/MGLFeature.mm",
"platform/ios/src/UIImage+MGLAdditions.mm",
@@ -286,6 +287,7 @@
"MGLUserLocationAnnotationView_Private.h": "platform/ios/src/MGLUserLocationAnnotationView_Private.h",
"MGLRasterTileSource_Private.h": "platform/darwin/src/MGLRasterTileSource_Private.h",
"MGLFeature_Private.h": "platform/darwin/src/MGLFeature_Private.h",
+ "MGLNativeInterfaceReceiver.h": "platform/ios/src/MGLNativeInterfaceReceiver.h",
"MGLRendererConfiguration.h": "platform/darwin/src/MGLRendererConfiguration.h",
"MMEReachability.h": "platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/Reachability/MMEReachability.h",
"MMENamespacedDependencies.h": "platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/MMENamespacedDependencies.h",
diff --git a/platform/ios/src/MGLNativeInterfaceReceiver.h b/platform/ios/src/MGLNativeInterfaceReceiver.h
new file mode 100644
index 0000000000..367adf9f3f
--- /dev/null
+++ b/platform/ios/src/MGLNativeInterfaceReceiver.h
@@ -0,0 +1,8 @@
+#import <Foundation/Foundation.h>
+#include <mbgl/interface/native_apple_interface.h>
+
+@interface MGLNativeInterfaceReceiver : NSObject <MGLNativeAppleInterfaceDelegate>
+
++ (MGLNativeInterfaceReceiver *)shared;
+
+@end
diff --git a/platform/ios/src/MGLNativeInterfaceReceiver.m b/platform/ios/src/MGLNativeInterfaceReceiver.m
new file mode 100644
index 0000000000..a703c55d38
--- /dev/null
+++ b/platform/ios/src/MGLNativeInterfaceReceiver.m
@@ -0,0 +1,50 @@
+#import "MGLNativeInterfaceReceiver.h"
+
+#import "MGLLoggingConfiguration_Private.h"
+#import "MGLNetworkConfiguration_Private.h"
+
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+#import "MGLAccountManager_Private.h"
+#endif
+
+@implementation MGLNativeInterfaceReceiver
+
+static MGLNativeInterfaceReceiver *instance = nil;
+
++ (MGLNativeInterfaceReceiver *)shared {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ instance = [[MGLNativeInterfaceReceiver alloc] init];
+ });
+ return instance;
+}
+
+#pragma mark - MGLNativeAppleInterfaceManager delegate -
+
+- (NSURLSessionConfiguration *)nai_sessionConfiguration {
+ return [MGLNetworkConfiguration sharedManager].sessionConfiguration;
+}
+
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+- (NSString *)nai_accountTypeKey {
+ return MGLMapboxAccountTypeKey;
+}
+
+- (NSString *)nai_skuToken {
+ return MGLAccountManager.skuToken;
+}
+#endif
+
+- (void)nai_startDownloadEvent:(NSString *)event type:(NSString *)type {
+ [[MGLNetworkConfiguration sharedManager] startDownloadEvent:event type:@"tile"];
+}
+
+- (void)nai_cancelDownloadEventForResponse:(NSURLResponse *)response {
+ [[MGLNetworkConfiguration sharedManager] cancelDownloadEventForResponse:response];
+}
+
+- (void)nai_stopDownloadEventForResponse:(NSURLResponse *)response {
+ [[MGLNetworkConfiguration sharedManager] stopDownloadEventForResponse:response];
+}
+
+@end
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 7dcd72b47d..a10ae16e9c 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -134,6 +134,8 @@
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 */; };
+ CF0E907E239EA6BB0074A30D /* MGLNativeInterfaceReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = CF0E907C239EA6BB0074A30D /* MGLNativeInterfaceReceiver.h */; };
+ CF0E907F239EA6BB0074A30D /* MGLNativeInterfaceReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0E907D239EA6BB0074A30D /* MGLNativeInterfaceReceiver.m */; };
CF762DEF22DC7EFF00338472 /* MGLLoggingConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF762DEE22DC7EFF00338472 /* MGLLoggingConfiguration.mm */; };
CFF9F98D23A2505700B0DE92 /* MGLNetworkIntegrationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CFF9F98B23A2505700B0DE92 /* MGLNetworkIntegrationManager.m */; };
CFF9F98E23A2505700B0DE92 /* MGLNetworkIntegrationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CFF9F98C23A2505700B0DE92 /* MGLNetworkIntegrationManager.h */; };
@@ -477,6 +479,8 @@
CA8FBC0C21A4A74300D1203C /* MGLRendererConfigurationTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLRendererConfigurationTests.mm; path = ../../darwin/test/MGLRendererConfigurationTests.mm; sourceTree = "<group>"; };
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 = "<group>"; };
+ CF0E907C239EA6BB0074A30D /* MGLNativeInterfaceReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNativeInterfaceReceiver.h; sourceTree = "<group>"; };
+ CF0E907D239EA6BB0074A30D /* MGLNativeInterfaceReceiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNativeInterfaceReceiver.m; sourceTree = "<group>"; };
CF762DEE22DC7EFF00338472 /* MGLLoggingConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLoggingConfiguration.mm; sourceTree = "<group>"; };
CFF9F98B23A2505700B0DE92 /* MGLNetworkIntegrationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLNetworkIntegrationManager.m; path = ../../darwin/src/MGLNetworkIntegrationManager.m; sourceTree = "<group>"; };
CFF9F98C23A2505700B0DE92 /* MGLNetworkIntegrationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLNetworkIntegrationManager.h; path = ../../darwin/src/MGLNetworkIntegrationManager.h; sourceTree = "<group>"; };
@@ -1421,6 +1425,7 @@
3538AA231D542685008EC33D /* MGLStyleLayer.h in Headers */,
DAE6C35C1CC31E0400DB3429 /* MGLGeometry.h in Headers */,
DAE6C35A1CC31E0400DB3429 /* MGLAccountManager.h in Headers */,
+ CF0E907E239EA6BB0074A30D /* MGLNativeInterfaceReceiver.h in Headers */,
DA551B821DB496AC0009AFAF /* MGLTileSource.h in Headers */,
35602C001D3EA9B40050646F /* MGLForegroundStyleLayer.h in Headers */,
DAE6C35D1CC31E0400DB3429 /* MGLMapCamera.h in Headers */,
@@ -1669,6 +1674,7 @@
files = (
07A019EF1ED665CD00ACD43E /* MGLImageSource.mm in Sources */,
92092EF11F5EB10E00AF5130 /* MGLMapSnapshotter.mm in Sources */,
+ CF0E907F239EA6BB0074A30D /* MGLNativeInterfaceReceiver.m in Sources */,
40ABDB561DB0022100372083 /* NSImage+MGLAdditions.mm in Sources */,
DAF25715201901C200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */,
DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.mm in Sources */,
diff --git a/platform/macos/sdk-files.json b/platform/macos/sdk-files.json
index 65b946cd06..d24b7c3fa7 100644
--- a/platform/macos/sdk-files.json
+++ b/platform/macos/sdk-files.json
@@ -3,6 +3,7 @@
"sources": [
"platform/darwin/src/MGLImageSource.mm",
"platform/darwin/src/MGLMapSnapshotter.mm",
+ "platform/macos/src/MGLNativeInterfaceReceiver.m",
"platform/macos/src/NSImage+MGLAdditions.mm",
"platform/darwin/src/MGLHillshadeStyleLayer.mm",
"platform/darwin/src/MGLPointAnnotation.mm",
@@ -195,6 +196,7 @@
"MGLValueEvaluator.h": "platform/darwin/src/MGLValueEvaluator.h",
"MGLOfflinePack_Private.h": "platform/darwin/src/MGLOfflinePack_Private.h",
"MGLFoundation_Private.h": "platform/darwin/src/MGLFoundation_Private.h",
+ "MGLNativeInterfaceReceiver.h": "platform/macos/src/MGLNativeInterfaceReceiver.h",
"MGLCompassCell.h": "platform/macos/src/MGLCompassCell.h",
"MGLShapeSource_Private.h": "platform/darwin/src/MGLShapeSource_Private.h",
"MGLStyle_Private.h": "platform/darwin/src/MGLStyle_Private.h",
diff --git a/platform/macos/src/MGLNativeInterfaceReceiver.h b/platform/macos/src/MGLNativeInterfaceReceiver.h
new file mode 100644
index 0000000000..367adf9f3f
--- /dev/null
+++ b/platform/macos/src/MGLNativeInterfaceReceiver.h
@@ -0,0 +1,8 @@
+#import <Foundation/Foundation.h>
+#include <mbgl/interface/native_apple_interface.h>
+
+@interface MGLNativeInterfaceReceiver : NSObject <MGLNativeAppleInterfaceDelegate>
+
++ (MGLNativeInterfaceReceiver *)shared;
+
+@end
diff --git a/platform/macos/src/MGLNativeInterfaceReceiver.m b/platform/macos/src/MGLNativeInterfaceReceiver.m
new file mode 100644
index 0000000000..c9ee9ca6d7
--- /dev/null
+++ b/platform/macos/src/MGLNativeInterfaceReceiver.m
@@ -0,0 +1,40 @@
+#import "MGLNativeInterfaceReceiver.h"
+
+#import "MGLLoggingConfiguration_Private.h"
+#import "MGLNetworkConfiguration_Private.h"
+
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+#import "MGLAccountManager_Private.h"
+#endif
+
+@implementation MGLNativeInterfaceReceiver
+
+static MGLNativeInterfaceReceiver *instance = nil;
+
++ (MGLNativeInterfaceReceiver *)shared {
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ instance = [[MGLNativeInterfaceReceiver alloc] init];
+ });
+ return instance;
+}
+
+#pragma mark - MGLNativeAppleInterfaceManager delegate -
+
+- (NSURLSessionConfiguration *)nai_sessionConfiguration {
+ return [MGLNetworkConfiguration sharedManager].sessionConfiguration;
+}
+
+- (void)nai_startDownloadEvent:(NSString *)event type:(NSString *)type {
+ [[MGLNetworkConfiguration sharedManager] startDownloadEvent:event type:@"tile"];
+}
+
+- (void)nai_cancelDownloadEventForResponse:(NSURLResponse *)response {
+ [[MGLNetworkConfiguration sharedManager] cancelDownloadEventForResponse:response];
+}
+
+- (void)nai_stopDownloadEventForResponse:(NSURLResponse *)response {
+ [[MGLNetworkConfiguration sharedManager] stopDownloadEventForResponse:response];
+}
+
+@end
diff --git a/render-test/ios-manifest.json b/render-test/ios-manifest.json
new file mode 100644
index 0000000000..7eb03a3253
--- /dev/null
+++ b/render-test/ios-manifest.json
@@ -0,0 +1,7 @@
+{
+ "base_test_path":"integration",
+ "expectation_paths":["expected/"],
+ "ignore_paths":["ignores.json", "mac-ignores.json"],
+ "vendor_path":"mapbox-gl-styles",
+ "asset_path": "integration"
+}
diff --git a/render-test/ios/AppDelegate.h b/render-test/ios/AppDelegate.h
new file mode 100644
index 0000000000..134c8063dc
--- /dev/null
+++ b/render-test/ios/AppDelegate.h
@@ -0,0 +1,7 @@
+#import <UIKit/UIApplication.h> // UIApplicationDelegate
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end \ No newline at end of file
diff --git a/render-test/ios/AppDelegate.m b/render-test/ios/AppDelegate.m
new file mode 100644
index 0000000000..d86c1ce7ae
--- /dev/null
+++ b/render-test/ios/AppDelegate.m
@@ -0,0 +1,38 @@
+#import "AppDelegate.h"
+
+@interface AppDelegate()
+
+@end
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Insert code here to initialize your application
+ NSLog(@"didFinishLaunchingWithOptions");
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+ // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+ // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+
+@end \ No newline at end of file
diff --git a/render-test/ios/Info.plist b/render-test/ios/Info.plist
new file mode 100644
index 0000000000..74d7179bde
--- /dev/null
+++ b/render-test/ios/Info.plist
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleExecutable</key>
+ <string>RenderTestAPP</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.mapbox.render</string>
+ <key>CFBundleGetInfoString</key>
+ <string>${MACOSX_BUNDLE_INFO_STRING}</string>
+ <key>CFBundleIconFile</key>
+ <string>${MACOSX_BUNDLE_ICON_FILE}</string>
+ <key>CFBundleIdentifier</key>
+ <string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>1.0</string>
+ <key>CFBundleLongVersionString</key>
+ <string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
+ <key>CFBundleName</key>
+ <string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>7877</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${MACOSX_DEPLOYMENT_TARGET}</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIBackgroundModes</key>
+ <array>
+ <string>fetch</string>
+ <string>remote-notification</string>
+ </array>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>NSAppTransportSecurity</key>
+ <dict>
+ <key>NSAllowsArbitraryLoads</key>
+ <true/>
+ </dict>
+</dict>
+</plist> \ No newline at end of file
diff --git a/render-test/ios/LaunchScreen.storyboard b/render-test/ios/LaunchScreen.storyboard
new file mode 100644
index 0000000000..c9b7564332
--- /dev/null
+++ b/render-test/ios/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9531" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9529"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="53" y="375"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/render-test/ios/Main.storyboard b/render-test/ios/Main.storyboard
new file mode 100644
index 0000000000..34d4c7e2ec
--- /dev/null
+++ b/render-test/ios/Main.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <animations/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/render-test/ios/Prefix.pch b/render-test/ios/Prefix.pch
new file mode 100644
index 0000000000..b717e4a446
--- /dev/null
+++ b/render-test/ios/Prefix.pch
@@ -0,0 +1,7 @@
+#import <Availability.h>
+
+#ifdef __OBJC__
+ #import <UIKit/UIKit.h>
+ #import <Foundation/Foundation.h>
+#endif
+
diff --git a/render-test/ios/ViewController.h b/render-test/ios/ViewController.h
new file mode 100644
index 0000000000..40ea147a8a
--- /dev/null
+++ b/render-test/ios/ViewController.h
@@ -0,0 +1,9 @@
+// ViewController.h
+// Your main view controller
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+@end
+
diff --git a/render-test/ios/ViewController.m b/render-test/ios/ViewController.m
new file mode 100644
index 0000000000..892ada7231
--- /dev/null
+++ b/render-test/ios/ViewController.m
@@ -0,0 +1,22 @@
+#import "ViewController.h"
+#import "iosTestRunner.h"
+
+@interface ViewController ()
+{
+ IosTestRunner* i;
+}
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ i = [[IosTestRunner alloc]init];
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/render-test/ios/iosTestRunner.h b/render-test/ios/iosTestRunner.h
new file mode 100644
index 0000000000..768a20a91e
--- /dev/null
+++ b/render-test/ios/iosTestRunner.h
@@ -0,0 +1,5 @@
+#import <Foundation/Foundation.h>
+
+@interface IosTestRunner : NSObject
+
+@end
diff --git a/render-test/ios/iosTestRunner.mm b/render-test/ios/iosTestRunner.mm
new file mode 100644
index 0000000000..9326602bef
--- /dev/null
+++ b/render-test/ios/iosTestRunner.mm
@@ -0,0 +1,34 @@
+#import "iosTestRunner.h"
+
+#import "ios_test_runner.hpp"
+
+#include <string>
+
+@interface IosTestRunner ()
+{
+ TestRunner* runner;
+}
+@end
+
+@implementation IosTestRunner
+
+-(instancetype)init
+{
+ self = [super init];
+ if (self) {
+ runner = new TestRunner();
+ NSString *path = [[NSBundle mainBundle] pathForResource:@"mac-manifest" ofType:@"json"];
+
+// NSString * path1 = [[NSBundle mainBundle] pathForResource:@"package-lock" ofType:@"json" inDirectory:@"integration"];
+ NSString *path1 = [[NSBundle mainBundle] bundlePath];
+ (void)path1;
+// NSURL *url = [NSURL fileURLWithPath:path];
+ std::string manifest = std::string([path UTF8String]);
+ runner->startTest(manifest);
+ delete runner;
+ runner = nullptr;
+ }
+ return self;
+}
+
+@end
diff --git a/render-test/ios/ios_test_runner.cpp b/render-test/ios/ios_test_runner.cpp
new file mode 100644
index 0000000000..f2184fdf72
--- /dev/null
+++ b/render-test/ios/ios_test_runner.cpp
@@ -0,0 +1,44 @@
+//
+// ios_test_runner.cpp
+// RenderTestAPP
+//
+// Created by Miao Zhao on 12/11/19.
+//
+
+#include "ios_test_runner.hpp"
+
+#include <mbgl/render_test.hpp>
+
+#include <mbgl/util/logging.hpp>
+
+#include <vector>
+
+void TestRunner::startTest(const std::string& manifest) {
+
+ auto runTestWithManifest = [](const std::string& manifest) -> bool {
+ std::vector<std::string> arguments = {"mbgl-render-test-runner", "-p", manifest};
+ std::vector<char*> argv;
+ for (const auto& arg : arguments) {
+ argv.push_back(const_cast<char*>(arg.data()));
+ }
+ argv.push_back(nullptr);
+
+ int finishedTestCount = 0;
+ std::function<void()> testStatus = [&]() {
+ mbgl::Log::Info(mbgl::Event::General, "Current finished tests number is '%d' ", ++finishedTestCount);
+ };
+ mbgl::Log::Info(
+ mbgl::Event::General, "Start running RenderTestRunner with manifest: '%s'", manifest.c_str());
+
+ auto result = mbgl::runRenderTests(static_cast<int>(argv.size() - 1), argv.data(), testStatus) == 0;
+ mbgl::Log::Info(mbgl::Event::General, "End running RenderTestRunner with manifest: '%s'", manifest.c_str());
+ return result;
+ };
+
+ try {
+ runTestWithManifest(manifest);}
+ catch(...){
+ mbgl::Log::Info(mbgl::Event::General, "testFailed");
+ }
+ mbgl::Log::Info(mbgl::Event::General, "All tests are finished!");
+}
diff --git a/render-test/ios/ios_test_runner.hpp b/render-test/ios/ios_test_runner.hpp
new file mode 100644
index 0000000000..8d721a4eeb
--- /dev/null
+++ b/render-test/ios/ios_test_runner.hpp
@@ -0,0 +1,21 @@
+//
+// ios_test_runner.hpp
+// RenderTestAPP
+//
+// Created by Miao Zhao on 12/11/19.
+//
+
+#ifndef ios_test_runner_hpp
+#define ios_test_runner_hpp
+
+#include <string>
+
+class TestRunner {
+public:
+ TestRunner()=default;
+ ~TestRunner() =default;
+
+ void startTest(const std::string& manifest);
+};
+
+#endif /* ios_test_runner_hpp */
diff --git a/render-test/ios/main.m b/render-test/ios/main.m
new file mode 100644
index 0000000000..9aa3af5003
--- /dev/null
+++ b/render-test/ios/main.m
@@ -0,0 +1,11 @@
+// UIApplicationMain()
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char * argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+} \ No newline at end of file