WorldTrackingProvider Not running. Arkitsession terminated

Hi everyone I am working on a small project that requires World Anchors so that I can persist my content through whenever the user chooses to leave/close the app. However I can't manage to make my Arkit session to run even though I think all the privacy permissions have been set and allowed correctly. Here is a sample code in an empty scene: // // WorldTrackingView.swift // SH_AVP_Demo // // Created by 李希 on 9/19/24. // import SwiftUI import RealityKit import RealityKitContent //import VisionKit import ARKit import Foundation import UIKit import simd

struct WorldTrackingView_test: View { @State var myCube = Entity() @Environment(.scenePhase) var myScenePhase

var body: some View {
    RealityView { content in

        //Load Scene
        if let Scene = try? await Entity.load(named: "WorldTrackingScene", in: realityKitContentBundle){

            //Add scene to the view
            content.add(Scene)

            //Look for the cube entity
            if let cubeEntity = Scene.findEntity(named: "Cube"){
                myCube = cubeEntity
                // Create collission for the cube
                myCube.generateCollisionShapes(recursive: true)
                // Allow inputs to interact
                myCube.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                // set some ground shadows
                myCube.components.set(GroundingShadowComponent(castsShadow: true))
            }
        }

    }
    // Add drag gesture that targets any entity in the scene
    .gesture(DragGesture().targetedToAnyEntity()
       
        //Do something when the cube position changes
        .onChanged{ value in value.entity.position = value.convert(value.location3D, from: .local, to: value.entity.parent!)
            myCube = value.entity

// Test and see if the Arkit runs with different data providers var session = ARKitSession() var worldData = WorldTrackingProvider() let planeData = PlaneDetectionProvider() let sceneData = SceneReconstructionProvider()

            do {
                Task{
                try await session.run([worldData])
                    for await update in worldData.anchorUpdates {
                        switch update.event {
                        case .added, .updated:
                            // Update the app's understanding of this world anchor.
                            print("Anchor position updated.")
                        case .removed:
                            // Remove content related to this anchor.
                            print("Anchor position now unknown.")
                        }
                    }
                }

            }catch{
                print("session not running \(error.localizedDescription)")
                return
            }

        }
             //At the end of the gesture save anchor
        .onEnded{ value in

        }
    )
}

} #Preview(immersionStyle: .mixed) { WorldTrackingView() }

All is does is to generate a cube in an immersive view. The cube has collision and input components added to so that I can interact with it using a drag gesture. I decided to start an arkit session with a WorldTrackingProvider() but I keep getting the following error:

ARPredictorRemoteService <0x117e0c620>: Service configured with error: Error Domain=com.apple.arkit.error Code=501 "(null)" Remote Service was invalidated: <ARPredictorRemoteService: 0x117e0c620>, will stop all data_providers. ARRemoteService: remote object proxy failed with error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 81 named com.apple.arkit.service.session was invalidated from this process." UserInfo={NSDebugDescription=The connection to service with pid 81 named com.apple.arkit.service.session was invalidated from this process.} ARRemoteService: weak self released before invalidation ARRemoteService: remote object proxy failed with error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 81 named com.apple.arkit.service.prediction was invalidated from this process." UserInfo={NSDebugDescription=The connection to service with pid 81 named com.apple.arkit.service.prediction was invalidated from this process.} ARRemoteService: weak self released before invalidation

If I switch it with a PlaneDetectionProvider() or a SceneReconstructionProvider() I get print statements in my terminal, but none if i replace it with a WorldTrackingProvider(). Any idea what could be causing this? Same code was working before a recent for xcode I believe.

Hi @AVPdevCN

I was able to run your code and reproduced the same warning message. One thing that seems strange to me is that you are calling try await session.run([worldData]) from inside the .gesture callback on your RealityView. Is this necessary for what you are trying to achieve? I think this may be the source of your error, as moving your world tracking code to a .task on your RealityView eliminates the warning on my end.

This code you've shared may not be doing what you expect it to: every frame this onChanged block is executed, a new Task is created to run the session with a new WorldTrackingProvider instance. This doesn't seem like intentional behavior to me.

I recommend taking a look at the Tracking specific points in world space sample project, as it goes in depth into creating world anchors and attaching objects to them.

Thank you for the reply! All I am trying to do is to be able to create a simple example of using the world Anchor to lock a cube in place and be able to find it exactly where I left it off in the world after leaving/closing the application. My previous example I had troubles running the Arkit session so I tried to get a response by calling it inside a drag gesture just to see what the logs were telling me.

