EN VI

Getting Call to main actor-isolated static method 'loadMainScene()' in a synchronous nonisolated context error in ARKit swiftui application?

2024-03-11 15:00:12
How to Getting Call to main actor-isolated static method 'loadMainScene()' in a synchronous nonisolated context error in ARKit swiftui application

In swiftui ARKit application for putting selected image on floor i am getting the error Call to main actor-isolated static method 'loadMainScene()' in a synchronous nonisolated context at line self.mainScene = try! Experience.loadMainScene() . How to resolve abover error?

import Foundation
import RealityKit
import ARKit 


class Coordinator {
    
    var arView: ARView?
    var mainScene: Experience.MainScene
    var vm: FurnitureViewModel
    
    init(vm: FurnitureViewModel) {
        self.vm = vm
        self.mainScene = try! Experience.loadMainScene()
    }
    
    @objc func tapped(_ recognizer: UITapGestureRecognizer) {
        
        guard let arView = arView else {
            return
        }
        
        let location = recognizer.location(in: arView)
        let results = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal)
        
        if let result = results.first {
            
            let anchor = AnchorEntity(raycastResult: result)
            guard let entity = mainScene.findEntity(named: vm.selectedFurniture) else {
                return
            }
            entity.position = SIMD3(0,0,0)
            
            anchor.addChild(entity)
            arView.scene.addAnchor(anchor)
        }
        
    }
    
}

// // Experience.swift // GENERATED CONTENT. DO NOT EDIT. //

import Foundation import RealityKit import simd import Combine

@available(iOS 13.0, macOS 10.15, *) public enum Experience {

public enum LoadRealityFileError: Error {
    case fileNotFound(String)
}

@MainActor
private static var streams = [Combine.AnyCancellable]()

@MainActor
public static func loadMainScene() throws -> Experience.MainScene {
    guard let realityFileURL = Foundation.Bundle(for: Experience.MainScene.self).url(forResource: "Experience", withExtension: "reality") else {
        throw Experience.LoadRealityFileError.fileNotFound("Experience.reality")
    }

    let realityFileSceneURL = realityFileURL.appendingPathComponent("MainScene", isDirectory: false)
    let anchorEntity = try Experience.MainScene.loadAnchor(contentsOf: realityFileSceneURL)
    return createMainScene(from: anchorEntity)
}

@MainActor
public static func loadMainSceneAsync(completion: @escaping (Swift.Result<Experience.MainScene, Swift.Error>) -> Void) {
    guard let realityFileURL = Foundation.Bundle(for: Experience.MainScene.self).url(forResource: "Experience", withExtension: "reality") else {
        completion(.failure(Experience.LoadRealityFileError.fileNotFound("Experience.reality")))
        return
    }

    var cancellable: Combine.AnyCancellable?
    let realityFileSceneURL = realityFileURL.appendingPathComponent("MainScene", isDirectory: false)
    let loadRequest = Experience.MainScene.loadAnchorAsync(contentsOf: realityFileSceneURL)
    cancellable = loadRequest.sink(receiveCompletion: { loadCompletion in
        if case let .failure(error) = loadCompletion {
            completion(.failure(error))
        }
        streams.removeAll { $0 === cancellable }
    }, receiveValue: { entity in
        completion(.success(Experience.createMainScene(from: entity)))
    })
    cancellable?.store(in: &streams)
}

@MainActor
private static func createMainScene(from anchorEntity: RealityKit.AnchorEntity) -> Experience.MainScene {
    let mainScene = Experience.MainScene()
    mainScene.anchoring = anchorEntity.anchoring
    mainScene.addChild(anchorEntity)
    return mainScene
}

public class MainScene: RealityKit.Entity, RealityKit.HasAnchoring {

    public var armoire: RealityKit.Entity? {
        return self.findEntity(named: "armoire")
    }



    public var chair: RealityKit.Entity? {
        return self.findEntity(named: "chair")
    }



    public var sofa: RealityKit.Entity? {
        return self.findEntity(named: "sofa")
    }



    public var table: RealityKit.Entity? {
        return self.findEntity(named: "table")
    }



}

}

Any help would be appreciated.

Solution:

Since the loadMainScene() static function was marked with the @MainActor annotation, which means this function will perform on the main thread. So, you also need to add @MainActor to your init function.

@MainActor
init(vm: FurnitureViewModel) {
    ...
}

Or provide a default value for mainScene and perform a @MainActor task in the init function.

var mainScene: Experience.MainScene! //<- Default value here.

init(vm: FurnitureViewModel) {
    ...
    Task { @MainActor in
        self.mainScene = try! Experience.loadMainScene()
    }
}
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login