diff --git a/android/src/main/kotlin/com/uhg0/ar_flutter_plugin_2/ArView.kt b/android/src/main/kotlin/com/uhg0/ar_flutter_plugin_2/ArView.kt index 1f8d8b3..290a9df 100644 --- a/android/src/main/kotlin/com/uhg0/ar_flutter_plugin_2/ArView.kt +++ b/android/src/main/kotlin/com/uhg0/ar_flutter_plugin_2/ArView.kt @@ -247,11 +247,14 @@ class ArView( override fun onMoveEnd(detector: MoveGestureDetector, e: MotionEvent) { if (handlePans) { super.onMoveEnd(detector, e) - val transformMap = mapOf( - "name" to name, - "transform" to transform.toFloatArray().toList() - ) - objectChannel.invokeMethod("onPanEnd", transformMap) + // Only invoke callback if name exists (defensive check) + name?.let { nodeName -> + val transformMap = mapOf( + "name" to nodeName, + "transform" to transform.toFloatArray().toList() + ) + objectChannel.invokeMethod("onPanEnd", transformMap) + } } } @@ -276,11 +279,14 @@ class ArView( override fun onRotateEnd(detector: RotateGestureDetector, e: MotionEvent) { if (handleRotation) { super.onRotateEnd(detector, e) - val transformMap = mapOf( - "name" to name, - "transform" to transform.toFloatArray().toList() - ) - objectChannel.invokeMethod("onRotationEnd", transformMap) + // Only invoke callback if name exists (defensive check) + name?.let { nodeName -> + val transformMap = mapOf( + "name" to nodeName, + "transform" to transform.toFloatArray().toList() + ) + objectChannel.invokeMethod("onRotationEnd", transformMap) + } } } }.apply { diff --git a/ios/Classes/IosARView.swift b/ios/Classes/IosARView.swift index b50eb17..f3c685e 100644 --- a/ios/Classes/IosARView.swift +++ b/ios/Classes/IosARView.swift @@ -626,10 +626,14 @@ class IosARView: NSObject, FlutterPlatformView, ARSCNViewDelegate, UIGestureReco // State Ended if(recognizer.state == UIGestureRecognizer.State.ended) { + // Store node reference before clearing it + let nodeToSerialize = panningNode // kill variables panStartLocation = nil panCurrentLocation = nil - DispatchQueue.main.async {self.objectManagerChannel.invokeMethod("onPanEnd", arguments: serializeLocalTransformation(node: self.panningNode))} + if let node = nodeToSerialize { + DispatchQueue.main.async {self.objectManagerChannel.invokeMethod("onPanEnd", arguments: serializeLocalTransformation(node: node))} + } panningNode = nil } } @@ -688,10 +692,14 @@ class IosARView: NSObject, FlutterPlatformView, ARSCNViewDelegate, UIGestureReco // State Ended if(recognizer.state == UIGestureRecognizer.State.ended) { + // Store node reference before clearing it + let nodeToSerialize = panningNode // kill variables rotation = nil rotationVelocity = nil - DispatchQueue.main.async {self.objectManagerChannel.invokeMethod("onRotationEnd", arguments: serializeLocalTransformation(node: self.panningNode))} + if let node = nodeToSerialize { + DispatchQueue.main.async {self.objectManagerChannel.invokeMethod("onRotationEnd", arguments: serializeLocalTransformation(node: node))} + } panningNode = nil } diff --git a/ios/Classes/Serialization/Serializers.swift b/ios/Classes/Serialization/Serializers.swift index 73826ee..ab1b5c5 100644 --- a/ios/Classes/Serialization/Serializers.swift +++ b/ios/Classes/Serialization/Serializers.swift @@ -42,9 +42,14 @@ func serializeAnchor(anchor: ARAnchor, anchorNode: SCNNode?, ganchor: GARAnchor, func serializeLocalTransformation(node: SCNNode?) -> Dictionary { var serializedLocalTransformation = Dictionary() - let transform: [Float?] = [node?.transform.m11, node?.transform.m12, node?.transform.m13, node?.transform.m14, node?.transform.m21, node?.transform.m22, node?.transform.m23, node?.transform.m24, node?.transform.m31, node?.transform.m32, node?.transform.m33, node?.transform.m34, node?.transform.m41, node?.transform.m42, node?.transform.m43, node?.transform.m44] + guard let node = node else { + // Return empty dictionary if node is nil to prevent crashes + return serializedLocalTransformation + } + + let transform: [Float] = [node.transform.m11, node.transform.m12, node.transform.m13, node.transform.m14, node.transform.m21, node.transform.m22, node.transform.m23, node.transform.m24, node.transform.m31, node.transform.m32, node.transform.m33, node.transform.m34, node.transform.m41, node.transform.m42, node.transform.m43, node.transform.m44] - serializedLocalTransformation["name"] = node?.name + serializedLocalTransformation["name"] = node.name serializedLocalTransformation["transform"] = transform return serializedLocalTransformation