I’ve been experimenting with ARKit on Swift Playgrounds. I’ve written the starter code, but when I run it nothing happens. Instead of evaluating the code, it displays the pop up that shows ay issues in the code.
I know the code I’m using works, because I’ve used the same code on an iPad running an older version of Swift Playgrounds and the code works perfectly. It seems to be a problem with either Swift Playgrounds 3 or Swift 5.
Here’s the interesting part. When I remove the line of code that runs the ARWorldTrackingConfiguration
initializer, and the code that makes the view controller the delegate of the session and scene, the code runs just fine. When I put it back, it does the same error again. I don’t know what’s going wrong.
I’m running Swift Playgrounds 3.0 on and iPad 6th Generation. The playground uses ARKit, UIKit, SceneKit, and PlaygroundSupport.
Lastly, here’s some code.
// Code inside modules can be shared between pages and other source files.
import ARKit
import SceneKit
import UIKit
extension ARSCNView {
public func setup(){
antialiasingMode = .multisampling4X
automaticallyUpdatesLighting = false
preferredFramesPerSecond = 60
contentScaleFactor = 1.0
if let camera = pointOfView?.camera {
camera.wantsHDR = true
camera.wantsExposureAdaptation = true
camera.exposureOffset = -1
camera.minimumExposure = -1
camera.maximumExposure = 3
}
}
}
public class vc : UIViewController, ARSessionDelegate, ARSCNViewDelegate {
var arscn : ARSCNView!
var scene : SCNScene!
public override func loadView() {
arscn = ARSCNView(frame: CGRect(x: 0, y: 0, width: 768, height: 1024))
arscn.delegate = self
arscn.setup()
scene = SCNScene()
arscn.scene = scene
var config = ARWorldTrackingConfiguration()
config.planeDetection = .horizontal
arscn.session.delegate = self
self.view = arscn
arscn.session.run(configåå)
}
public func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user
}
public func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay
}
public func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required
}
}
Lastly, please note that I’m presenting the live view in the main playground page and putting the class in the shared code.
I’ve figured out a way to make this work. All I had to do was assign the view controller to a variable and then present the variable. I’m not exactly sure why this works, I just know it does.
import ARKit
import SceneKit
import UIKit
import PlaygroundSupport
public class LiveVC: UIViewController, ARSessionDelegate, ARSCNViewDelegate {
let scene = SCNScene()
public var arscn = ARSCNView(frame: CGRect(x: 0,y: 0,width: 640,height: 360))
override public func viewDidLoad() {
super.viewDidLoad()
arscn.delegate = self
arscn.session.delegate = self
arscn.scene = scene
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
arscn.session.run(config)
view.addSubview(arscn)
}
public func session(_ session: ARSession, didFailWithError error: Error) {}
public func sessionWasInterrupted(_ session: ARSession) {}
public func sessionInterruptionEnded(_ session: ARSession) {}
}
var vc = LiveVC()
PlaygroundPage.current.liveView = vc
PlaygroundPage.current.needsIndefiniteExecution = true