├── .DS_Store ├── SwiftUISceneKitDemo ├── .DS_Store ├── Assets.xcassets │ ├── Contents.json │ ├── AppIcon.appiconset │ │ ├── SwiftUISceneKitDemo-Icon@2x.png │ │ ├── SwiftUISceneKitDemo-Icon@3x.png │ │ └── Contents.json │ └── AccentColor.colorset │ │ └── Contents.json ├── art.scnassets │ ├── ship.scn │ └── texture.png ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── SwiftUISceneKitDemoApp.swift ├── Info.plist └── ContentView.swift ├── SwiftUISceneKitDemo.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── jdhouse4.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── README.md └── .gitignore /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/.DS_Store -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/SwiftUISceneKitDemo/.DS_Store -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/art.scnassets/ship.scn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/SwiftUISceneKitDemo/art.scnassets/ship.scn -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/art.scnassets/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/SwiftUISceneKitDemo/art.scnassets/texture.png -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Assets.xcassets/AppIcon.appiconset/SwiftUISceneKitDemo-Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/SwiftUISceneKitDemo/Assets.xcassets/AppIcon.appiconset/SwiftUISceneKitDemo-Icon@2x.png -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Assets.xcassets/AppIcon.appiconset/SwiftUISceneKitDemo-Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jdhouse4/SwiftUISceneKitDemo/HEAD/SwiftUISceneKitDemo/Assets.xcassets/AppIcon.appiconset/SwiftUISceneKitDemo-Icon@3x.png -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/SwiftUISceneKitDemoApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftUISceneKitDemoApp.swift 3 | // SwiftUISceneKitDemo 4 | // 5 | // Created by James Hillhouse IV on 10/17/20. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct SwiftUISceneKitDemoApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo.xcodeproj/xcuserdata/jdhouse4.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SwiftUISceneKitDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUISceneKitDemo 2 | 3 | On June 22, 2020 during the WWDC20 State of the Union, Apple announced that SwiftUI had been updated to include, among a great many other 4 | additions, SceneKit support. Specifically, SceneView was added as a View type, similar to SCNView. 5 | 6 | Unfortunately, there were no WWDC20 sessions on SceneKit or SceneView. This meant that those of us slower than most (I'm raising my hand here) 7 | experienced the very unpleasant experience of trying to figure out how to make SceneView work in all but the most rudementary of code. 8 | For example, how to implement changing a scene view's pointOfView? Or creating a gesture recognizer for pinch-to-zoom and dragging? How about a 9 | double-tap to reset the orientation of the scene view's scen model? What about turning lights on and off within the scene? 10 | 11 | When Xcode 12 was released, no project template existed for implementing SceneKit in SwiftUI. I can only assume that Apple's SceneKit team and 12 | most other Apple developers thought it so trivial to implement SceneView that a SwiftUI implementation of SceneView was thought unnecessary. For 13 | those of us, like I, for whom this is not the case, this demo app hopes to partly solve that. This app is modeled after the Xcode UIKit SceneKit 14 | template app using SwiftUI 2's SceneView. 15 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | 28 | UIApplicationSupportsIndirectInputEvents 29 | 30 | UILaunchScreen 31 | 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "SwiftUISceneKitDemo-Icon@2x.png", 35 | "idiom" : "iphone", 36 | "scale" : "2x", 37 | "size" : "60x60" 38 | }, 39 | { 40 | "filename" : "SwiftUISceneKitDemo-Icon@3x.png", 41 | "idiom" : "iphone", 42 | "scale" : "3x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "scale" : "1x", 48 | "size" : "20x20" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "scale" : "2x", 53 | "size" : "20x20" 54 | }, 55 | { 56 | "idiom" : "ipad", 57 | "scale" : "1x", 58 | "size" : "29x29" 59 | }, 60 | { 61 | "idiom" : "ipad", 62 | "scale" : "2x", 63 | "size" : "29x29" 64 | }, 65 | { 66 | "idiom" : "ipad", 67 | "scale" : "1x", 68 | "size" : "40x40" 69 | }, 70 | { 71 | "idiom" : "ipad", 72 | "scale" : "2x", 73 | "size" : "40x40" 74 | }, 75 | { 76 | "idiom" : "ipad", 77 | "scale" : "1x", 78 | "size" : "76x76" 79 | }, 80 | { 81 | "idiom" : "ipad", 82 | "scale" : "2x", 83 | "size" : "76x76" 84 | }, 85 | { 86 | "idiom" : "ipad", 87 | "scale" : "2x", 88 | "size" : "83.5x83.5" 89 | }, 90 | { 91 | "idiom" : "ios-marketing", 92 | "scale" : "1x", 93 | "size" : "1024x1024" 94 | } 95 | ], 96 | "info" : { 97 | "author" : "xcode", 98 | "version" : 1 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/swift,xcode 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=swift,xcode 4 | 5 | ### Swift ### 6 | # Xcode 7 | # 8 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 9 | 10 | ## User settings 11 | xcuserdata/ 12 | 13 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 14 | *.xcscmblueprint 15 | *.xccheckout 16 | 17 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 18 | build/ 19 | DerivedData/ 20 | *.moved-aside 21 | *.pbxuser 22 | !default.pbxuser 23 | *.mode1v3 24 | !default.mode1v3 25 | *.mode2v3 26 | !default.mode2v3 27 | *.perspectivev3 28 | !default.perspectivev3 29 | 30 | ## Obj-C/Swift specific 31 | *.hmap 32 | 33 | ## App packaging 34 | *.ipa 35 | *.dSYM.zip 36 | *.dSYM 37 | 38 | ## Playgrounds 39 | timeline.xctimeline 40 | playground.xcworkspace 41 | 42 | # Swift Package Manager 43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 44 | # Packages/ 45 | # Package.pins 46 | # Package.resolved 47 | # *.xcodeproj 48 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 49 | # hence it is not needed unless you have added a package configuration file to your project 50 | # .swiftpm 51 | 52 | .build/ 53 | 54 | # CocoaPods 55 | # We recommend against adding the Pods directory to your .gitignore. However 56 | # you should judge for yourself, the pros and cons are mentioned at: 57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 58 | # Pods/ 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 64 | # Carthage/Checkouts 65 | 66 | Carthage/Build/ 67 | 68 | # Accio dependency management 69 | Dependencies/ 70 | .accio/ 71 | 72 | # fastlane 73 | # It is recommended to not store the screenshots in the git repo. 74 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 75 | # For more information about the recommended setup visit: 76 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 77 | 78 | fastlane/report.xml 79 | fastlane/Preview.html 80 | fastlane/screenshots/**/*.png 81 | fastlane/test_output 82 | 83 | # Code Injection 84 | # After new code Injection tools there's a generated folder /iOSInjectionProject 85 | # https://github.com/johnno1962/injectionforxcode 86 | 87 | iOSInjectionProject/ 88 | 89 | ### Xcode ### 90 | # Xcode 91 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 92 | 93 | 94 | 95 | 96 | ## Gcc Patch 97 | /*.gcno 98 | 99 | ### Xcode Patch ### 100 | *.xcodeproj/* 101 | !*.xcodeproj/project.pbxproj 102 | !*.xcodeproj/xcshareddata/ 103 | !*.xcworkspace/contents.xcworkspacedata 104 | **/xcshareddata/WorkspaceSettings.xcsettings 105 | 106 | # End of https://www.toptal.com/developers/gitignore/api/swift,xcode 107 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // SwiftUISceneKitDemo 4 | // 5 | // Created by James Hillhouse IV on 10/17/20. 6 | // 7 | 8 | import SwiftUI 9 | import SceneKit 10 | 11 | 12 | 13 | 14 | struct ContentView: View { 15 | @State private var sunlightSwitch = true 16 | @State private var cameraSwitch = true 17 | @State private var povName = "distantCamera" 18 | @State private var magnification = CGFloat(1.0) 19 | @State private var isDragging = false 20 | @State private var totalChangePivot = SCNMatrix4Identity 21 | 22 | private var aircraftScene = SCNScene(named: "art.scnassets/ship.scn")! 23 | 24 | // SceneView.Options for affecting the SceneView. 25 | // Uncomment if you would like to have Apple do all of the camera control 26 | //private var sceneViewCameraOption = SceneView.Options.allowsCameraControl 27 | 28 | // Don't forget to comment this is you are using .allowsCameraControl 29 | var drag: some Gesture { 30 | DragGesture() 31 | .onChanged { value in 32 | self.isDragging = true 33 | 34 | changeOrientation(of: aircraftScene.rootNode.childNode(withName: "shipNode", recursively: true)!, with: value.translation) 35 | } 36 | .onEnded { value in 37 | self.isDragging = false 38 | 39 | updateOrientation(of: aircraftScene.rootNode.childNode(withName: "shipNode", recursively: true)!) 40 | } 41 | } 42 | 43 | // Don't forget to comment this is you are using .allowsCameraControl 44 | var magnify: some Gesture { 45 | MagnificationGesture() 46 | .onChanged{ (value) in 47 | print("magnify = \(self.magnification)") 48 | 49 | self.magnification = value 50 | 51 | changeCameraFOV(of: (self.aircraftScene.rootNode.childNode(withName: povName, recursively: true)?.camera)!, 52 | value: self.magnification) 53 | } 54 | .onEnded{ value in 55 | print("Ended pinch with value \(value)\n\n") 56 | } 57 | } 58 | 59 | // Don't forget to comment this is you are using .allowsCameraControl 60 | var exclusiveGesture: some Gesture { 61 | ExclusiveGesture(drag, magnify) 62 | } 63 | 64 | 65 | 66 | var body: some View { 67 | ZStack { 68 | Color.black.edgesIgnoringSafeArea(.all) 69 | 70 | SceneView ( 71 | scene: aircraftScene, 72 | pointOfView: aircraftScene.rootNode.childNode(withName: povName, recursively: true) 73 | ) 74 | .gesture(exclusiveGesture) 75 | .onTapGesture(count: 2, perform: { 76 | resetOrientation(of: aircraftScene.rootNode.childNode(withName: "shipNode", recursively: true)!) 77 | }) 78 | 79 | VStack() { 80 | Text("Hello, SwiftUI!").multilineTextAlignment(.leading).padding() 81 | .foregroundColor(Color.gray) 82 | 83 | .font(.largeTitle) 84 | 85 | Text("And SceneView too") 86 | .foregroundColor(Color.gray) 87 | .font(.title2) 88 | 89 | Spacer(minLength: 300) 90 | 91 | HStack (spacing: 5) { 92 | 93 | Button( action: { 94 | withAnimation{ 95 | self.sunlightSwitch.toggle() 96 | } 97 | let sunlight = self.aircraftScene.rootNode.childNode(withName: "sunlightNode", recursively: true)?.light 98 | 99 | if self.sunlightSwitch == true { 100 | sunlight!.intensity = 2000.0 101 | } else { 102 | sunlight!.intensity = 0.0 103 | } 104 | }) { 105 | Image(systemName: sunlightSwitch ? "lightbulb.fill" : "lightbulb") 106 | .imageScale(.large) 107 | .accessibility(label: Text("Light Switch")) 108 | .padding() 109 | } 110 | 111 | Button( action: { 112 | withAnimation { 113 | self.cameraSwitch.toggle() 114 | } 115 | if self.cameraSwitch == false { 116 | povName = "shipCamera" 117 | } 118 | if self.cameraSwitch == true { 119 | povName = "distantCamera" 120 | } 121 | print("\(povName)") 122 | }) { 123 | Image(systemName: cameraSwitch ? "video.fill" : "video") 124 | .imageScale(.large) 125 | .accessibility(label: Text("Camera Switch")) 126 | .padding() 127 | } 128 | } 129 | } 130 | } 131 | .statusBar(hidden: true) 132 | } 133 | 134 | 135 | 136 | private func changeOrientation(of node: SCNNode, with translation: CGSize) { 137 | let x = Float(translation.width) 138 | let y = Float(-translation.height) 139 | 140 | let anglePan = sqrt(pow(x,2)+pow(y,2)) * (Float)(Double.pi) / 180.0 141 | 142 | var rotationVector = SCNVector4() 143 | 144 | rotationVector.x = -y 145 | rotationVector.y = x 146 | rotationVector.z = 0 147 | rotationVector.w = anglePan 148 | 149 | node.rotation = rotationVector 150 | } 151 | 152 | 153 | 154 | private func updateOrientation(of node: SCNNode) { 155 | let currentPivot = node.pivot 156 | 157 | let changePivot = SCNMatrix4Invert(node.transform) 158 | 159 | totalChangePivot = SCNMatrix4Mult(changePivot, currentPivot) 160 | 161 | node.pivot = SCNMatrix4Mult(changePivot, currentPivot) 162 | 163 | node.transform = SCNMatrix4Identity 164 | } 165 | 166 | 167 | 168 | private func resetOrientation(of node: SCNNode) { 169 | let currentPivot = node.pivot 170 | //print("currentPivot: \(currentPivot)") 171 | 172 | let changePivot = SCNMatrix4Invert( totalChangePivot ) 173 | //print("changePivot = \(changePivot)") 174 | 175 | node.pivot = SCNMatrix4Mult(changePivot, currentPivot) 176 | 177 | totalChangePivot = SCNMatrix4Identity 178 | } 179 | 180 | 181 | 182 | private func changeCameraFOV(of camera: SCNCamera, value: CGFloat) { 183 | if self.magnification >= 1.025 { 184 | self.magnification = 1.025 185 | } 186 | if self.magnification <= 0.97 { 187 | self.magnification = 0.97 188 | } 189 | 190 | let maximumFOV: CGFloat = 25 // Zoom-in. 191 | let minimumFOV: CGFloat = 90 // Zoom-out. 192 | 193 | camera.fieldOfView /= magnification 194 | 195 | if camera.fieldOfView <= maximumFOV { 196 | camera.fieldOfView = maximumFOV 197 | self.magnification = 1.0 198 | } 199 | if camera.fieldOfView >= minimumFOV { 200 | camera.fieldOfView = minimumFOV 201 | self.magnification = 1.0 202 | } 203 | } 204 | } 205 | 206 | 207 | 208 | 209 | struct ContentView_Previews: PreviewProvider { 210 | static var previews: some View { 211 | ContentView() 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /SwiftUISceneKitDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E68406DF253BAA1400E621F1 /* SwiftUISceneKitDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68406DE253BAA1400E621F1 /* SwiftUISceneKitDemoApp.swift */; }; 11 | E68406E1253BAA1400E621F1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68406E0253BAA1400E621F1 /* ContentView.swift */; }; 12 | E68406E3253BAA1600E621F1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E68406E2253BAA1600E621F1 /* Assets.xcassets */; }; 13 | E68406E6253BAA1600E621F1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E68406E5253BAA1600E621F1 /* Preview Assets.xcassets */; }; 14 | E68406EF253BAA5E00E621F1 /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = E68406EE253BAA5E00E621F1 /* art.scnassets */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | E68406DB253BAA1400E621F1 /* SwiftUISceneKitDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUISceneKitDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | E68406DE253BAA1400E621F1 /* SwiftUISceneKitDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUISceneKitDemoApp.swift; sourceTree = ""; }; 20 | E68406E0253BAA1400E621F1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 21 | E68406E2253BAA1600E621F1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 22 | E68406E5253BAA1600E621F1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 23 | E68406E7253BAA1600E621F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 24 | E68406EE253BAA5E00E621F1 /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = art.scnassets; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | E68406D8253BAA1400E621F1 /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXFrameworksBuildPhase section */ 36 | 37 | /* Begin PBXGroup section */ 38 | E68406D2253BAA1400E621F1 = { 39 | isa = PBXGroup; 40 | children = ( 41 | E68406DD253BAA1400E621F1 /* SwiftUISceneKitDemo */, 42 | E68406DC253BAA1400E621F1 /* Products */, 43 | ); 44 | sourceTree = ""; 45 | }; 46 | E68406DC253BAA1400E621F1 /* Products */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | E68406DB253BAA1400E621F1 /* SwiftUISceneKitDemo.app */, 50 | ); 51 | name = Products; 52 | sourceTree = ""; 53 | }; 54 | E68406DD253BAA1400E621F1 /* SwiftUISceneKitDemo */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | E68406DE253BAA1400E621F1 /* SwiftUISceneKitDemoApp.swift */, 58 | E68406E0253BAA1400E621F1 /* ContentView.swift */, 59 | E68406E2253BAA1600E621F1 /* Assets.xcassets */, 60 | E68406EE253BAA5E00E621F1 /* art.scnassets */, 61 | E68406E7253BAA1600E621F1 /* Info.plist */, 62 | E68406E4253BAA1600E621F1 /* Preview Content */, 63 | ); 64 | path = SwiftUISceneKitDemo; 65 | sourceTree = ""; 66 | }; 67 | E68406E4253BAA1600E621F1 /* Preview Content */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | E68406E5253BAA1600E621F1 /* Preview Assets.xcassets */, 71 | ); 72 | path = "Preview Content"; 73 | sourceTree = ""; 74 | }; 75 | /* End PBXGroup section */ 76 | 77 | /* Begin PBXNativeTarget section */ 78 | E68406DA253BAA1400E621F1 /* SwiftUISceneKitDemo */ = { 79 | isa = PBXNativeTarget; 80 | buildConfigurationList = E68406EA253BAA1600E621F1 /* Build configuration list for PBXNativeTarget "SwiftUISceneKitDemo" */; 81 | buildPhases = ( 82 | E68406D7253BAA1400E621F1 /* Sources */, 83 | E68406D8253BAA1400E621F1 /* Frameworks */, 84 | E68406D9253BAA1400E621F1 /* Resources */, 85 | ); 86 | buildRules = ( 87 | ); 88 | dependencies = ( 89 | ); 90 | name = SwiftUISceneKitDemo; 91 | productName = SwiftUISceneKitDemo; 92 | productReference = E68406DB253BAA1400E621F1 /* SwiftUISceneKitDemo.app */; 93 | productType = "com.apple.product-type.application"; 94 | }; 95 | /* End PBXNativeTarget section */ 96 | 97 | /* Begin PBXProject section */ 98 | E68406D3253BAA1400E621F1 /* Project object */ = { 99 | isa = PBXProject; 100 | attributes = { 101 | LastSwiftUpdateCheck = 1220; 102 | LastUpgradeCheck = 1220; 103 | TargetAttributes = { 104 | E68406DA253BAA1400E621F1 = { 105 | CreatedOnToolsVersion = 12.2; 106 | }; 107 | }; 108 | }; 109 | buildConfigurationList = E68406D6253BAA1400E621F1 /* Build configuration list for PBXProject "SwiftUISceneKitDemo" */; 110 | compatibilityVersion = "Xcode 9.3"; 111 | developmentRegion = en; 112 | hasScannedForEncodings = 0; 113 | knownRegions = ( 114 | en, 115 | Base, 116 | ); 117 | mainGroup = E68406D2253BAA1400E621F1; 118 | productRefGroup = E68406DC253BAA1400E621F1 /* Products */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | E68406DA253BAA1400E621F1 /* SwiftUISceneKitDemo */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXResourcesBuildPhase section */ 128 | E68406D9253BAA1400E621F1 /* Resources */ = { 129 | isa = PBXResourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | E68406E6253BAA1600E621F1 /* Preview Assets.xcassets in Resources */, 133 | E68406EF253BAA5E00E621F1 /* art.scnassets in Resources */, 134 | E68406E3253BAA1600E621F1 /* Assets.xcassets in Resources */, 135 | ); 136 | runOnlyForDeploymentPostprocessing = 0; 137 | }; 138 | /* End PBXResourcesBuildPhase section */ 139 | 140 | /* Begin PBXSourcesBuildPhase section */ 141 | E68406D7253BAA1400E621F1 /* Sources */ = { 142 | isa = PBXSourcesBuildPhase; 143 | buildActionMask = 2147483647; 144 | files = ( 145 | E68406E1253BAA1400E621F1 /* ContentView.swift in Sources */, 146 | E68406DF253BAA1400E621F1 /* SwiftUISceneKitDemoApp.swift in Sources */, 147 | ); 148 | runOnlyForDeploymentPostprocessing = 0; 149 | }; 150 | /* End PBXSourcesBuildPhase section */ 151 | 152 | /* Begin XCBuildConfiguration section */ 153 | E68406E8253BAA1600E621F1 /* Debug */ = { 154 | isa = XCBuildConfiguration; 155 | buildSettings = { 156 | ALWAYS_SEARCH_USER_PATHS = NO; 157 | CLANG_ANALYZER_NONNULL = YES; 158 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 159 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 160 | CLANG_CXX_LIBRARY = "libc++"; 161 | CLANG_ENABLE_MODULES = YES; 162 | CLANG_ENABLE_OBJC_ARC = YES; 163 | CLANG_ENABLE_OBJC_WEAK = YES; 164 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 165 | CLANG_WARN_BOOL_CONVERSION = YES; 166 | CLANG_WARN_COMMA = YES; 167 | CLANG_WARN_CONSTANT_CONVERSION = YES; 168 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 169 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 170 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 171 | CLANG_WARN_EMPTY_BODY = YES; 172 | CLANG_WARN_ENUM_CONVERSION = YES; 173 | CLANG_WARN_INFINITE_RECURSION = YES; 174 | CLANG_WARN_INT_CONVERSION = YES; 175 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 176 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 177 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 178 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 179 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 180 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 181 | CLANG_WARN_STRICT_PROTOTYPES = YES; 182 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 183 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 184 | CLANG_WARN_UNREACHABLE_CODE = YES; 185 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 186 | COPY_PHASE_STRIP = NO; 187 | DEBUG_INFORMATION_FORMAT = dwarf; 188 | ENABLE_STRICT_OBJC_MSGSEND = YES; 189 | ENABLE_TESTABILITY = YES; 190 | GCC_C_LANGUAGE_STANDARD = gnu11; 191 | GCC_DYNAMIC_NO_PIC = NO; 192 | GCC_NO_COMMON_BLOCKS = YES; 193 | GCC_OPTIMIZATION_LEVEL = 0; 194 | GCC_PREPROCESSOR_DEFINITIONS = ( 195 | "DEBUG=1", 196 | "$(inherited)", 197 | ); 198 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 199 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 200 | GCC_WARN_UNDECLARED_SELECTOR = YES; 201 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 202 | GCC_WARN_UNUSED_FUNCTION = YES; 203 | GCC_WARN_UNUSED_VARIABLE = YES; 204 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 205 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 206 | MTL_FAST_MATH = YES; 207 | ONLY_ACTIVE_ARCH = YES; 208 | SDKROOT = iphoneos; 209 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 210 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 211 | }; 212 | name = Debug; 213 | }; 214 | E68406E9253BAA1600E621F1 /* Release */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | ALWAYS_SEARCH_USER_PATHS = NO; 218 | CLANG_ANALYZER_NONNULL = YES; 219 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 220 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 221 | CLANG_CXX_LIBRARY = "libc++"; 222 | CLANG_ENABLE_MODULES = YES; 223 | CLANG_ENABLE_OBJC_ARC = YES; 224 | CLANG_ENABLE_OBJC_WEAK = YES; 225 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_COMMA = YES; 228 | CLANG_WARN_CONSTANT_CONVERSION = YES; 229 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 230 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 231 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 232 | CLANG_WARN_EMPTY_BODY = YES; 233 | CLANG_WARN_ENUM_CONVERSION = YES; 234 | CLANG_WARN_INFINITE_RECURSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 237 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 238 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 239 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 240 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 241 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 242 | CLANG_WARN_STRICT_PROTOTYPES = YES; 243 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 244 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 245 | CLANG_WARN_UNREACHABLE_CODE = YES; 246 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 247 | COPY_PHASE_STRIP = NO; 248 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 249 | ENABLE_NS_ASSERTIONS = NO; 250 | ENABLE_STRICT_OBJC_MSGSEND = YES; 251 | GCC_C_LANGUAGE_STANDARD = gnu11; 252 | GCC_NO_COMMON_BLOCKS = YES; 253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 255 | GCC_WARN_UNDECLARED_SELECTOR = YES; 256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 257 | GCC_WARN_UNUSED_FUNCTION = YES; 258 | GCC_WARN_UNUSED_VARIABLE = YES; 259 | IPHONEOS_DEPLOYMENT_TARGET = 14.2; 260 | MTL_ENABLE_DEBUG_INFO = NO; 261 | MTL_FAST_MATH = YES; 262 | SDKROOT = iphoneos; 263 | SWIFT_COMPILATION_MODE = wholemodule; 264 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 265 | VALIDATE_PRODUCT = YES; 266 | }; 267 | name = Release; 268 | }; 269 | E68406EB253BAA1600E621F1 /* Debug */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 273 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 274 | CODE_SIGN_STYLE = Automatic; 275 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUISceneKitDemo/Preview Content\""; 276 | DEVELOPMENT_TEAM = 7CCAB8L658; 277 | ENABLE_PREVIEWS = YES; 278 | INFOPLIST_FILE = SwiftUISceneKitDemo/Info.plist; 279 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 280 | LD_RUNPATH_SEARCH_PATHS = ( 281 | "$(inherited)", 282 | "@executable_path/Frameworks", 283 | ); 284 | PRODUCT_BUNDLE_IDENTIFIER = com.portablefrontier.SwiftUISceneKitDemo; 285 | PRODUCT_NAME = "$(TARGET_NAME)"; 286 | SWIFT_VERSION = 5.0; 287 | TARGETED_DEVICE_FAMILY = "1,2"; 288 | }; 289 | name = Debug; 290 | }; 291 | E68406EC253BAA1600E621F1 /* Release */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 295 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 296 | CODE_SIGN_STYLE = Automatic; 297 | DEVELOPMENT_ASSET_PATHS = "\"SwiftUISceneKitDemo/Preview Content\""; 298 | DEVELOPMENT_TEAM = 7CCAB8L658; 299 | ENABLE_PREVIEWS = YES; 300 | INFOPLIST_FILE = SwiftUISceneKitDemo/Info.plist; 301 | IPHONEOS_DEPLOYMENT_TARGET = 14.0; 302 | LD_RUNPATH_SEARCH_PATHS = ( 303 | "$(inherited)", 304 | "@executable_path/Frameworks", 305 | ); 306 | PRODUCT_BUNDLE_IDENTIFIER = com.portablefrontier.SwiftUISceneKitDemo; 307 | PRODUCT_NAME = "$(TARGET_NAME)"; 308 | SWIFT_VERSION = 5.0; 309 | TARGETED_DEVICE_FAMILY = "1,2"; 310 | }; 311 | name = Release; 312 | }; 313 | /* End XCBuildConfiguration section */ 314 | 315 | /* Begin XCConfigurationList section */ 316 | E68406D6253BAA1400E621F1 /* Build configuration list for PBXProject "SwiftUISceneKitDemo" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | E68406E8253BAA1600E621F1 /* Debug */, 320 | E68406E9253BAA1600E621F1 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | defaultConfigurationName = Release; 324 | }; 325 | E68406EA253BAA1600E621F1 /* Build configuration list for PBXNativeTarget "SwiftUISceneKitDemo" */ = { 326 | isa = XCConfigurationList; 327 | buildConfigurations = ( 328 | E68406EB253BAA1600E621F1 /* Debug */, 329 | E68406EC253BAA1600E621F1 /* Release */, 330 | ); 331 | defaultConfigurationIsVisible = 0; 332 | defaultConfigurationName = Release; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = E68406D3253BAA1400E621F1 /* Project object */; 337 | } 338 | --------------------------------------------------------------------------------