Closed yandroidUA closed 10 months ago
Hi, thanks for the report. Could you provide a short but complete reproducer of the problem?
Sure, here is a sample project - archive.
XCode: Version 15.0 (15A240d)
P.S. Please, ignore the GoogleSignIn
pod in the app, initially it was a reproducer for the other issue, but it doesn't impact this issue
From the logs:
CONTENT
STATE: com.app.test.NavigationState@1b958020
STATE: com.app.test.NavigationState@1b958020
IMAGE_PICKER: Camera
IMAGE_PICKER: imagePickerControllerDidCancel
CONTENT
STATE: com.app.test.NavigationState@1b95ca20
Same behaviour on the real iOS device
I'm not sure whether it's a Compose problem, but in case it is not I'd be apriciate to receive any advice how I can handle this case
@yandroidUA it is the known issue with a compose scene lifecycle: https://github.com/JetBrains/compose-multiplatform/issues/3890
I will close this as a duplicate
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Describe the bug When the user opens a camera through the
UIImagePickerController
and then cancels or makes a photo the application "reloads" or losses its state. Not sure whether it's a bug of Compose or not, I'm using a following function to obtain an instance of my router:So, from my understanding it should not be reinstantiated. From the logs I see that
ComposeUIViewController
invokes children composables one the application become active after the camera and with the function above myNavigationState
get reinstantiated and I don't know why.Implementation to open the Camera & Gallery
``` // TODO need to store somewhere globally, otherwise iOS wipes it out and these are never called back private var imagePickerCoordinator: ImagePickerCoordinator? = null private var imagePickerController: UIImagePickerController? = null @Composable internal actual fun ImagePickerResultHandler( source: ImageSource?, onRequestSourceDialog: () -> Unit, onShowPermissionRationale: (Permission) -> Unit, onLoading: (Boolean) -> Unit, onError: (String) -> Unit, onResult: (RuntimeImage) -> Unit ) { val fileManager = LocalFileManager.current val currentController = UIApplication.sharedApplication.keyWindow?.rootViewController ?: LocalUIViewController.current imagePickerCoordinator = remember { ImagePickerCoordinator(onImagePicked = { onResult(RuntimeImage(it)) }, onPickerDismissed = onRequestSourceDialog) } imagePickerController = remember(imagePickerCoordinator) { UIImagePickerController().apply { delegate = imagePickerCoordinator } } LaunchedEffect(source) { when (source) { ImageSource.Camera -> { Napier.d(tag = "IMAGE_PICKER") { "Camera" } imagePickerController?.sourceType = UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypeCamera imagePickerController?.cameraCaptureMode = UIImagePickerControllerCameraCaptureMode.UIImagePickerControllerCameraCaptureModePhoto currentController.showViewController(imagePickerController!!, null) } ImageSource.Gallery -> { imagePickerController?.sourceType = UIImagePickerControllerSourceType.UIImagePickerControllerSourceTypePhotoLibrary currentController.showViewController(imagePickerController!!, null) } is ImageSource.RemoteUrl -> { fileManager.getImageFromCacheOrDownload(source.url, force = true) .collect { state -> when (state) { is ApiState.Failed -> onError(state.reason) ApiState.Idle -> {} ApiState.Loading -> onLoading(true) is ApiState.Succeed -> state.data.representation?.image?.let(onResult) ?: onError("") } } } null -> Unit } } } private class ImagePickerCoordinator( private val onImagePicked: (ByteArray) -> Unit, private val onPickerDismissed: () -> Unit ) : NSObject(), UIImagePickerControllerDelegateProtocol, UINavigationControllerDelegateProtocol { override fun imagePickerController( picker: UIImagePickerController, didFinishPickingImage: UIImage, editingInfo: MapAffected platforms Select one of the platforms below:
Versions
To Reproduce
Expected behavior Since I'm using
remember
I'm expecting to retrieve a same instance of the router.Screenshots
https://github.com/JetBrains/compose-multiplatform/assets/46822605/429cbee8-1611-4e50-a6c5-1e4c3692bcfa
Additional context Obviously, it works fine if I save the
NavigationState
globally, but should I do that ? From my understanding, it's something thatremember
is responsible, doesn't it ?