onseok/peekaboo

IrLinkageError for UIKitView after upgrading app to compose 1.7.0

Opened this issue · 4 comments

I've upgraded my app using you library to jetpack compose 1.7.0 but now i get this error when trying to start camera.

I think it's because of different versions of compose in use.
They've change UIKitView implementation and deprecated old. And I guess that leads to the error.


Uncaught Kotlin exception: kotlin.native.internal.IrLinkageError: Function 'UIKitView' can not be called: No function found for symbol 'androidx.compose.ui.interop/UIKitView|UIKitView(kotlin.Function0<0:0>;androidx.compose.ui.Modifier;kotlin.Function1<0:0,kotlin.Unit>?;androidx.compose.ui.graphics.Color;kotlin.Function1<0:0,kotlin.Unit>?;kotlin.Function2<0:0,kotlinx.cinterop.CValue<platform.CoreGraphics.CGRect>,kotlin.Unit>?;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<platform.UIKit.UIView>}[0]'
    at 0   composeui                           0x10e11289b        kfun:kotlin.Throwable#<init>(kotlin.String?){} + 119 
    at 1   composeui                           0x10e10b9b3        kfun:kotlin.Error#<init>(kotlin.String?){} + 115 
    at 2   composeui                           0x10e14a757        kfun:kotlin.native.internal.IrLinkageError#<init>(kotlin.String?){} + 115 
    at 3   composeui                           0x10e14a81b        kfun:kotlin.native.internal#ThrowIrLinkageError(kotlin.String?){}kotlin.Nothing + 175 
    at 4   composeui                           0x10fee8be7        kfun:com.preat.peekaboo.ui.camera.RealDeviceCamera#internal.2 + 6183 
    at 5   composeui                           0x10fee6ecf        kfun:com.preat.peekaboo.ui.camera.AuthorizedCamera#internal.1 + 2819 
    at 6   composeui                           0x10fee611f        kfun:com.preat.peekaboo.ui.camera#PeekabooCamera(com.preat.peekaboo.ui.camera.PeekabooCameraState;androidx.compose.ui.Modifier;kotlin.Function2<androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){} + 9563 
    at 7   composeui                           0x10feecaa7        kfun:com.preat.peekaboo.ui.camera.PeekabooCamera$lambda$4#internal + 371 
    at 8   composeui                           0x10fef0de7        kfun:com.preat.peekaboo.ui.camera.$PeekabooCamera$lambda$4$FUNCTION_REFERENCE$1.invoke#internal + 131 
    at 9   composeui                           0x10fef0f9b        kfun:com.preat.peekaboo.ui.camera.$PeekabooCamera$lambda$4$FUNCTION_REFERENCE$1.$<bridge-DNNNU>invoke(androidx.compose.runtime.Composer?;kotlin.Int){}#internal + 159 
    at 10  composeui                           0x10e2718bb        kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline + 115 
    at 11  composeui                           0x10e42213f        kfun:androidx.compose.runtime.RecomposeScopeImpl#compose(androidx.compose.runtime.Composer){} + 767 
    at 12  composeui                           0x10e3ea287       

I'm facing a similar issue.

Same issue here.

I've found temporary solution.

Since compose multiplatform 1.7.0,
UIKitView and UIKitViewController in package androidx.compose.ui.interop are deprecated..

So we need to fix UIKitView code in PeekabooCamera.ios.kt like that.

import androidx.compose.ui.viewinterop.UIKitView
// import androidx.compose.ui.interop.UIKitView


UIKitView(
        modifier = modifier,
//      background = Color.Black,
        factory = {
            val dispatchGroup = dispatch_group_create()
            val cameraContainer = UIView()
            cameraContainer.backgroundColor = UIColor.blackColor // set background color
            cameraContainer.layer.addSublayer(cameraPreviewLayer)
            cameraPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

            dispatch_group_enter(dispatchGroup)
            dispatch_async(queue) {
                captureSession.startRunning()
                dispatch_group_leave(dispatchGroup)
            }
            dispatch_group_notify(dispatchGroup, dispatch_get_main_queue()) {
                state.onCameraReady()
            }

            cameraContainer
        },
        update = { view ->
            cameraPreviewLayer.setFrame(view.bounds) // set frame of cameraPreviewLayer
        }
//      onResize = { view: UIView, rect: CValue<CGRect> ->
//          CATransaction.begin()
//          CATransaction.setValue(true, kCATransactionDisableActions)
//          view.layer.setFrame(rect)
//          cameraPreviewLayer.setFrame(rect)
//          CATransaction.commit()
//      },
    )

It works in Kotlin 2.0.10, but I haven't tested it enough so there may be some issues. Hope this helps and good luck!

For me this didnt work. we fixed this by moving the UIKitView() to a BoxWithConstraints and use the constraints for the size:

val rect = CGRectMake( 0.0, 0.0, maxWidth.toCGFloat(), maxHeight.toCGFloat(), ) cameraPreviewLayer.setFrame(rect)