Kotlin Multiplatform Terminating app due to uncaught exception 'CMPViewControllerMisuse',

63 Views Asked by At

After the camera is working, I want to take a photo and get that photo as a bitmap. While it works on Android, I get the following error on iOS: *** Terminating app due to uncaught exception 'CMPViewControllerMisuse', reason: 'CMPViewController shouldn't be reused after completely removed from hierarchy, because it's logically marked as Destroyed. 'You must create a new CMPViewController and use it instead.' I didn't understand what I should do My codes are as follows:


@Composable
actual fun rememberCameraManager(onResult: (SharedImage?) -> Unit): CameraManager {
    return remember {
        CameraManager {
            val imagePicker = UIImagePickerController()
            val cameraDelegate = object : NSObject(), UIImagePickerControllerDelegateProtocol,
                UINavigationControllerDelegateProtocol {
                override fun imagePickerController(
                    picker: UIImagePickerController,
                    didFinishPickingMediaWithInfo: Map<Any?, *>
                ) {
                    val image =
                        didFinishPickingMediaWithInfo.getValue(UIImagePickerControllerEditedImage) as? UIImage
                            ?: didFinishPickingMediaWithInfo.getValue(
                                UIImagePickerControllerOriginalImage
                            ) as? UIImage
                    onResult.invoke(SharedImage(image))
                    picker.dismissViewControllerAnimated(true, null)
                }
            }

            imagePicker.setSourceType(UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypeCamera)
            imagePicker.setAllowsEditing(true)
            imagePicker.setCameraCaptureMode(UIImagePickerControllerCameraCaptureMode.UIImagePickerControllerCameraCaptureModePhoto)
            imagePicker.setDelegate(cameraDelegate)
            UIApplication.sharedApplication.keyWindow?.rootViewController?.presentViewController(
                imagePicker, true, null
            )
        }
    }
}

actual class CameraManager actual constructor(
    private val onLaunch: () -> Unit
) {
    actual fun launch() {
        onLaunch()
    }
}



actual class SharedImage(private val image: UIImage?) {
    @OptIn(ExperimentalForeignApi::class)
    actual fun toByteArray(): ByteArray? {
        return if (image != null) {
            val imageData = UIImageJPEGRepresentation(image, COMPRESSION_QUALITY)
                ?: throw IllegalArgumentException("image data is null")
            val bytes = imageData.bytes ?: throw IllegalArgumentException("image bytes is null")
            val length = imageData.length

            val data: CPointer<ByteVar> = bytes.reinterpret()
            ByteArray(length.toInt()) { index -> data[index] }
        } else {
            null
        }

    }

    actual fun toImageBitmap(): ImageBitmap? {
        val byteArray = toByteArray()
        return if (byteArray != null) {
            Image.makeFromEncoded(byteArray).toComposeImageBitmap()
        } else {
            null
        }
    }

    private companion object {
        const val COMPRESSION_QUALITY = 0.99
    }
}
@Composable
fun FaceRecognitionScene(onComplete :() -> Unit) {
var imageBitmap by remember { mutableStateOf<ImageBitmap?>(null) }
var launchCamera by remember { mutableStateOf(value = false) }
   
val cameraManager = rememberCameraManager {
        coroutineScope.launch {
            val bitmap =
                it?.toImageBitmap()

            imageBitmap = bitmap
        }
    }



    if (launchCamera) {
        viewModel.onRequestPermissionButtonPressed()
        if (viewModel.isPermissionGranted) {
            cameraManager.launch()
        }
        launchCamera = false

    }

}
0

There are 0 best solutions below