What I am trying to do here: 1) Find the cube from a loaded scene from Reality Composer pro 2) Drag in space using a drag gesture and snap it onto surfaces using PlaneDetection. 3) The moment I finish dragging the cube I want its position in the world to be saved and be able reload its position again in the world whenever the user enters the application again. To do this I am saving the anchor id and its transform matrix in two separate text files. The functions get triggered automatically every time at .onEnded of the drag gesture. In the .onAppear block is where I am attempting to reload the anchor id and transform and re-apply its position to the cube. I can get the transform and ID save and reload ok, the log shows the functions are working but how can I make the cube appear where I left it exactly like last time? do I need to query the device position somehow and let the cube be aware that the device location has changed and there for the cube position needs to be offset? sorry is my first time working with an Vision Pro project so I'm not familiar what the anchors can do out of the box.

var body: some View {
    RealityView { content in
        //Load "Scene" from Reality Composer Pro
        if let Scene = try? await Entity.load(named: "WorldTrackingScene", in: realityKitContentBundle){
            
            //Add scene to the view
            content.add(Scene)
            
            //Look for the cube entity
            if let cubeEntity = Scene.findEntity(named: "Cube"){
                myCube = cubeEntity
                // Create collission for the cube
                myCube.generateCollisionShapes(recursive: true)
                // Allow inputs to interact
                myCube.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                // set some ground shadows
                myCube.components.set(GroundingShadowComponent(castsShadow: true))
            }
        }
      // Add your RealityKit scene setup here
        Task {
            // Start the ARKit session
            try await session.run([planeData,worldData])
            print("ARKit session started")
            //Add anchor back
           
                if let restoredAnchor = restoredAnchor{
                    try? await worldData.addAnchor(restoredAnchor)
                
            }
        }
        
        // Task for handling plane anchor updates
        Task {
            for await planeUpdate in planeData.anchorUpdates {
                switch planeUpdate.event {
                case .added, .updated:
                    //print("Plane anchor location: \(extractTranslation(from: planeUpdate.anchor.originFromAnchorTransform))")
                    currentPlaneAnchor = planeUpdate.anchor
              
                case .removed:
                    print("Plane anchor removed")
                }
            }
        }
        
        
        //Check if anchor exists
        Task{
            for await myAnchor in worldData.anchorUpdates{
                if myAnchor.anchor.id == testUUID{
                    print("Anchor ID found : \(myAnchor.anchor.id)")
                    loadedTransform = extractTranslation(from: myAnchor.anchor.originFromAnchorTransform)
                }
                let currentTime = CACurrentMediaTime()
                let deviceLocation = worldData.queryDeviceAnchor(atTimestamp: currentTime)
                //print("device location: \(deviceLocation)")
            }
            myCube.position = loadedTransform
        }
        
        
    }
    .onChange(of: myScenePhase){newvalue in
        switch myScenePhase {
        case .active:
            print("App active")
            
        case .inactive, .background:
            print("App closing")

        }
        
    }
    .onAppear{
        
        // Load UUID
        if let loadedUUID = loadUUIDFromFile(filename: "savedUUID.txt"){
            testUUID = loadedUUID
            print("Anchor ID ON APPEAR : \(testUUID)")
            
            //Load Trans
            if let savedTrans = loadTransformFromFile(filename: "savedTransform.txt"){
                print("Anchor TRANSFORM ON APPEAR : \(savedTrans)")
                //let retrievedAnchor = WorldAnchor(originFromAnchorTransform: savedTrans)
                //restoredAnchor = retrievedAnchor
               
                
            }
            
        }
        
    }
    .gesture(DragGesture().targetedToAnyEntity()
             //When entity changes in position
        .onChanged{ value in value.entity.position = value.convert(value.location3D, from: .local, to: value.entity.parent!)
            myCube = value.entity
            //Place cube snapped to the surface
            if let planeAnchor = currentPlaneAnchor{
                // Assign the anchors position Y to the cube's position Y
                myCube.position.y = planeAnchor.originFromAnchorTransform.columns.3.y
            }
        }
        .onEnded{value in
            // Task for handling world anchor updates
            Task{
               
                    let worldAnchor = WorldAnchor(originFromAnchorTransform: currentPlaneAnchor!.originFromAnchorTransform)
                    // Add the world anchor to the worldData provider
                    try? await worldData.addAnchor(worldAnchor)
                    
                    //Store the UUID in a file
                    testUUID = worldAnchor.id
                    print("World anchor added: \(worldAnchor.id)----\(testUUID)")
                    print("word anchor is tracked: \(worldAnchor.isTracked)")
                    saveUUIDToFile(testUUID, filename: "savedUUID.txt")
                    
                    //Store the transform
                    saveTransformToFile(worldAnchor.originFromAnchorTransform, filename: "savedTransform.txt")
                
                
            }
        }
    )
      
}

}

WorldTrackingProvider Not running. Arkitsession terminated
 
 
Q