├── .gitignore ├── Cartfile ├── Cartfile.resolved ├── LICENSE.md ├── MapboxARKit.podspec ├── MapboxARKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── MapboxARKit.xcscheme │ └── MapboxARKitDemoApp.xcscheme ├── MapboxARKit ├── Annotation.swift ├── AnnotationManager.swift ├── Info.plist ├── MBARAnchor.swift └── MapboxARKit.h ├── MapboxARKitDemoApp ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── arrived.imageset │ │ ├── Contents.json │ │ └── arrived.png │ ├── crosshairs.imageset │ │ ├── Contents.json │ │ └── crosshairs.png │ ├── straightahead.imageset │ │ ├── Contents.json │ │ └── straightahead.png │ ├── turnleft.imageset │ │ ├── Contents.json │ │ └── turnleft.png │ └── turnright.imageset │ │ ├── Contents.json │ │ └── turnright.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── ViewController.swift └── art.scnassets │ ├── LED-Fluorescent-light-bulb-1---UV-LAYOUT.png │ ├── Metal_AO.jpg │ ├── Metal_BaseColor.jpg │ ├── Metal_Glossiness.jpg │ ├── Metal_Metallic.jpg │ ├── Plastic_AO.jpg │ ├── Plastic_BaseColor.jpg │ ├── Plastic_Glossiness.jpg │ ├── Plastic_Metallic.jpg │ ├── Plastic_Roughness.jpg │ └── light-bulb.dae ├── MapboxARKitTests ├── Info.plist └── MapboxARKitTests.swift ├── README.md ├── documentation └── images │ └── mapbox_directions_arkit.jpeg └── scripts └── setup.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | xcuserdata 4 | *.xccheckout 5 | *.moved-aside 6 | *.xcuserstate 7 | *.xcscmblueprint 8 | 9 | Carthage/Build 10 | Carthage/Checkouts 11 | 12 | mapbox_access_token 13 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "mapbox/turf-swift" 2 | github "mapbox/MapboxDirections.swift" 3 | binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 3.6 4 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" "3.6.4" 2 | github "mapbox/MapboxDirections.swift" "v0.11.2" 3 | github "mapbox/Turf-swift" "c0651d438dde71519a0469956b69ef641573fcae" 4 | github "raphaelmor/Polyline" "v4.1.1" 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright © 2014–2017, Mapbox 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | 15 | -------------------------------------------------------------------------------- /MapboxARKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 4 | 5 | s.name = "MapboxARKit" 6 | s.version = "0.0.1" 7 | s.summary = "Utilities for combining Mapbox maps and location services with ARKit in your applications." 8 | 9 | s.description = <<-DESC 10 | Utilities for combining Mapbox maps and location services with ARKit in your applications. 11 | DESC 12 | 13 | s.homepage = "https://www.mapbox.com/" 14 | s.documentation_url = "https://mapbox.github.io/mapbox-arkit-ios/documentation/" 15 | 16 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 17 | 18 | s.license = { :type => "ISC", :file => "LICENSE.md" } 19 | 20 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 21 | 22 | s.author = { "Mapbox" => "mobile@mapbox.com" } 23 | s.social_media_url = "https://twitter.com/mapbox" 24 | 25 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 26 | 27 | s.ios.deployment_target = "11.0" 28 | 29 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 30 | 31 | s.source = { :git => "https://github.com/mapbox/mapbox-arkit-ios.git", :tag => "v#{s.version.to_s}" } 32 | 33 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 34 | 35 | s.source_files = ["MapboxARKit/*"] 36 | 37 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 38 | 39 | s.requires_arc = true 40 | s.module_name = "MapboxARKit" 41 | 42 | s.dependency "Turf" 43 | end 44 | -------------------------------------------------------------------------------- /MapboxARKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4032F70C1F3BDA8B002D0E35 /* Annotation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4032F70B1F3BDA8B002D0E35 /* Annotation.swift */; }; 11 | 404B7C301F3CE59500D53423 /* Turf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C41F3CE3DF00937EF1 /* Turf.framework */; }; 12 | 404B7C311F3CE5AD00D53423 /* Turf.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C41F3CE3DF00937EF1 /* Turf.framework */; }; 13 | 404B7C321F3CE5AD00D53423 /* Turf.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C41F3CE3DF00937EF1 /* Turf.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 404B7C331F3CE5AD00D53423 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C31F3CE3DC00937EF1 /* Mapbox.framework */; }; 15 | 404B7C341F3CE5AD00D53423 /* Mapbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C31F3CE3DC00937EF1 /* Mapbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 16 | 404B7C351F3CE5AD00D53423 /* MapboxDirections.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C21F3CE3D900937EF1 /* MapboxDirections.framework */; }; 17 | 404B7C361F3CE5AD00D53423 /* MapboxDirections.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5C21F3CE3D900937EF1 /* MapboxDirections.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | 404B7C371F3CE5AD00D53423 /* Polyline.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5B71F3CE3C200937EF1 /* Polyline.framework */; }; 19 | 404B7C381F3CE5AD00D53423 /* Polyline.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 40CDD5B71F3CE3C200937EF1 /* Polyline.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | 404B7C3A1F3CE5B500D53423 /* MapboxARKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40D722841F3A4F3D00466721 /* MapboxARKit.framework */; }; 21 | 404B7C3B1F3CE5B500D53423 /* MapboxARKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 40D722841F3A4F3D00466721 /* MapboxARKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 22 | 40D7228E1F3A4F3D00466721 /* MapboxARKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40D722841F3A4F3D00466721 /* MapboxARKit.framework */; }; 23 | 40D722931F3A4F3D00466721 /* MapboxARKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D722921F3A4F3D00466721 /* MapboxARKitTests.swift */; }; 24 | 40D722951F3A4F3D00466721 /* MapboxARKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 40D722871F3A4F3D00466721 /* MapboxARKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 40D722A01F3A598400466721 /* MBARAnchor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D7229E1F3A597F00466721 /* MBARAnchor.swift */; }; 26 | 40D722A11F3A598600466721 /* AnnotationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D7229F1F3A597F00466721 /* AnnotationManager.swift */; }; 27 | 40DEF9A91F3CE1570089629A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40DEF9A81F3CE1570089629A /* AppDelegate.swift */; }; 28 | 40DEF9AB1F3CE1570089629A /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40DEF9AA1F3CE1570089629A /* ViewController.swift */; }; 29 | 40DEF9AE1F3CE1570089629A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40DEF9AC1F3CE1570089629A /* Main.storyboard */; }; 30 | 40DEF9B01F3CE1570089629A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 40DEF9AF1F3CE1570089629A /* Assets.xcassets */; }; 31 | 40DEF9B31F3CE1570089629A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40DEF9B11F3CE1570089629A /* LaunchScreen.storyboard */; }; 32 | 40F3F19E1F3E349A00FF419C /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = 40F3F19D1F3E349A00FF419C /* art.scnassets */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 404B7C3C1F3CE5B500D53423 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 40D7227B1F3A4F3D00466721 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 40D722831F3A4F3D00466721; 41 | remoteInfo = MapboxARKit; 42 | }; 43 | 40D7228F1F3A4F3D00466721 /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 40D7227B1F3A4F3D00466721 /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 40D722831F3A4F3D00466721; 48 | remoteInfo = MapboxARKit; 49 | }; 50 | /* End PBXContainerItemProxy section */ 51 | 52 | /* Begin PBXCopyFilesBuildPhase section */ 53 | 404B7C391F3CE5AD00D53423 /* Embed Frameworks */ = { 54 | isa = PBXCopyFilesBuildPhase; 55 | buildActionMask = 2147483647; 56 | dstPath = ""; 57 | dstSubfolderSpec = 10; 58 | files = ( 59 | 404B7C3B1F3CE5B500D53423 /* MapboxARKit.framework in Embed Frameworks */, 60 | 404B7C361F3CE5AD00D53423 /* MapboxDirections.framework in Embed Frameworks */, 61 | 404B7C321F3CE5AD00D53423 /* Turf.framework in Embed Frameworks */, 62 | 404B7C381F3CE5AD00D53423 /* Polyline.framework in Embed Frameworks */, 63 | 404B7C341F3CE5AD00D53423 /* Mapbox.framework in Embed Frameworks */, 64 | ); 65 | name = "Embed Frameworks"; 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXCopyFilesBuildPhase section */ 69 | 70 | /* Begin PBXFileReference section */ 71 | 4032F70B1F3BDA8B002D0E35 /* Annotation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Annotation.swift; sourceTree = ""; }; 72 | 40CDD5B71F3CE3C200937EF1 /* Polyline.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Polyline.framework; path = Carthage/Build/iOS/Polyline.framework; sourceTree = ""; }; 73 | 40CDD5C21F3CE3D900937EF1 /* MapboxDirections.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapboxDirections.framework; path = Carthage/Build/iOS/MapboxDirections.framework; sourceTree = ""; }; 74 | 40CDD5C31F3CE3DC00937EF1 /* Mapbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Mapbox.framework; path = Carthage/Build/iOS/Mapbox.framework; sourceTree = ""; }; 75 | 40CDD5C41F3CE3DF00937EF1 /* Turf.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Turf.framework; path = Carthage/Build/iOS/Turf.framework; sourceTree = ""; }; 76 | 40D722841F3A4F3D00466721 /* MapboxARKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MapboxARKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | 40D722871F3A4F3D00466721 /* MapboxARKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MapboxARKit.h; sourceTree = ""; }; 78 | 40D722881F3A4F3D00466721 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 79 | 40D7228D1F3A4F3D00466721 /* MapboxARKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapboxARKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 40D722921F3A4F3D00466721 /* MapboxARKitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapboxARKitTests.swift; sourceTree = ""; }; 81 | 40D722941F3A4F3D00466721 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 82 | 40D7229E1F3A597F00466721 /* MBARAnchor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MBARAnchor.swift; sourceTree = ""; }; 83 | 40D7229F1F3A597F00466721 /* AnnotationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnnotationManager.swift; sourceTree = ""; }; 84 | 40DEF9A61F3CE1570089629A /* MapboxARKitDemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MapboxARKitDemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 85 | 40DEF9A81F3CE1570089629A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 86 | 40DEF9AA1F3CE1570089629A /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 87 | 40DEF9AD1F3CE1570089629A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 88 | 40DEF9AF1F3CE1570089629A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 89 | 40DEF9B21F3CE1570089629A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 90 | 40DEF9B41F3CE1570089629A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 91 | 40F3F19D1F3E349A00FF419C /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = art.scnassets; sourceTree = ""; }; 92 | /* End PBXFileReference section */ 93 | 94 | /* Begin PBXFrameworksBuildPhase section */ 95 | 40D722801F3A4F3D00466721 /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | 404B7C301F3CE59500D53423 /* Turf.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | 40D7228A1F3A4F3D00466721 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | 40D7228E1F3A4F3D00466721 /* MapboxARKit.framework in Frameworks */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | 40DEF9A31F3CE1570089629A /* Frameworks */ = { 112 | isa = PBXFrameworksBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | 404B7C3A1F3CE5B500D53423 /* MapboxARKit.framework in Frameworks */, 116 | 404B7C351F3CE5AD00D53423 /* MapboxDirections.framework in Frameworks */, 117 | 404B7C311F3CE5AD00D53423 /* Turf.framework in Frameworks */, 118 | 404B7C371F3CE5AD00D53423 /* Polyline.framework in Frameworks */, 119 | 404B7C331F3CE5AD00D53423 /* Mapbox.framework in Frameworks */, 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | /* End PBXFrameworksBuildPhase section */ 124 | 125 | /* Begin PBXGroup section */ 126 | 4032F6E51F3BC3D4002D0E35 /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 40CDD5C41F3CE3DF00937EF1 /* Turf.framework */, 130 | 40CDD5C31F3CE3DC00937EF1 /* Mapbox.framework */, 131 | 40CDD5C21F3CE3D900937EF1 /* MapboxDirections.framework */, 132 | 40CDD5B71F3CE3C200937EF1 /* Polyline.framework */, 133 | ); 134 | name = Frameworks; 135 | sourceTree = ""; 136 | }; 137 | 40D7227A1F3A4F3D00466721 = { 138 | isa = PBXGroup; 139 | children = ( 140 | 40D722861F3A4F3D00466721 /* MapboxARKit */, 141 | 40D722911F3A4F3D00466721 /* MapboxARKitTests */, 142 | 40DEF9A71F3CE1570089629A /* MapboxARKitDemoApp */, 143 | 40D722851F3A4F3D00466721 /* Products */, 144 | 4032F6E51F3BC3D4002D0E35 /* Frameworks */, 145 | ); 146 | sourceTree = ""; 147 | }; 148 | 40D722851F3A4F3D00466721 /* Products */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 40D722841F3A4F3D00466721 /* MapboxARKit.framework */, 152 | 40D7228D1F3A4F3D00466721 /* MapboxARKitTests.xctest */, 153 | 40DEF9A61F3CE1570089629A /* MapboxARKitDemoApp.app */, 154 | ); 155 | name = Products; 156 | sourceTree = ""; 157 | }; 158 | 40D722861F3A4F3D00466721 /* MapboxARKit */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 40D722871F3A4F3D00466721 /* MapboxARKit.h */, 162 | 4032F70B1F3BDA8B002D0E35 /* Annotation.swift */, 163 | 40D7229F1F3A597F00466721 /* AnnotationManager.swift */, 164 | 40D7229E1F3A597F00466721 /* MBARAnchor.swift */, 165 | 40D722881F3A4F3D00466721 /* Info.plist */, 166 | ); 167 | path = MapboxARKit; 168 | sourceTree = ""; 169 | }; 170 | 40D722911F3A4F3D00466721 /* MapboxARKitTests */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 40D722921F3A4F3D00466721 /* MapboxARKitTests.swift */, 174 | 40D722941F3A4F3D00466721 /* Info.plist */, 175 | ); 176 | path = MapboxARKitTests; 177 | sourceTree = ""; 178 | }; 179 | 40DEF9A71F3CE1570089629A /* MapboxARKitDemoApp */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 40DEF9A81F3CE1570089629A /* AppDelegate.swift */, 183 | 40DEF9AA1F3CE1570089629A /* ViewController.swift */, 184 | 40DEF9AC1F3CE1570089629A /* Main.storyboard */, 185 | 40DEF9B11F3CE1570089629A /* LaunchScreen.storyboard */, 186 | 40F3F19D1F3E349A00FF419C /* art.scnassets */, 187 | 40DEF9AF1F3CE1570089629A /* Assets.xcassets */, 188 | 40DEF9B41F3CE1570089629A /* Info.plist */, 189 | ); 190 | path = MapboxARKitDemoApp; 191 | sourceTree = ""; 192 | }; 193 | /* End PBXGroup section */ 194 | 195 | /* Begin PBXHeadersBuildPhase section */ 196 | 40D722811F3A4F3D00466721 /* Headers */ = { 197 | isa = PBXHeadersBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 40D722951F3A4F3D00466721 /* MapboxARKit.h in Headers */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXHeadersBuildPhase section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | 40D722831F3A4F3D00466721 /* MapboxARKit */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 40D722981F3A4F3D00466721 /* Build configuration list for PBXNativeTarget "MapboxARKit" */; 210 | buildPhases = ( 211 | 40D7227F1F3A4F3D00466721 /* Sources */, 212 | 40D722801F3A4F3D00466721 /* Frameworks */, 213 | 40D722811F3A4F3D00466721 /* Headers */, 214 | 40D722821F3A4F3D00466721 /* Resources */, 215 | ); 216 | buildRules = ( 217 | ); 218 | dependencies = ( 219 | ); 220 | name = MapboxARKit; 221 | productName = MapboxARKit; 222 | productReference = 40D722841F3A4F3D00466721 /* MapboxARKit.framework */; 223 | productType = "com.apple.product-type.framework"; 224 | }; 225 | 40D7228C1F3A4F3D00466721 /* MapboxARKitTests */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 40D7229B1F3A4F3D00466721 /* Build configuration list for PBXNativeTarget "MapboxARKitTests" */; 228 | buildPhases = ( 229 | 40D722891F3A4F3D00466721 /* Sources */, 230 | 40D7228A1F3A4F3D00466721 /* Frameworks */, 231 | 40D7228B1F3A4F3D00466721 /* Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | 40D722901F3A4F3D00466721 /* PBXTargetDependency */, 237 | ); 238 | name = MapboxARKitTests; 239 | productName = MapboxARKitTests; 240 | productReference = 40D7228D1F3A4F3D00466721 /* MapboxARKitTests.xctest */; 241 | productType = "com.apple.product-type.bundle.unit-test"; 242 | }; 243 | 40DEF9A51F3CE1570089629A /* MapboxARKitDemoApp */ = { 244 | isa = PBXNativeTarget; 245 | buildConfigurationList = 40DEF9B51F3CE1570089629A /* Build configuration list for PBXNativeTarget "MapboxARKitDemoApp" */; 246 | buildPhases = ( 247 | 40DEF9A21F3CE1570089629A /* Sources */, 248 | 40DEF9A31F3CE1570089629A /* Frameworks */, 249 | 40DEF9A41F3CE1570089629A /* Resources */, 250 | 404B7C391F3CE5AD00D53423 /* Embed Frameworks */, 251 | 404B7C3E1F3CE66D00D53423 /* ShellScript */, 252 | ); 253 | buildRules = ( 254 | ); 255 | dependencies = ( 256 | 404B7C3D1F3CE5B500D53423 /* PBXTargetDependency */, 257 | ); 258 | name = MapboxARKitDemoApp; 259 | productName = MapboxARKitDemoApp; 260 | productReference = 40DEF9A61F3CE1570089629A /* MapboxARKitDemoApp.app */; 261 | productType = "com.apple.product-type.application"; 262 | }; 263 | /* End PBXNativeTarget section */ 264 | 265 | /* Begin PBXProject section */ 266 | 40D7227B1F3A4F3D00466721 /* Project object */ = { 267 | isa = PBXProject; 268 | attributes = { 269 | LastSwiftUpdateCheck = 0900; 270 | LastUpgradeCheck = 0900; 271 | ORGANIZATIONNAME = Mapbox; 272 | TargetAttributes = { 273 | 40D722831F3A4F3D00466721 = { 274 | CreatedOnToolsVersion = 9.0; 275 | LastSwiftMigration = 0900; 276 | ProvisioningStyle = Manual; 277 | }; 278 | 40D7228C1F3A4F3D00466721 = { 279 | CreatedOnToolsVersion = 9.0; 280 | ProvisioningStyle = Manual; 281 | }; 282 | 40DEF9A51F3CE1570089629A = { 283 | CreatedOnToolsVersion = 9.0; 284 | }; 285 | }; 286 | }; 287 | buildConfigurationList = 40D7227E1F3A4F3D00466721 /* Build configuration list for PBXProject "MapboxARKit" */; 288 | compatibilityVersion = "Xcode 8.0"; 289 | developmentRegion = en; 290 | hasScannedForEncodings = 0; 291 | knownRegions = ( 292 | en, 293 | Base, 294 | ); 295 | mainGroup = 40D7227A1F3A4F3D00466721; 296 | productRefGroup = 40D722851F3A4F3D00466721 /* Products */; 297 | projectDirPath = ""; 298 | projectRoot = ""; 299 | targets = ( 300 | 40D722831F3A4F3D00466721 /* MapboxARKit */, 301 | 40D7228C1F3A4F3D00466721 /* MapboxARKitTests */, 302 | 40DEF9A51F3CE1570089629A /* MapboxARKitDemoApp */, 303 | ); 304 | }; 305 | /* End PBXProject section */ 306 | 307 | /* Begin PBXResourcesBuildPhase section */ 308 | 40D722821F3A4F3D00466721 /* Resources */ = { 309 | isa = PBXResourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | ); 313 | runOnlyForDeploymentPostprocessing = 0; 314 | }; 315 | 40D7228B1F3A4F3D00466721 /* Resources */ = { 316 | isa = PBXResourcesBuildPhase; 317 | buildActionMask = 2147483647; 318 | files = ( 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | }; 322 | 40DEF9A41F3CE1570089629A /* Resources */ = { 323 | isa = PBXResourcesBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | 40DEF9B31F3CE1570089629A /* LaunchScreen.storyboard in Resources */, 327 | 40F3F19E1F3E349A00FF419C /* art.scnassets in Resources */, 328 | 40DEF9B01F3CE1570089629A /* Assets.xcassets in Resources */, 329 | 40DEF9AE1F3CE1570089629A /* Main.storyboard in Resources */, 330 | ); 331 | runOnlyForDeploymentPostprocessing = 0; 332 | }; 333 | /* End PBXResourcesBuildPhase section */ 334 | 335 | /* Begin PBXShellScriptBuildPhase section */ 336 | 404B7C3E1F3CE66D00D53423 /* ShellScript */ = { 337 | isa = PBXShellScriptBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | ); 341 | inputPaths = ( 342 | ); 343 | outputPaths = ( 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | shellPath = /bin/sh; 347 | shellScript = "token_file=mapbox_access_token\ntoken=\"$(cat $token_file)\"\nif [ \"$token\" ]; then\nplutil -replace MGLMapboxAccessToken -string $token \"$TARGET_BUILD_DIR/$INFOPLIST_PATH\"\nelse\necho 'error: Missing Mapbox access token'\nopen 'https://www.mapbox.com/studio/account/tokens/'\necho \"error: Get an access token from , then create a new file at $token_file that contains the access token.\"\nexit 1\nfi"; 348 | }; 349 | /* End PBXShellScriptBuildPhase section */ 350 | 351 | /* Begin PBXSourcesBuildPhase section */ 352 | 40D7227F1F3A4F3D00466721 /* Sources */ = { 353 | isa = PBXSourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | 40D722A11F3A598600466721 /* AnnotationManager.swift in Sources */, 357 | 4032F70C1F3BDA8B002D0E35 /* Annotation.swift in Sources */, 358 | 40D722A01F3A598400466721 /* MBARAnchor.swift in Sources */, 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | }; 362 | 40D722891F3A4F3D00466721 /* Sources */ = { 363 | isa = PBXSourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | 40D722931F3A4F3D00466721 /* MapboxARKitTests.swift in Sources */, 367 | ); 368 | runOnlyForDeploymentPostprocessing = 0; 369 | }; 370 | 40DEF9A21F3CE1570089629A /* Sources */ = { 371 | isa = PBXSourcesBuildPhase; 372 | buildActionMask = 2147483647; 373 | files = ( 374 | 40DEF9AB1F3CE1570089629A /* ViewController.swift in Sources */, 375 | 40DEF9A91F3CE1570089629A /* AppDelegate.swift in Sources */, 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | /* End PBXSourcesBuildPhase section */ 380 | 381 | /* Begin PBXTargetDependency section */ 382 | 404B7C3D1F3CE5B500D53423 /* PBXTargetDependency */ = { 383 | isa = PBXTargetDependency; 384 | target = 40D722831F3A4F3D00466721 /* MapboxARKit */; 385 | targetProxy = 404B7C3C1F3CE5B500D53423 /* PBXContainerItemProxy */; 386 | }; 387 | 40D722901F3A4F3D00466721 /* PBXTargetDependency */ = { 388 | isa = PBXTargetDependency; 389 | target = 40D722831F3A4F3D00466721 /* MapboxARKit */; 390 | targetProxy = 40D7228F1F3A4F3D00466721 /* PBXContainerItemProxy */; 391 | }; 392 | /* End PBXTargetDependency section */ 393 | 394 | /* Begin PBXVariantGroup section */ 395 | 40DEF9AC1F3CE1570089629A /* Main.storyboard */ = { 396 | isa = PBXVariantGroup; 397 | children = ( 398 | 40DEF9AD1F3CE1570089629A /* Base */, 399 | ); 400 | name = Main.storyboard; 401 | sourceTree = ""; 402 | }; 403 | 40DEF9B11F3CE1570089629A /* LaunchScreen.storyboard */ = { 404 | isa = PBXVariantGroup; 405 | children = ( 406 | 40DEF9B21F3CE1570089629A /* Base */, 407 | ); 408 | name = LaunchScreen.storyboard; 409 | sourceTree = ""; 410 | }; 411 | /* End PBXVariantGroup section */ 412 | 413 | /* Begin XCBuildConfiguration section */ 414 | 40D722961F3A4F3D00466721 /* Debug */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | CLANG_ANALYZER_NONNULL = YES; 419 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 420 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 421 | CLANG_CXX_LIBRARY = "libc++"; 422 | CLANG_ENABLE_MODULES = YES; 423 | CLANG_ENABLE_OBJC_ARC = YES; 424 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 425 | CLANG_WARN_BOOL_CONVERSION = YES; 426 | CLANG_WARN_COMMA = YES; 427 | CLANG_WARN_CONSTANT_CONVERSION = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INFINITE_RECURSION = YES; 433 | CLANG_WARN_INT_CONVERSION = YES; 434 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 435 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 436 | CLANG_WARN_STRICT_PROTOTYPES = YES; 437 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 438 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | CODE_SIGN_IDENTITY = "iPhone Developer"; 442 | COPY_PHASE_STRIP = NO; 443 | CURRENT_PROJECT_VERSION = 1; 444 | DEBUG_INFORMATION_FORMAT = dwarf; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | ENABLE_TESTABILITY = YES; 447 | GCC_C_LANGUAGE_STANDARD = gnu11; 448 | GCC_DYNAMIC_NO_PIC = NO; 449 | GCC_NO_COMMON_BLOCKS = YES; 450 | GCC_OPTIMIZATION_LEVEL = 0; 451 | GCC_PREPROCESSOR_DEFINITIONS = ( 452 | "DEBUG=1", 453 | "$(inherited)", 454 | ); 455 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 456 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 457 | GCC_WARN_UNDECLARED_SELECTOR = YES; 458 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 459 | GCC_WARN_UNUSED_FUNCTION = YES; 460 | GCC_WARN_UNUSED_VARIABLE = YES; 461 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 462 | MTL_ENABLE_DEBUG_INFO = YES; 463 | ONLY_ACTIVE_ARCH = YES; 464 | SDKROOT = iphoneos; 465 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 466 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 467 | VERSIONING_SYSTEM = "apple-generic"; 468 | VERSION_INFO_PREFIX = ""; 469 | }; 470 | name = Debug; 471 | }; 472 | 40D722971F3A4F3D00466721 /* Release */ = { 473 | isa = XCBuildConfiguration; 474 | buildSettings = { 475 | ALWAYS_SEARCH_USER_PATHS = NO; 476 | CLANG_ANALYZER_NONNULL = YES; 477 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 487 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INFINITE_RECURSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 493 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 494 | CLANG_WARN_STRICT_PROTOTYPES = YES; 495 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 496 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 497 | CLANG_WARN_UNREACHABLE_CODE = YES; 498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 499 | CODE_SIGN_IDENTITY = "iPhone Developer"; 500 | COPY_PHASE_STRIP = NO; 501 | CURRENT_PROJECT_VERSION = 1; 502 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 503 | ENABLE_NS_ASSERTIONS = NO; 504 | ENABLE_STRICT_OBJC_MSGSEND = YES; 505 | GCC_C_LANGUAGE_STANDARD = gnu11; 506 | GCC_NO_COMMON_BLOCKS = YES; 507 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 508 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 509 | GCC_WARN_UNDECLARED_SELECTOR = YES; 510 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 511 | GCC_WARN_UNUSED_FUNCTION = YES; 512 | GCC_WARN_UNUSED_VARIABLE = YES; 513 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 514 | MTL_ENABLE_DEBUG_INFO = NO; 515 | SDKROOT = iphoneos; 516 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 517 | VALIDATE_PRODUCT = YES; 518 | VERSIONING_SYSTEM = "apple-generic"; 519 | VERSION_INFO_PREFIX = ""; 520 | }; 521 | name = Release; 522 | }; 523 | 40D722991F3A4F3D00466721 /* Debug */ = { 524 | isa = XCBuildConfiguration; 525 | buildSettings = { 526 | CLANG_ENABLE_MODULES = YES; 527 | CODE_SIGN_IDENTITY = ""; 528 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 529 | CODE_SIGN_STYLE = Manual; 530 | DEFINES_MODULE = YES; 531 | DYLIB_COMPATIBILITY_VERSION = 1; 532 | DYLIB_CURRENT_VERSION = 1; 533 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 534 | FRAMEWORK_SEARCH_PATHS = ( 535 | "$(inherited)", 536 | "$(PROJECT_DIR)/Carthage/Build/iOS", 537 | ); 538 | INFOPLIST_FILE = MapboxARKit/Info.plist; 539 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 540 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 541 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKit; 542 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 543 | PROVISIONING_PROFILE_SPECIFIER = ""; 544 | SKIP_INSTALL = YES; 545 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 546 | SWIFT_VERSION = 4.0; 547 | TARGETED_DEVICE_FAMILY = "1,2"; 548 | }; 549 | name = Debug; 550 | }; 551 | 40D7229A1F3A4F3D00466721 /* Release */ = { 552 | isa = XCBuildConfiguration; 553 | buildSettings = { 554 | CLANG_ENABLE_MODULES = YES; 555 | CODE_SIGN_IDENTITY = ""; 556 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 557 | CODE_SIGN_STYLE = Manual; 558 | DEFINES_MODULE = YES; 559 | DYLIB_COMPATIBILITY_VERSION = 1; 560 | DYLIB_CURRENT_VERSION = 1; 561 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 562 | FRAMEWORK_SEARCH_PATHS = ( 563 | "$(inherited)", 564 | "$(PROJECT_DIR)/Carthage/Build/iOS", 565 | ); 566 | INFOPLIST_FILE = MapboxARKit/Info.plist; 567 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 568 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 569 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKit; 570 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 571 | PROVISIONING_PROFILE_SPECIFIER = ""; 572 | SKIP_INSTALL = YES; 573 | SWIFT_VERSION = 4.0; 574 | TARGETED_DEVICE_FAMILY = "1,2"; 575 | }; 576 | name = Release; 577 | }; 578 | 40D7229C1F3A4F3D00466721 /* Debug */ = { 579 | isa = XCBuildConfiguration; 580 | buildSettings = { 581 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 582 | CODE_SIGN_STYLE = Manual; 583 | DEVELOPMENT_TEAM = ""; 584 | INFOPLIST_FILE = MapboxARKitTests/Info.plist; 585 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 586 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKitTests; 587 | PRODUCT_NAME = "$(TARGET_NAME)"; 588 | PROVISIONING_PROFILE_SPECIFIER = ""; 589 | SWIFT_VERSION = 4.0; 590 | TARGETED_DEVICE_FAMILY = "1,2"; 591 | }; 592 | name = Debug; 593 | }; 594 | 40D7229D1F3A4F3D00466721 /* Release */ = { 595 | isa = XCBuildConfiguration; 596 | buildSettings = { 597 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 598 | CODE_SIGN_STYLE = Manual; 599 | DEVELOPMENT_TEAM = ""; 600 | INFOPLIST_FILE = MapboxARKitTests/Info.plist; 601 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 602 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKitTests; 603 | PRODUCT_NAME = "$(TARGET_NAME)"; 604 | PROVISIONING_PROFILE_SPECIFIER = ""; 605 | SWIFT_VERSION = 4.0; 606 | TARGETED_DEVICE_FAMILY = "1,2"; 607 | }; 608 | name = Release; 609 | }; 610 | 40DEF9B61F3CE1570089629A /* Debug */ = { 611 | isa = XCBuildConfiguration; 612 | buildSettings = { 613 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 614 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 615 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 616 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 617 | DEVELOPMENT_TEAM = ""; 618 | FRAMEWORK_SEARCH_PATHS = ( 619 | "$(inherited)", 620 | "$(PROJECT_DIR)/Carthage/Build/iOS", 621 | ); 622 | INFOPLIST_FILE = MapboxARKitDemoApp/Info.plist; 623 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 624 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKitDemoApp; 625 | PRODUCT_NAME = "$(TARGET_NAME)"; 626 | SWIFT_VERSION = 4.0; 627 | TARGETED_DEVICE_FAMILY = "1,2"; 628 | }; 629 | name = Debug; 630 | }; 631 | 40DEF9B71F3CE1570089629A /* Release */ = { 632 | isa = XCBuildConfiguration; 633 | buildSettings = { 634 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 635 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 636 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 637 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 638 | DEVELOPMENT_TEAM = ""; 639 | FRAMEWORK_SEARCH_PATHS = ( 640 | "$(inherited)", 641 | "$(PROJECT_DIR)/Carthage/Build/iOS", 642 | ); 643 | INFOPLIST_FILE = MapboxARKitDemoApp/Info.plist; 644 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 645 | PRODUCT_BUNDLE_IDENTIFIER = mapbox.com.MapboxARKitDemoApp; 646 | PRODUCT_NAME = "$(TARGET_NAME)"; 647 | SWIFT_VERSION = 4.0; 648 | TARGETED_DEVICE_FAMILY = "1,2"; 649 | }; 650 | name = Release; 651 | }; 652 | /* End XCBuildConfiguration section */ 653 | 654 | /* Begin XCConfigurationList section */ 655 | 40D7227E1F3A4F3D00466721 /* Build configuration list for PBXProject "MapboxARKit" */ = { 656 | isa = XCConfigurationList; 657 | buildConfigurations = ( 658 | 40D722961F3A4F3D00466721 /* Debug */, 659 | 40D722971F3A4F3D00466721 /* Release */, 660 | ); 661 | defaultConfigurationIsVisible = 0; 662 | defaultConfigurationName = Release; 663 | }; 664 | 40D722981F3A4F3D00466721 /* Build configuration list for PBXNativeTarget "MapboxARKit" */ = { 665 | isa = XCConfigurationList; 666 | buildConfigurations = ( 667 | 40D722991F3A4F3D00466721 /* Debug */, 668 | 40D7229A1F3A4F3D00466721 /* Release */, 669 | ); 670 | defaultConfigurationIsVisible = 0; 671 | defaultConfigurationName = Release; 672 | }; 673 | 40D7229B1F3A4F3D00466721 /* Build configuration list for PBXNativeTarget "MapboxARKitTests" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | 40D7229C1F3A4F3D00466721 /* Debug */, 677 | 40D7229D1F3A4F3D00466721 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | defaultConfigurationName = Release; 681 | }; 682 | 40DEF9B51F3CE1570089629A /* Build configuration list for PBXNativeTarget "MapboxARKitDemoApp" */ = { 683 | isa = XCConfigurationList; 684 | buildConfigurations = ( 685 | 40DEF9B61F3CE1570089629A /* Debug */, 686 | 40DEF9B71F3CE1570089629A /* Release */, 687 | ); 688 | defaultConfigurationIsVisible = 0; 689 | defaultConfigurationName = Release; 690 | }; 691 | /* End XCConfigurationList section */ 692 | }; 693 | rootObject = 40D7227B1F3A4F3D00466721 /* Project object */; 694 | } 695 | -------------------------------------------------------------------------------- /MapboxARKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MapboxARKit.xcodeproj/xcshareddata/xcschemes/MapboxARKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /MapboxARKit.xcodeproj/xcshareddata/xcschemes/MapboxARKitDemoApp.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 57 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 76 | 78 | 84 | 85 | 86 | 87 | 89 | 90 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /MapboxARKit/Annotation.swift: -------------------------------------------------------------------------------- 1 | import CoreLocation 2 | 3 | public class Annotation: NSObject { 4 | 5 | public var location: CLLocation 6 | public var calloutImage: UIImage? 7 | public var anchor: MBARAnchor? 8 | 9 | public init(location: CLLocation, calloutImage: UIImage?) { 10 | self.location = location 11 | self.calloutImage = calloutImage 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /MapboxARKit/AnnotationManager.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | import SpriteKit 3 | import CoreLocation 4 | 5 | @objc public protocol AnnotationManagerDelegate { 6 | 7 | @objc optional func node(for annotation: Annotation) -> SCNNode? 8 | @objc optional func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) 9 | 10 | } 11 | 12 | public class AnnotationManager: NSObject { 13 | 14 | public private(set) var session: ARSession 15 | public private(set) var sceneView: ARSCNView? 16 | public private(set) var anchors = [ARAnchor]() 17 | public private(set) var annotationsByAnchor = [ARAnchor: Annotation]() 18 | public private(set) var annotationsByNode = [SCNNode: Annotation]() 19 | public var delegate: AnnotationManagerDelegate? 20 | public var originLocation: CLLocation? 21 | 22 | public init(session: ARSession) { 23 | self.session = session 24 | } 25 | 26 | convenience public init(sceneView: ARSCNView) { 27 | self.init(session: sceneView.session) 28 | session = sceneView.session 29 | sceneView.delegate = self 30 | } 31 | 32 | public func addAnnotation(annotation: Annotation) { 33 | guard let originLocation = originLocation else { 34 | print("Warning: \(type(of: self)).\(#function) was called without first setting \(type(of: self)).originLocation") 35 | return 36 | } 37 | 38 | // Create a Mapbox AR anchor anchor at the transformed position 39 | let anchor = MBARAnchor(originLocation: originLocation, location: annotation.location) 40 | 41 | // Add the anchor to the session 42 | session.add(anchor: anchor) 43 | 44 | anchors.append(anchor) 45 | annotation.anchor = anchor 46 | annotationsByAnchor[anchor] = annotation 47 | } 48 | 49 | public func addAnnotations(annotations: [Annotation]) { 50 | for annotation in annotations { 51 | addAnnotation(annotation: annotation) 52 | } 53 | } 54 | 55 | public func removeAllAnnotations() { 56 | for anchor in anchors { 57 | session.remove(anchor: anchor) 58 | } 59 | 60 | anchors.removeAll() 61 | annotationsByAnchor.removeAll() 62 | } 63 | 64 | public func removeAnnotations(annotations: [Annotation]) { 65 | for annotation in annotations { 66 | removeAnnotation(annotation: annotation) 67 | } 68 | } 69 | 70 | public func removeAnnotation(annotation: Annotation) { 71 | if let anchor = annotation.anchor { 72 | session.remove(anchor: anchor) 73 | anchors.remove(at: anchors.index(of: anchor)!) 74 | annotationsByAnchor.removeValue(forKey: anchor) 75 | } 76 | } 77 | 78 | } 79 | 80 | // MARK: - ARSCNViewDelegate 81 | 82 | extension AnnotationManager: ARSCNViewDelegate { 83 | 84 | public func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) { 85 | delegate?.session?(session, cameraDidChangeTrackingState: camera) 86 | } 87 | 88 | public func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { 89 | 90 | // Handle MBARAnchor 91 | if let anchor = anchor as? MBARAnchor { 92 | let annotation = annotationsByAnchor[anchor]! 93 | 94 | var newNode: SCNNode! 95 | 96 | // If the delegate supplied a node then use that, otherwise provide a basic default node 97 | if let suppliedNode = delegate?.node?(for: annotation) { 98 | newNode = suppliedNode 99 | } else { 100 | newNode = createDefaultNode() 101 | } 102 | 103 | if let calloutImage = annotation.calloutImage { 104 | let calloutNode = createCalloutNode(with: calloutImage, node: newNode) 105 | newNode.addChildNode(calloutNode) 106 | } 107 | 108 | node.addChildNode(newNode) 109 | 110 | annotationsByNode[newNode] = annotation 111 | } 112 | 113 | // TODO: let delegate provide a node for a non-MBARAnchor 114 | } 115 | 116 | // MARK: - Utility methods for ARSCNViewDelegate 117 | 118 | func createDefaultNode() -> SCNNode { 119 | let geometry = SCNSphere(radius: 0.2) 120 | geometry.firstMaterial?.diffuse.contents = UIColor.red 121 | return SCNNode(geometry: geometry) 122 | } 123 | 124 | func createCalloutNode(with image: UIImage, node: SCNNode) -> SCNNode { 125 | 126 | var width: CGFloat = 0.0 127 | var height: CGFloat = 0.0 128 | 129 | if image.size.width >= image.size.height { 130 | width = image.size.width / image.size.height 131 | height = 1.0 132 | } else { 133 | width = 1.0 134 | height = image.size.height / image.size.width 135 | } 136 | 137 | let calloutGeometry = SCNPlane(width: width, height: height) 138 | calloutGeometry.firstMaterial?.diffuse.contents = image 139 | 140 | let calloutNode = SCNNode(geometry: calloutGeometry) 141 | var nodePosition = node.position 142 | let (min, max) = node.boundingBox 143 | let nodeHeight = max.y - min.y 144 | nodePosition.y = nodeHeight + 0.5 145 | 146 | calloutNode.position = nodePosition 147 | 148 | let constraint = SCNBillboardConstraint() 149 | constraint.freeAxes = [.Y] 150 | calloutNode.constraints = [constraint] 151 | 152 | return calloutNode 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /MapboxARKit/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MapboxARKit/MBARAnchor.swift: -------------------------------------------------------------------------------- 1 | import ARKit 2 | import CoreLocation 3 | import Turf 4 | 5 | public class MBARAnchor: ARAnchor { 6 | 7 | public var calloutString: String? 8 | 9 | public convenience init(originLocation: CLLocation, location: CLLocation) { 10 | let transform = matrix_identity_float4x4.transformMatrix(originLocation: originLocation, location: location) 11 | self.init(transform: transform) 12 | } 13 | 14 | } 15 | 16 | internal extension simd_float4x4 { 17 | 18 | // Effectively copy the position of the start location, rotate it about 19 | // the bearing of the end location and "push" it out the required distance 20 | func transformMatrix(originLocation: CLLocation, location: CLLocation) -> simd_float4x4 { 21 | // Determine the distance and bearing between the start and end locations 22 | let distance = Float(location.distance(from: originLocation)) 23 | let bearing = GLKMathDegreesToRadians(Float(originLocation.coordinate.direction(to: location.coordinate))) 24 | 25 | // Effectively copy the position of the start location, rotate it about 26 | // the bearing of the end location and "push" it out the required distance 27 | let position = vector_float4(0.0, 0.0, -distance, 0.0) 28 | let translationMatrix = matrix_identity_float4x4.translationMatrix(position) 29 | let rotationMatrix = matrix_identity_float4x4.rotationAroundY(radians: bearing) 30 | let transformMatrix = simd_mul(rotationMatrix, translationMatrix) 31 | return simd_mul(self, transformMatrix) 32 | } 33 | 34 | } 35 | 36 | internal extension matrix_float4x4 { 37 | 38 | func rotationAroundY(radians: Float) -> matrix_float4x4 { 39 | var m : matrix_float4x4 = self; 40 | 41 | m.columns.0.x = cos(radians); 42 | m.columns.0.z = -sin(radians); 43 | 44 | m.columns.2.x = sin(radians); 45 | m.columns.2.z = cos(radians); 46 | 47 | return m.inverse; 48 | } 49 | 50 | func translationMatrix(_ translation : vector_float4) -> matrix_float4x4 { 51 | var m : matrix_float4x4 = self 52 | m.columns.3 = translation 53 | return m 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /MapboxARKit/MapboxARKit.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | //! Project version number for MapboxARKit. 4 | FOUNDATION_EXPORT double MapboxARKitVersionNumber; 5 | 6 | //! Project version string for MapboxARKit. 7 | FOUNDATION_EXPORT const unsigned char MapboxARKitVersionString[]; 8 | 9 | // In this header, you should import all the public headers of your framework using statements like #import 10 | 11 | 12 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | var window: UIWindow? 7 | 8 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 9 | return true 10 | } 11 | 12 | } 13 | 14 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/arrived.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "arrived.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/arrived.imageset/arrived.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/Assets.xcassets/arrived.imageset/arrived.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/crosshairs.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "crosshairs.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/crosshairs.imageset/crosshairs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/Assets.xcassets/crosshairs.imageset/crosshairs.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/straightahead.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "straightahead.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/straightahead.imageset/straightahead.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/Assets.xcassets/straightahead.imageset/straightahead.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/turnleft.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "turnleft.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/turnleft.imageset/turnleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/Assets.xcassets/turnleft.imageset/turnleft.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/turnright.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "turnright.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Assets.xcassets/turnright.imageset/turnright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/Assets.xcassets/turnright.imageset/turnright.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | MapboxDirectionsARKitDemo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | MGLMapboxAccessToken 26 | <access_token> 27 | NSCameraUsageDescription 28 | This application will use the camera for Augmented Reality. 29 | NSLocationWhenInUseUsageDescription 30 | Mapbox ARKit demo 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UIStatusBarHidden 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | 45 | UISupportedInterfaceOrientations~ipad 46 | 47 | UIInterfaceOrientationPortrait 48 | UIInterfaceOrientationPortraitUpsideDown 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/ViewController.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import ARKit 3 | import SceneKit 4 | import SpriteKit 5 | import CoreLocation 6 | 7 | import MapboxARKit 8 | import Mapbox 9 | import MapboxDirections 10 | import Turf 11 | 12 | class ViewController: UIViewController { 13 | 14 | // **** 15 | // * NOTE: There is currently an issue with the Xcode beta and GPU frame capture 16 | // * https://stackoverflow.com/questions/45368426/mapbox-crashes-when-used-with-scenekit 17 | // * You can fix that by following these instructions 18 | // * https://stackoverflow.com/questions/31264537/adding-google-maps-as-subview-crashes-ios-app-with-exc-bad/31445847#31445847 19 | // **** 20 | 21 | // Use this to control how ARKit aligns itself to the world 22 | // Often ARKit can determine the direction of North well enough for 23 | // the demo to work. However, its accuracy can be poor and it can 24 | // often make more sense to manually help the demo calibrate by starting 25 | // app while facing North. If you do that, change this setting to false 26 | var automaticallyFindTrueNorth = true 27 | 28 | @IBOutlet weak var cameraStateInfoLabel: UILabel! 29 | @IBOutlet weak var mapView: MGLMapView! 30 | @IBOutlet var sceneView: ARSCNView! 31 | @IBOutlet weak var controlsContainerView: UIView! 32 | 33 | // Create an instance of MapboxDirections to simplify querying the Mapbox Directions API 34 | let directions = Directions.shared 35 | var annotationManager: AnnotationManager! 36 | 37 | // Define a shape collection that will be used to hold the point geometries that define the 38 | // directions routeline 39 | var waypointShapeCollectionFeature: MGLShapeCollectionFeature? 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | 44 | // Configure and style control and map views 45 | styleControlViewContainer() 46 | configureMapboxMapView() 47 | 48 | // SceneKit 49 | sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin] 50 | sceneView.scene = SCNScene() 51 | 52 | // Create an AR annotation manager and give it a reference to the AR scene view 53 | annotationManager = AnnotationManager(sceneView: sceneView) 54 | annotationManager.delegate = self 55 | } 56 | 57 | override func viewDidAppear(_ animated: Bool) { 58 | super.viewDidAppear(animated) 59 | 60 | // Start the AR session 61 | startSession() 62 | } 63 | 64 | override func viewWillDisappear(_ animated: Bool) { 65 | super.viewWillDisappear(animated) 66 | 67 | // Pause the view's session 68 | sceneView.session.pause() 69 | } 70 | 71 | // MARK: - Actions 72 | 73 | // Handle a long press on the Mapbox map view 74 | @IBAction func didLongPress(_ recognizer: UILongPressGestureRecognizer) { 75 | // Find the geographic coordinate of the point pressed in the map view 76 | let point = recognizer.location(in: mapView) 77 | let coordinate = mapView.convert(point, toCoordinateFrom: mapView) 78 | 79 | // Remove any existing annotations on the map view 80 | if let existingAnnotations = mapView.annotations { 81 | mapView.removeAnnotations(existingAnnotations) 82 | } 83 | 84 | // Add an annotation to the map view for the pressed point 85 | let annotation = MGLPointAnnotation() 86 | annotation.coordinate = coordinate 87 | mapView.addAnnotation(annotation) 88 | 89 | // When the gesture ends use the annotation location to initiate a query to the Mapbox Directions API 90 | if recognizer.state == .ended { 91 | 92 | // remove any previously rendered route 93 | annotationManager.removeAllAnnotations() 94 | resetShapeCollectionFeature(&waypointShapeCollectionFeature) 95 | self.updateSource(identifer: "annotationSource", shape: self.waypointShapeCollectionFeature) 96 | 97 | // Create a CLLocation instance to represent the end location for the directions query 98 | let annotationLocation = CLLocation(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude) 99 | queryDirections(with: annotationLocation) 100 | } 101 | } 102 | 103 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 104 | guard let touch = touches.first else { return } 105 | let result = sceneView.hitTest(touch.location(in: sceneView), options: [SCNHitTestOption.firstFoundOnly : true]).first 106 | if let node = result?.node, let annotation = annotationManager.annotationsByNode[node] { 107 | annotationManager.removeAnnotation(annotation: annotation) 108 | } 109 | } 110 | 111 | // MARK: - Directions 112 | 113 | // Query the directions endpoint with waypoints that are the current center location of the map 114 | // as the start and the passed in location as the end 115 | func queryDirections(with endLocation: CLLocation) { 116 | let currentLocation = CLLocation(latitude: self.mapView.centerCoordinate.latitude, longitude: self.mapView.centerCoordinate.longitude) 117 | annotationManager.originLocation = currentLocation 118 | 119 | let waypoints = [ 120 | Waypoint(coordinate: CLLocationCoordinate2D(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude), name: "start"), 121 | Waypoint(coordinate: CLLocationCoordinate2D(latitude: endLocation.coordinate.latitude, longitude: endLocation.coordinate.longitude), name: "end"), 122 | ] 123 | 124 | // Ask for walking directions 125 | let options = RouteOptions(waypoints: waypoints, profileIdentifier: .walking) 126 | options.includesSteps = true 127 | 128 | var annotationsToAdd = [Annotation]() 129 | 130 | // Initiate the query 131 | let _ = directions.calculate(options) { (waypoints, routes, error) in 132 | guard error == nil else { 133 | print("Error calculating directions: \(error!)") 134 | return 135 | } 136 | 137 | // If a route is returned: 138 | if let route = routes?.first, let leg = route.legs.first { 139 | var polyline = [CLLocationCoordinate2D]() 140 | 141 | // Add an AR node and map view annotation for every defined "step" in the route 142 | for step in leg.steps { 143 | let coordinate = step.coordinates!.first! 144 | polyline.append(coordinate) 145 | let stepLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) 146 | 147 | // Update feature collection for map view 148 | self.updateShapeCollectionFeature(&self.waypointShapeCollectionFeature, with: stepLocation, typeKey: "waypoint-type", typeAttribute: "big") 149 | 150 | // Add an AR node 151 | let annotation = Annotation(location: stepLocation, calloutImage: self.calloutImage(for: step.description)) 152 | annotationsToAdd.append(annotation) 153 | } 154 | 155 | let metersPerNode: CLLocationDistance = 5 156 | let turfPolyline = Polyline(polyline) 157 | 158 | // Walk the route line and add a small AR node and map view annotation every metersPerNode 159 | for i in stride(from: metersPerNode, to: turfPolyline.distance() - metersPerNode, by: metersPerNode) { 160 | // Use Turf to find the coordinate of each incremented distance along the polyline 161 | if let nextCoordinate = turfPolyline.coordinateFromStart(distance: i) { 162 | let interpolatedStepLocation = CLLocation(latitude: nextCoordinate.latitude, longitude: nextCoordinate.longitude) 163 | 164 | // Update feature collection for map view 165 | self.updateShapeCollectionFeature(&self.waypointShapeCollectionFeature, with: interpolatedStepLocation, typeKey: "waypoint-type", typeAttribute: "small") 166 | 167 | // Add an AR node 168 | let annotation = Annotation(location: interpolatedStepLocation, calloutImage: nil) 169 | annotationsToAdd.append(annotation) 170 | } 171 | } 172 | 173 | // Update the source used for route line visualization with the latest waypoint shape collection 174 | self.updateSource(identifer: "annotationSource", shape: self.waypointShapeCollectionFeature) 175 | 176 | // Update the annotation manager with the latest AR annotations 177 | self.annotationManager.addAnnotations(annotations: annotationsToAdd) 178 | } 179 | } 180 | 181 | // Put the map view into a "follow with course" tracking mode 182 | mapView.userTrackingMode = .followWithCourse 183 | } 184 | 185 | // MARK: - Utility methods 186 | 187 | private func startSession() { 188 | // Create a session configuration 189 | let configuration = ARWorldTrackingConfiguration() 190 | 191 | if automaticallyFindTrueNorth { 192 | configuration.worldAlignment = .gravityAndHeading 193 | } else { 194 | configuration.worldAlignment = .gravity 195 | } 196 | 197 | // Run the view's session 198 | sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) 199 | } 200 | 201 | private func styleControlViewContainer() { 202 | let blurEffect = UIBlurEffect(style: .prominent) 203 | let blurView = UIVisualEffectView(effect: blurEffect) 204 | blurView.frame = controlsContainerView.bounds 205 | blurView.autoresizingMask = [.flexibleHeight, .flexibleWidth] 206 | controlsContainerView.insertSubview(blurView, belowSubview: mapView) 207 | } 208 | 209 | private func configureMapboxMapView() { 210 | mapView.delegate = self 211 | mapView.styleURL = URL(string: "mapbox://styles/mapbox/cj3kbeqzo00022smj7akz3o1e") // "Moonlight" style 212 | mapView.userTrackingMode = .followWithHeading 213 | mapView.layer.cornerRadius = 10 214 | } 215 | 216 | private func calloutImage(for stepDescription: String) -> UIImage? { 217 | 218 | let lowerCasedDescription = stepDescription.lowercased() 219 | var image: UIImage? 220 | 221 | if lowerCasedDescription.contains("arrived") { 222 | image = UIImage(named: "arrived") 223 | } else if lowerCasedDescription.contains("left") { 224 | image = UIImage(named: "turnleft") 225 | } else if lowerCasedDescription.contains("right") { 226 | image = UIImage(named: "turnright") 227 | } else if lowerCasedDescription.contains("head") { 228 | image = UIImage(named: "straightahead") 229 | } 230 | 231 | return image 232 | } 233 | 234 | } 235 | 236 | // MARK: - AnnotationManagerDelegate 237 | 238 | extension ViewController: AnnotationManagerDelegate { 239 | 240 | func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) { 241 | print("camera did change tracking state: \(camera.trackingState)") 242 | 243 | switch camera.trackingState { 244 | case .normal: 245 | cameraStateInfoLabel.text = "Ready!" 246 | UIView.animate(withDuration: 1, delay: 1, options: [], animations: { 247 | self.cameraStateInfoLabel.alpha = 0 248 | }, completion: nil) 249 | default: 250 | cameraStateInfoLabel.alpha = 1 251 | cameraStateInfoLabel.text = "Move the camera" 252 | } 253 | } 254 | 255 | func node(for annotation: Annotation) -> SCNNode? { 256 | 257 | if annotation.calloutImage == nil { 258 | // Comment `createLightBulbNode` and add `return nil` to use the default node 259 | return createLightBulbNode() 260 | } else { 261 | let firstColor = UIColor(red: 0.0, green: 99/255.0, blue: 175/255.0, alpha: 1.0) 262 | return createSphereNode(with: 0.5, firstColor: firstColor, secondColor: UIColor.green) 263 | } 264 | } 265 | 266 | // MARK: - Utility methods for AnnotationManagerDelegate 267 | 268 | func createSphereNode(with radius: CGFloat, firstColor: UIColor, secondColor: UIColor) -> SCNNode { 269 | let geometry = SCNSphere(radius: radius) 270 | geometry.firstMaterial?.diffuse.contents = firstColor 271 | 272 | let sphereNode = SCNNode(geometry: geometry) 273 | sphereNode.animateInterpolatedColor(from: firstColor, to: secondColor, duration: 1) 274 | 275 | return sphereNode 276 | } 277 | 278 | func createLightBulbNode() -> SCNNode { 279 | let lightBulbNode = collada2SCNNode(filepath: "art.scnassets/light-bulb.dae") 280 | lightBulbNode.scale = SCNVector3Make(0.25, 0.25, 0.25) 281 | return lightBulbNode 282 | } 283 | 284 | func collada2SCNNode(filepath:String) -> SCNNode { 285 | let node = SCNNode() 286 | let scene = SCNScene(named: filepath, inDirectory: nil, options: [SCNSceneSource.LoadingOption.animationImportPolicy: SCNSceneSource.AnimationImportPolicy.doNotPlay]) 287 | let nodeArray = scene!.rootNode.childNodes 288 | for childNode in nodeArray { 289 | node.addChildNode(childNode as SCNNode) 290 | } 291 | return node 292 | } 293 | 294 | } 295 | 296 | // MARK: - MGLMapViewDelegate 297 | 298 | extension ViewController: MGLMapViewDelegate { 299 | 300 | func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { 301 | // Set up Mapbox iOS Maps SDK "runtime styling" source and style layers to style the directions route line 302 | waypointShapeCollectionFeature = MGLShapeCollectionFeature() 303 | let annotationSource = MGLShapeSource(identifier: "annotationSource", shape: waypointShapeCollectionFeature, options: nil) 304 | mapView.style?.addSource(annotationSource) 305 | let circleStyleLayer = MGLCircleStyleLayer(identifier: "circleStyleLayer", source: annotationSource) 306 | 307 | let color = UIColor(red: 147/255.0, green: 230/255.0, blue: 249/255.0, alpha: 1.0) 308 | let colorStops = ["small": MGLStyleValue(rawValue: color.withAlphaComponent(0.75)), 309 | "big": MGLStyleValue(rawValue: color)] 310 | circleStyleLayer.circleColor = MGLStyleValue( 311 | interpolationMode: .categorical, 312 | sourceStops: colorStops, 313 | attributeName: "waypoint-type", 314 | options: nil 315 | ) 316 | let sizeStops = ["small": MGLStyleValue(rawValue: 2), 317 | "big": MGLStyleValue(rawValue: 4)] 318 | circleStyleLayer.circleRadius = MGLStyleValue( 319 | interpolationMode: .categorical, 320 | sourceStops: sizeStops, 321 | attributeName: "waypoint-type", 322 | options: nil 323 | ) 324 | mapView.style?.addLayer(circleStyleLayer) 325 | } 326 | 327 | func generateFeature(centerCoordinate: CLLocationCoordinate2D) -> MGLPointFeature { 328 | let feature = MGLPointFeature() 329 | feature.coordinate = centerCoordinate 330 | return feature 331 | } 332 | 333 | // MARK: - Utility methods for MGLMapViewDelegate 334 | 335 | private func updateSource(identifer: String, shape: MGLShape?) { 336 | guard let shape = shape else { 337 | return 338 | } 339 | 340 | if let source = mapView.style?.source(withIdentifier: identifer) as? MGLShapeSource { 341 | source.shape = shape 342 | } 343 | } 344 | 345 | private func updateShapeCollectionFeature(_ feature: inout MGLShapeCollectionFeature?, with location: CLLocation, typeKey: String?, typeAttribute: String?) { 346 | if let shapeCollectionFeature = feature { 347 | let annotation = MGLPointFeature() 348 | if let key = typeKey, let value = typeAttribute { 349 | annotation.attributes = [key: value] 350 | } 351 | annotation.coordinate = location.coordinate 352 | let newFeatures = [annotation].map { $0 as MGLShape } 353 | let existingFeatures: [MGLShape] = shapeCollectionFeature.shapes 354 | let allFeatures = newFeatures + existingFeatures 355 | feature = MGLShapeCollectionFeature(shapes: allFeatures) 356 | } 357 | } 358 | 359 | private func resetShapeCollectionFeature(_ feature: inout MGLShapeCollectionFeature?) { 360 | if feature != nil { 361 | feature = MGLShapeCollectionFeature(shapes: []) 362 | } 363 | } 364 | 365 | } 366 | 367 | extension SCNNode { 368 | 369 | func animateInterpolatedColor(from oldColor: UIColor, to newColor: UIColor, duration: Double) { 370 | let act0 = SCNAction.customAction(duration: duration, action: { (node, elapsedTime) in 371 | let percentage = elapsedTime / CGFloat(duration) 372 | self.geometry?.firstMaterial?.diffuse.contents = newColor.interpolatedColor(to: oldColor, percentage: percentage) 373 | }) 374 | let act1 = SCNAction.customAction(duration: duration, action: { (node, elapsedTime) in 375 | let percentage = elapsedTime / CGFloat(duration) 376 | self.geometry?.firstMaterial?.diffuse.contents = oldColor.interpolatedColor(to: newColor, percentage: percentage) 377 | }) 378 | 379 | let act = SCNAction.repeatForever(SCNAction.sequence([act0, act1])) 380 | self.runAction(act) 381 | } 382 | 383 | } 384 | 385 | extension UIColor { 386 | 387 | // https://stackoverflow.com/questions/40472524/how-to-add-animations-to-change-sncnodes-color-scenekit 388 | func interpolatedColor(to: UIColor, percentage: CGFloat) -> UIColor { 389 | let fromComponents = self.cgColor.components! 390 | let toComponents = to.cgColor.components! 391 | let color = UIColor(red: fromComponents[0] + (toComponents[0] - fromComponents[0]) * percentage, 392 | green: fromComponents[1] + (toComponents[1] - fromComponents[1]) * percentage, 393 | blue: fromComponents[2] + (toComponents[2] - fromComponents[2]) * percentage, 394 | alpha: fromComponents[3] + (toComponents[3] - fromComponents[3]) * percentage) 395 | return color 396 | } 397 | 398 | } 399 | -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/LED-Fluorescent-light-bulb-1---UV-LAYOUT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/LED-Fluorescent-light-bulb-1---UV-LAYOUT.png -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Metal_AO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Metal_AO.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Metal_BaseColor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Metal_BaseColor.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Metal_Glossiness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Metal_Glossiness.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Metal_Metallic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Metal_Metallic.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Plastic_AO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Plastic_AO.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Plastic_BaseColor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Plastic_BaseColor.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Plastic_Glossiness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Plastic_Glossiness.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Plastic_Metallic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Plastic_Metallic.jpg -------------------------------------------------------------------------------- /MapboxARKitDemoApp/art.scnassets/Plastic_Roughness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/MapboxARKitDemoApp/art.scnassets/Plastic_Roughness.jpg -------------------------------------------------------------------------------- /MapboxARKitTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MapboxARKitTests/MapboxARKitTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MapboxARKitTests.swift 3 | // MapboxARKitTests 4 | // 5 | // Created by Jesse Bounds on 8/8/17. 6 | // Copyright © 2017 Mapbox. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import MapboxARKit 11 | 12 | class MapboxARKitTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![mapbox+arkit](https://user-images.githubusercontent.com/5862541/29296653-7d786688-8110-11e7-95d7-776322499da4.png) 2 | 3 | 4 | Utilities for combining Mapbox maps and location services with ARKit in your applications. 5 | 6 | _**Warning:** The MapboxARKit API is **experimental** and will change. It is published to be able to get feedback from the community. Please use with caution and open issues for any problems you see or missing features that should be added._ 7 | 8 | ![](documentation/images/mapbox_directions_arkit.jpeg) 9 | 10 | ### Usage 11 | 12 | ##### Import MapboxARKit 13 | 14 | ```Swift 15 | import MapboxARKit 16 | ``` 17 | 18 | ##### Declare an an annotation manager instance in your view controller 19 | 20 | ```Swift 21 | ... 22 | @IBOutlet weak var sceneView: ARSCNView! 23 | var annotationManager: AnnotationManager! 24 | ... 25 | ``` 26 | 27 | ##### Create the annotation manager instance with ARSCNView instance and become the delegate 28 | 29 | The easist way to use MapboxARKit is to pass the ARSCNView and interact with the scene via the AnnotationManagerDelegate protocol. However, you can also initialize and `AnnotationManager` instance with only the ARKit session and handle all ARSCNView delegation yourself. 30 | 31 | ```Swift 32 | override func viewDidLoad() { 33 | super.viewDidLoad() 34 | 35 | // Create the annotation manager instance and give it an ARSCNView 36 | annotationManager = AnnotationManager(sceneView: sceneView) 37 | 38 | // Become the delegate of the annotation manager 39 | annotationManager.delegate = self 40 | 41 | } 42 | ``` 43 | 44 | ##### Monitor ARKit camera state readiness 45 | 46 | AnnotationManager monitors the ARSession and acts as a proxy for related notifications. This is useful for knowing when it makes sense to interact with the ARSession and ARSCNView and do thing like adding an `Annotation` instance 47 | 48 | ```Swift 49 | extension ViewController: AnnotationManagerDelegate { 50 | 51 | func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) { 52 | switch camera.trackingState { 53 | case .normal: 54 | // Tracking is sufficient to begin experience 55 | allowARInteractions() 56 | default: 57 | break 58 | } 59 | } 60 | } 61 | ``` 62 | 63 | ##### Annotation management of annotations that represent a real world location with a SceneKit node 64 | 65 | In view controller logic that is exercised after an ARSession is ready (see above), you can tell your AnnotationManager where it is in the world and ask it to place annotations (that are actually ARAnchor instances) representing other geographic locations in the world. 66 | 67 | ```Swift 68 | ... 69 | 70 | // Set the origin location of the annotation manager. The originLocation is a CLLocation that is as close as possible to the actual location (latitude, longitude) of the ARKit session origin point in the real world 71 | 72 | annotationManager.originLocation = originLocation 73 | 74 | // Create and add an annotation, MapboxARKit will supply a default red sphere as a SceneKit node to visualize the annotation if a node is not provided in an implementation of `AnnotationManagerDelegate.node(for:)` 75 | 76 | let annotation = Annotation(location: location, calloutImage: nil) 77 | annotationManager.addAnnotation(annotation: annotation) 78 | 79 | // Create and add an annotation with an image that will be shown above the annotation as a callout view. `calloutImage` is a UIImage 80 | 81 | let annotationWithCallout = Annotation(location: location, calloutImage: calloutImage) 82 | annotationManager.addAnnotation(annotation: annotationWithCallout) 83 | 84 | // Remove an annotation. The annotation manager will remove the annotation instance and its associated SceneKit node 85 | 86 | annotationManager.removeAnnotation(annotation: annotation) 87 | 88 | ... 89 | 90 | ``` 91 | 92 | ##### Provide your own SceneKit nodes for annotations 93 | 94 | Although MapboxARKit provides default red spheres to visualize added annotations, applications may want different nodes. This can be useful when adding 3d models. the `node(for:)` delegate method in `AnnotationManagerDelegate` allows an application to pass associate arbitrary nodes with annotations for a location. 95 | 96 | ```Swift 97 | extension ViewController: AnnotationManagerDelegate { 98 | func node(for annotation: Annotation) -> SCNNode? { 99 | return createSpecialNode(for: annotation) 100 | } 101 | } 102 | ``` 103 | 104 | ### Installation 105 | 106 | **Requirements:** 107 | * Xcode 9 or greater 108 | * An iDevice with an A9 (or greater) processor running iOS 11 or greater 109 | * [Carthage](https://github.com/Carthage/Carthage) (for development and running the sample app) 110 | * [CocoaPods](http://guides.cocoapods.org/using/getting-started.html#installation) (for installing the library in your own app) 111 | 112 | #### Adding MapboxARKit to your iOS app 113 | 114 | Although there has not yet been a beta release of this library yet, you can still experiment with it in your application by using CocoaPods to install it. Edit your Podfile to include: 115 | 116 | ``` 117 | # The MapboxARKit pod 118 | pod 'MapboxARKit', :git => 'https://github.com/mapbox/mapbox-arkit-ios.git' 119 | ``` 120 | 121 | #### Running the sample project 122 | 123 | * Run `scripts/setup.sh`. This script will check that you have Carthage installed and, if so, install the development dependencies 124 | * Open `MapboxARKit.xcodeproj` in Xcode 9 125 | * Select the `MapboxARKitDemoApp` scheme and target 126 | * Set your team identity for code signing 127 | * Create a file called `mapbox_access_token` in the root of the MapboxARKit project directory and write your [Mapbox Access Token](https://www.mapbox.com/studio/account/tokens/) in that file 128 | * Install and run the app **on a device** (ARKit cannot run in the simulator) 129 | -------------------------------------------------------------------------------- /documentation/images/mapbox_directions_arkit.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/mapbox-arkit-ios/0f470f1ababb3a18e44501f07dd090da4f901a60/documentation/images/mapbox_directions_arkit.jpeg -------------------------------------------------------------------------------- /scripts/setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if ! command -v carthage > /dev/null; then 4 | printf 'Carthage is not installed.\n' 5 | printf 'See https://github.com/Carthage/Carthage for install instructions.\n' 6 | exit 1 7 | fi 8 | 9 | carthage update --platform iOS 10 | --------------------------------------------------------------------------------