I have a Swift app, which consists of an ARScnView, a WebView stacked on top of it, and then a ReactView on top of that. Now my problem: Every 1 out of 5 Rebuilds/Starts (does not matter), I get a terminating crash with the following message:
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error
There is absolutely no more information to be found in the log. It doesn't matter if I run the app on a simulator or an actual iPhone. As far as I can tell, the error occurs when the metro bundler tries to load the local react-native bundle. I delay the loading of every component of my app for debugging reasons. This is my ViewController.swift:
Code Block // // SceneViewRenderer.swift // realnote_app // // Created by RealNote on 02.09.20. // Copyright © 2020 Facebook. All rights reserved. // import Foundation import UIKit import ARKit import WebKit import Vision @objc class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate, RCTBridgeDelegate { func sourceURL(for bridge: RCTBridge!) -> URL! { return Bundle.main.url(forResource: "main", withExtension: "jsbundle") } @IBOutlet weak var sceneView: ARSCNView! var webView: WKWebView! var webViewManager: WebViewManager! var rootView : RCTRootView? var bridge : RCTBridge? var interpreterReady = true var startTime = Date() var endTime = Date() var lastCameraImage : UIImage? let TAG = "ViewController" override func viewDidLoad() { super.viewDidLoad() UIApplication.shared.isIdleTimerDisabled = true DispatchQueue.main.asyncAfter(deadline: .now() + 4) { self.initReactView() DispatchQueue.main.asyncAfter(deadline: .now() + 10) { self.initWebView() let screenWidth = UIScreen.main.bounds.width let screenHeight = UIScreen.main.bounds.height } } configureLighting() addTapGestureToSceneView() } func initWebView() { self.webViewManager = WebViewManager(hostViewController: self) webView = webViewManager.webView self.view.insertSubview(webView, aboveSubview: sceneView!) } func initReactView() { bridge = RCTBridge(delegate: self, launchOptions: nil) rootView = RCTRootView( bridge: bridge!, moduleName: "realnote", initialProperties: nil) rootView!.frame = UIScreen.main.bounds rootView!.contentView.backgroundColor = UIColor.clear rootView!.backgroundColor = UIColor.clear self.view.insertSubview(rootView!, aboveSubview: sceneView) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setUpSceneView() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } func setUpSceneView() { let configuration = ARWorldTrackingConfiguration() configuration.planeDetection = [.horizontal, .vertical] sceneView.delegate = self sceneView.session.delegate = self sceneView.session.run(configuration) sceneView.session.delegate = self sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints] sceneView.isPlaying = true HostARInterface.instance.session = sceneView.session } func configureLighting() { sceneView.autoenablesDefaultLighting = true sceneView.automaticallyUpdatesLighting = true } func session(_ session: ARSession, didUpdate: ARFrame) { } @objc func tapDelegate(withGestureRecognizer recognizer: UIGestureRecognizer) { print("tapped") } @objc func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { // 1 guard let planeAnchor = anchor as? ARPlaneAnchor else { return } // 2 let width = CGFloat(planeAnchor.extent.x) let height = CGFloat(planeAnchor.extent.z) let plane = SCNPlane(width: width, height: height) // 3 plane.materials.first?.diffuse.contents = UIColor.transparentLightBlue // 4 let planeNode = SCNNode(geometry: plane) // 5 let x = CGFloat(planeAnchor.center.x) let y = CGFloat(planeAnchor.center.y) let z = CGFloat(planeAnchor.center.z) planeNode.position = SCNVector3(x,y,z) planeNode.eulerAngles.x = -.pi / 2 // 6 node.addChildNode(planeNode) sceneView.scene.rootNode.addChildNode(planeNode) } @objc func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { // 1 guard let planeAnchor = anchor as? ARPlaneAnchor, let planeNode = node.childNodes.first, let plane = planeNode.geometry as? SCNPlane else { return } // 2 let width = CGFloat(planeAnchor.extent.x) let height = CGFloat(planeAnchor.extent.z) plane.width = width plane.height = height // 3 let x = CGFloat(planeAnchor.center.x) let y = CGFloat(planeAnchor.center.y) let z = CGFloat(planeAnchor.center.z) planeNode.position = SCNVector3(x, y, z) } } extension float4x4 { var translation: float3 { let translation = self.columns.3 return float3(translation.x, translation.y, translation.z) } } extension UIColor { open class var transparentLightBlue: UIColor { return UIColor(red: 90/255, green: 200/255, blue: 250/255, alpha: 0.50) } } extension DispatchQueue { static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) { DispatchQueue.global(qos: .background).async { background?() if let completion = completion { DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: { completion() }) } } } }
And my storyboard looks like this:
Since this is NOT the often discussed libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)-error, I have absolutely no idea how to even debug this, or to get rid of it. Please note that on 4/5 runs the app behaves exactly as expected, react-native, and everything works like a charm.