Search code examples
iosswiftswift-playgroundipad-playgrounds

Swift Playgrounds (iPad) does not build an app with implemented ARSessionDelegate.session(_:didUpdate:) functions


I found an error while trying to implement a SwiftUI representation of ARView with ARSessionDelegate based on Apple’s official example “Building an immersive experience with RealityKit”.

There is the error

Method '__preview__session(_:didUpdate:)' with Objective-C selector '__preview__session:didUpdate:' conflicts with previous declaration with the same Objective-C selector

I prepared the following sample to easily reproduce this.


import ARKit
import RealityKit
import SwiftUI

struct ContentView: View {
    var body: some View {
        RealityKitView()
    }
}

private struct RealityKitView: UIViewRepresentable {
    class Coordinator: NSObject, ARSessionDelegate {
        func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { }
        func session(_ session: ARSession, didUpdate frame: ARFrame) { }
    }
    
    func makeCoordinator() -> Coordinator { Coordinator() }
    
    func makeUIView(context: Context) -> ARView {
        let view = ARView()
        let session = view.session
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = [.horizontal]
        session.run(config)
        session.delegate = context.coordinator
        return view
    }
    
    func updateUIView(_ view: A.  RView, context: Context) { }
}

A quite interesting moment is that this code above can be successfully built with a general Swift Playgrounds’ playground or Xcode but not within Swift Playgrounds' app. 🤔

Are there any workarounds?

Also, found another weird error 'Scene' is ambiguous for type lookup in this context from the same Apple’s Underwater example (FoodPool.swift). I simplified the content to clarify where the problem is, however, there is nothing wrong with this code.

import RealityKit

class FoodPool {
    private let arView: ARView
    private var scene: Scene { arView.scene } // Error: 'Scene' is ambiguous for type lookup in this context
    
    init(arView: ARView) { 
        self.arView = arView
    }
}

Apart from the ARSessionDelegate problem this one can be resolved with using arView.scene directly (removed line 5 will help).

Overall, seems like there is hidden much more complicated problem.


Solution

  • Workaround

    Given a file with a fake :D error, and planned changes are done in the file, when another valid file is chosen, and the project is reloaded (or Swift Playgrounds is restated), then the project could be run successfully straight away if there are no other errors.

    This helped me with the ARSessionDelegate problem and running the Underwater example on iPad.