summaryrefslogtreecommitdiff
path: root/ios/app
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2015-02-09 18:01:40 -0800
committerJustin R. Miller <incanus@codesorcery.net>2015-02-09 18:01:40 -0800
commitd4d4cd44151423d374e373798f09d12157babc27 (patch)
treeede100edc58475b969b62fba8f3bcb219b29beda /ios/app
parent0ee6044ccf49bb32a25c57ce25af15bcd58ca77b (diff)
downloadqtlocation-mapboxgl-d4d4cd44151423d374e373798f09d12157babc27.tar.gz
move iOS code from gl-cocoa to this project
Diffstat (limited to 'ios/app')
-rw-r--r--ios/app/MBXAppDelegate.h7
-rw-r--r--ios/app/MBXAppDelegate.m15
-rw-r--r--ios/app/MBXViewController.h5
-rw-r--r--ios/app/MBXViewController.mm266
-rw-r--r--ios/app/README.md3
-rw-r--r--ios/app/app-info.plist51
-rw-r--r--ios/app/img/Default-568h@2x.pngbin0 -> 2239 bytes
-rw-r--r--ios/app/img/Default-667h@2x.pngbin0 -> 2797 bytes
-rw-r--r--ios/app/img/Icon-40.pngbin0 -> 951 bytes
-rw-r--r--ios/app/img/Icon-40@2x.pngbin0 -> 1528 bytes
-rw-r--r--ios/app/img/Icon-60.pngbin0 -> 1313 bytes
-rw-r--r--ios/app/img/Icon-60@2x.pngbin0 -> 2091 bytes
-rw-r--r--ios/app/img/Icon-72.pngbin0 -> 1418 bytes
-rw-r--r--ios/app/img/Icon-72@2x.pngbin0 -> 2442 bytes
-rw-r--r--ios/app/img/Icon-76.pngbin0 -> 1447 bytes
-rw-r--r--ios/app/img/Icon-76@2x.pngbin0 -> 2520 bytes
-rw-r--r--ios/app/img/Icon-Small-50.pngbin0 -> 1118 bytes
-rw-r--r--ios/app/img/Icon-Small-50@2x.pngbin0 -> 1839 bytes
-rw-r--r--ios/app/img/Icon-Small.pngbin0 -> 684 bytes
-rw-r--r--ios/app/img/Icon-Small@2x.pngbin0 -> 1231 bytes
-rw-r--r--ios/app/img/Icon-Spotlight-40.pngbin0 -> 951 bytes
-rw-r--r--ios/app/img/Icon-Spotlight-40@2x.pngbin0 -> 1528 bytes
-rw-r--r--ios/app/img/Icon.pngbin0 -> 1171 bytes
-rw-r--r--ios/app/img/Icon@2x.pngbin0 -> 1931 bytes
-rw-r--r--ios/app/img/iTunesArtworkbin0 -> 264721 bytes
-rw-r--r--ios/app/img/iTunesArtwork.pngbin0 -> 5655 bytes
-rw-r--r--ios/app/img/iTunesArtwork@2xbin0 -> 661346 bytes
-rw-r--r--ios/app/img/iTunesArtwork@2x.pngbin0 -> 9293 bytes
-rw-r--r--ios/app/img/locateUser.pngbin0 -> 1111 bytes
-rw-r--r--ios/app/img/locateUser@2x.pngbin0 -> 1696 bytes
-rw-r--r--ios/app/img/settings.pngbin0 -> 528 bytes
-rw-r--r--ios/app/img/settings@2x.pngbin0 -> 1130 bytes
-rw-r--r--ios/app/main.m10
-rw-r--r--ios/app/mapboxgl-app.gyp57
34 files changed, 414 insertions, 0 deletions
diff --git a/ios/app/MBXAppDelegate.h b/ios/app/MBXAppDelegate.h
new file mode 100644
index 0000000000..da081fdcd5
--- /dev/null
+++ b/ios/app/MBXAppDelegate.h
@@ -0,0 +1,7 @@
+#import <UIKit/UIKit.h>
+
+@interface MBXAppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end \ No newline at end of file
diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m
new file mode 100644
index 0000000000..f0541b9971
--- /dev/null
+++ b/ios/app/MBXAppDelegate.m
@@ -0,0 +1,15 @@
+#import "MBXAppDelegate.h"
+#import "MBXViewController.h"
+
+@implementation MBXAppDelegate
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+ self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]];
+ [self.window makeKeyAndVisible];
+
+ return YES;
+}
+
+@end
diff --git a/ios/app/MBXViewController.h b/ios/app/MBXViewController.h
new file mode 100644
index 0000000000..924d3af60c
--- /dev/null
+++ b/ios/app/MBXViewController.h
@@ -0,0 +1,5 @@
+#import <UIKit/UIKit.h>
+
+@interface MBXViewController : UIViewController
+
+@end
diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm
new file mode 100644
index 0000000000..4945b73cc5
--- /dev/null
+++ b/ios/app/MBXViewController.mm
@@ -0,0 +1,266 @@
+#import "MBXViewController.h"
+
+#import <mbgl/ios/MGLMapView.h>
+
+#import <mbgl/platform/darwin/settings_nsuserdefaults.hpp>
+
+#import <CoreLocation/CoreLocation.h>
+
+static UIColor *const kTintColor = [UIColor colorWithRed:0.120 green:0.550 blue:0.670 alpha:1.000];
+
+static NSDictionary *const kStyles = @{
+ @"bright-v6": @"Bright",
+ @"basic-v6": @"Basic",
+ @"outdoors-v6": @"Outdoors",
+ @"satellite-v6": @"Satellite"
+};
+
+@interface MBXViewController () <UIActionSheetDelegate, CLLocationManagerDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) CLLocationManager *locationManager;
+
+@end
+
+@implementation MBXViewController
+
+mbgl::Settings_NSUserDefaults *settings = nullptr;
+
+#pragma mark - Setup
+
+- (id)init
+{
+ self = [super init];
+
+ if (self)
+ {
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveState:) name:UIApplicationDidEnterBackgroundNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restoreState:) name:UIApplicationWillEnterForegroundNotification object:nil];
+ }
+
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
+ if (accessToken) {
+ // Store to preferences so that we can launch the app later on without having to specify
+ // token.
+ [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"];
+ } else {
+ // Try to retrieve from preferences, maybe we've stored them there previously and can reuse
+ // the token.
+ accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
+ }
+
+ if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work.");
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:self.mapView];
+
+ self.mapView.viewControllerForLayoutGuides = self;
+
+ self.view.tintColor = kTintColor;
+ self.navigationController.navigationBar.tintColor = kTintColor;
+ self.mapView.tintColor = kTintColor;
+
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"settings.png"]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(showSettings)];
+
+ UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [titleButton setFrame:CGRectMake(0, 0, 120, 40)];
+ [titleButton setTitle:[[kStyles allValues] firstObject] forState:UIControlStateNormal];
+ [titleButton setTitleColor:kTintColor forState:UIControlStateNormal];
+ [titleButton addTarget:self action:@selector(cycleStyles) forControlEvents:UIControlEventTouchUpInside];
+ self.navigationItem.titleView = titleButton;
+
+ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"locateUser.png"]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(locateUser)];
+
+ settings = new mbgl::Settings_NSUserDefaults();
+ [self restoreState:nil];
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+- (void)saveState:(NSNotification *)notification
+{
+ if (self.mapView && settings)
+ {
+ settings->longitude = self.mapView.centerCoordinate.longitude;
+ settings->latitude = self.mapView.centerCoordinate.latitude;
+ settings->zoom = self.mapView.zoomLevel;
+ settings->bearing = self.mapView.direction;
+ settings->debug = self.mapView.isDebugActive;
+ settings->save();
+ }
+}
+
+- (void)restoreState:(NSNotification *)notification
+{
+ if (self.mapView && settings) {
+ settings->load();
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO];
+ self.mapView.direction = settings->bearing;
+ [self.mapView setDebugActive:settings->debug];
+ }
+}
+
+#pragma clang diagnostic pop
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+ return UIInterfaceOrientationMaskAll;
+}
+
+#pragma mark - Actions
+
+- (void)showSettings
+{
+ UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Map Settings"
+ delegate:self
+ cancelButtonTitle:@"Cancel"
+ destructiveButtonTitle:nil
+ otherButtonTitles:@"Reset North", @"Reset Position", @"Toggle Debug", nil];
+
+ [sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ if (buttonIndex == actionSheet.firstOtherButtonIndex)
+ {
+ [self.mapView resetNorth];
+ }
+ else if (buttonIndex == actionSheet.firstOtherButtonIndex + 1)
+ {
+ [self.mapView resetPosition];
+ }
+ else if (buttonIndex == actionSheet.firstOtherButtonIndex + 2)
+ {
+ [self.mapView toggleDebug];
+ }
+}
+
+- (void)cycleStyles
+{
+ UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
+
+ NSString *styleName = [titleButton titleForState:UIControlStateNormal];
+
+ if ( ! styleName)
+ {
+ styleName = [[kStyles allKeys] firstObject];
+ }
+ else
+ {
+ NSUInteger index = [[kStyles allValues] indexOfObject:styleName] + 1;
+ if (index == [[kStyles allKeys] count]) index = 0;
+ styleName = [[kStyles allKeys] objectAtIndex:index];
+ }
+
+ [self.mapView useBundledStyleNamed:styleName];
+
+ [titleButton setTitle:kStyles[styleName] forState:UIControlStateNormal];
+}
+
+- (void)locateUser
+{
+ if ( ! self.locationManager)
+ {
+ self.locationManager = [CLLocationManager new];
+ self.locationManager.delegate = self;
+ }
+
+ if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
+ {
+ [[[UIAlertView alloc] initWithTitle:@"Authorization Denied"
+ message:@"Please enable location services for this app in Privacy settings."
+ delegate:nil
+ cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];
+ }
+ else
+ {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)])
+ {
+ if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse)
+ {
+ [self.locationManager startUpdatingLocation];
+ }
+ else
+ {
+ [_locationManager requestWhenInUseAuthorization];
+ }
+ }
+ else
+ {
+ [self.locationManager startUpdatingLocation];
+ }
+#else
+ [self.locationManager startUpdatingLocation];
+#endif
+ }
+}
+
+#pragma mark - Destruction
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ if (settings)
+ {
+ [self saveState:nil];
+ delete settings;
+ settings = nullptr;
+ }
+}
+
+#pragma mark - Location
+
+- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
+{
+ switch (status)
+ {
+ case kCLAuthorizationStatusAuthorizedAlways:
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ case kCLAuthorizationStatusAuthorizedWhenInUse:
+#endif
+ {
+ [manager startUpdatingLocation];
+ break;
+ }
+ default:
+ {
+ }
+ }
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
+{
+ CLLocation *latestLocation = locations.lastObject;
+
+ if ([latestLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude]] > 100)
+ {
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES];
+ }
+
+ [self.locationManager stopUpdatingLocation];
+}
+
+#pragma clang diagnostic pop
+
+@end
diff --git a/ios/app/README.md b/ios/app/README.md
new file mode 100644
index 0000000000..325670f1ea
--- /dev/null
+++ b/ios/app/README.md
@@ -0,0 +1,3 @@
+This is the app for use in the development of Mapbox GL for iOS.
+
+If you want to run this app, head up to [`mapbox-gl-native`](https://github.com/mapbox/mapbox-gl-native) and follow the iOS installation instructions there. \ No newline at end of file
diff --git a/ios/app/app-info.plist b/ios/app/app-info.plist
new file mode 100644
index 0000000000..c15cbeb64f
--- /dev/null
+++ b/ios/app/app-info.plist
@@ -0,0 +1,51 @@
+<?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>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.mapbox.MapboxGL</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>0.0.1</string>
+ <key>CFBundleSignature</key>
+ <string>MBGL</string>
+ <key>CFBundleVersion</key>
+ <string>0.0.1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>NSHumanReadableCopyright</key>
+ <string>(c) 2014 Mapbox</string>
+ <key>NSLocationWhenInUseUsageDescription</key>
+ <string>The map will be centered on the user's location.</string>
+ <key>UILaunchStoryboardName</key>
+ <string>Default</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+</dict>
+</plist>
diff --git a/ios/app/img/Default-568h@2x.png b/ios/app/img/Default-568h@2x.png
new file mode 100644
index 0000000000..ea3706427a
--- /dev/null
+++ b/ios/app/img/Default-568h@2x.png
Binary files differ
diff --git a/ios/app/img/Default-667h@2x.png b/ios/app/img/Default-667h@2x.png
new file mode 100644
index 0000000000..03f139de66
--- /dev/null
+++ b/ios/app/img/Default-667h@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-40.png b/ios/app/img/Icon-40.png
new file mode 100644
index 0000000000..eca13393e6
--- /dev/null
+++ b/ios/app/img/Icon-40.png
Binary files differ
diff --git a/ios/app/img/Icon-40@2x.png b/ios/app/img/Icon-40@2x.png
new file mode 100644
index 0000000000..070d037539
--- /dev/null
+++ b/ios/app/img/Icon-40@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-60.png b/ios/app/img/Icon-60.png
new file mode 100644
index 0000000000..ff4c6ab4b1
--- /dev/null
+++ b/ios/app/img/Icon-60.png
Binary files differ
diff --git a/ios/app/img/Icon-60@2x.png b/ios/app/img/Icon-60@2x.png
new file mode 100644
index 0000000000..b7f25955f5
--- /dev/null
+++ b/ios/app/img/Icon-60@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-72.png b/ios/app/img/Icon-72.png
new file mode 100644
index 0000000000..0c876f664d
--- /dev/null
+++ b/ios/app/img/Icon-72.png
Binary files differ
diff --git a/ios/app/img/Icon-72@2x.png b/ios/app/img/Icon-72@2x.png
new file mode 100644
index 0000000000..6da408204a
--- /dev/null
+++ b/ios/app/img/Icon-72@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-76.png b/ios/app/img/Icon-76.png
new file mode 100644
index 0000000000..895b4a1761
--- /dev/null
+++ b/ios/app/img/Icon-76.png
Binary files differ
diff --git a/ios/app/img/Icon-76@2x.png b/ios/app/img/Icon-76@2x.png
new file mode 100644
index 0000000000..7bc5208976
--- /dev/null
+++ b/ios/app/img/Icon-76@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-Small-50.png b/ios/app/img/Icon-Small-50.png
new file mode 100644
index 0000000000..6d17da4b00
--- /dev/null
+++ b/ios/app/img/Icon-Small-50.png
Binary files differ
diff --git a/ios/app/img/Icon-Small-50@2x.png b/ios/app/img/Icon-Small-50@2x.png
new file mode 100644
index 0000000000..ac4ec19282
--- /dev/null
+++ b/ios/app/img/Icon-Small-50@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-Small.png b/ios/app/img/Icon-Small.png
new file mode 100644
index 0000000000..aecbbc8a1d
--- /dev/null
+++ b/ios/app/img/Icon-Small.png
Binary files differ
diff --git a/ios/app/img/Icon-Small@2x.png b/ios/app/img/Icon-Small@2x.png
new file mode 100644
index 0000000000..7773852e7a
--- /dev/null
+++ b/ios/app/img/Icon-Small@2x.png
Binary files differ
diff --git a/ios/app/img/Icon-Spotlight-40.png b/ios/app/img/Icon-Spotlight-40.png
new file mode 100644
index 0000000000..eca13393e6
--- /dev/null
+++ b/ios/app/img/Icon-Spotlight-40.png
Binary files differ
diff --git a/ios/app/img/Icon-Spotlight-40@2x.png b/ios/app/img/Icon-Spotlight-40@2x.png
new file mode 100644
index 0000000000..070d037539
--- /dev/null
+++ b/ios/app/img/Icon-Spotlight-40@2x.png
Binary files differ
diff --git a/ios/app/img/Icon.png b/ios/app/img/Icon.png
new file mode 100644
index 0000000000..9ca8194eef
--- /dev/null
+++ b/ios/app/img/Icon.png
Binary files differ
diff --git a/ios/app/img/Icon@2x.png b/ios/app/img/Icon@2x.png
new file mode 100644
index 0000000000..7c2e8ba037
--- /dev/null
+++ b/ios/app/img/Icon@2x.png
Binary files differ
diff --git a/ios/app/img/iTunesArtwork b/ios/app/img/iTunesArtwork
new file mode 100644
index 0000000000..ac6a0c58e8
--- /dev/null
+++ b/ios/app/img/iTunesArtwork
Binary files differ
diff --git a/ios/app/img/iTunesArtwork.png b/ios/app/img/iTunesArtwork.png
new file mode 100644
index 0000000000..b10824b048
--- /dev/null
+++ b/ios/app/img/iTunesArtwork.png
Binary files differ
diff --git a/ios/app/img/iTunesArtwork@2x b/ios/app/img/iTunesArtwork@2x
new file mode 100644
index 0000000000..fae1dad8bf
--- /dev/null
+++ b/ios/app/img/iTunesArtwork@2x
Binary files differ
diff --git a/ios/app/img/iTunesArtwork@2x.png b/ios/app/img/iTunesArtwork@2x.png
new file mode 100644
index 0000000000..fdee900aa4
--- /dev/null
+++ b/ios/app/img/iTunesArtwork@2x.png
Binary files differ
diff --git a/ios/app/img/locateUser.png b/ios/app/img/locateUser.png
new file mode 100644
index 0000000000..aa8d1cf52e
--- /dev/null
+++ b/ios/app/img/locateUser.png
Binary files differ
diff --git a/ios/app/img/locateUser@2x.png b/ios/app/img/locateUser@2x.png
new file mode 100644
index 0000000000..29c4905938
--- /dev/null
+++ b/ios/app/img/locateUser@2x.png
Binary files differ
diff --git a/ios/app/img/settings.png b/ios/app/img/settings.png
new file mode 100644
index 0000000000..5d7643eef5
--- /dev/null
+++ b/ios/app/img/settings.png
Binary files differ
diff --git a/ios/app/img/settings@2x.png b/ios/app/img/settings@2x.png
new file mode 100644
index 0000000000..2bb9f0ebad
--- /dev/null
+++ b/ios/app/img/settings@2x.png
Binary files differ
diff --git a/ios/app/main.m b/ios/app/main.m
new file mode 100644
index 0000000000..954584f141
--- /dev/null
+++ b/ios/app/main.m
@@ -0,0 +1,10 @@
+#import <UIKit/UIKit.h>
+
+#import "MBXAppDelegate.h"
+
+int main(int argc, char * argv[])
+{
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([MBXAppDelegate class]));
+ }
+}
diff --git a/ios/app/mapboxgl-app.gyp b/ios/app/mapboxgl-app.gyp
new file mode 100644
index 0000000000..7287932fc5
--- /dev/null
+++ b/ios/app/mapboxgl-app.gyp
@@ -0,0 +1,57 @@
+{
+ 'includes': [
+ '../../gyp/common.gypi',
+ ],
+ 'targets': [
+ { 'target_name': 'iosapp',
+ 'product_name': 'Mapbox GL',
+ 'type': 'executable',
+ 'product_extension': 'app',
+ 'mac_bundle': 1,
+ 'mac_bundle_resources': [
+ '<!@(find ./img -type f)',
+ ],
+
+ 'dependencies': [
+ '../../mbgl.gyp:bundle_styles',
+ '../../mbgl.gyp:core',
+ '../../mbgl.gyp:platform-<(platform_lib)',
+ '../../mbgl.gyp:http-<(http_lib)',
+ '../../mbgl.gyp:asset-<(asset_lib)',
+ '../../mbgl.gyp:cache-<(cache_lib)',
+ ],
+
+ 'sources': [
+ './main.m',
+ './MBXAppDelegate.h',
+ './MBXAppDelegate.m',
+ './MBXViewController.h',
+ './MBXViewController.mm',
+ '../../platform/darwin/settings_nsuserdefaults.mm',
+ ],
+
+ 'xcode_settings': {
+ 'SDKROOT': 'iphoneos',
+ 'SUPPORTED_PLATFORMS': 'iphonesimulator iphoneos',
+ 'INFOPLIST_FILE': 'app-info.plist',
+ 'TARGETED_DEVICE_FAMILY': '1,2',
+ 'COMBINE_HIDPI_IMAGES': 'NO', # don't merge @2x.png images into .tiff files
+ 'CLANG_ENABLE_OBJC_ARC': 'YES',
+ },
+
+ 'configurations': {
+ 'Debug': {
+ 'xcode_settings': {
+ 'CODE_SIGN_IDENTITY': 'iPhone Developer',
+ },
+ },
+ 'Release': {
+ 'xcode_settings': {
+ 'CODE_SIGN_IDENTITY': 'iPhone Distribution',
+ 'ARCHS': [ "armv7", "armv7s", "arm64", "i386", "x86_64" ],
+ },
+ },
+ },
+ }
+ ]
+}