Has anyone ever displayed an iOS UIImage or PHAsse...
# multiplatform
a
Has anyone ever displayed an iOS UIImage or PHAsset in Compose Multiplatform? Maybe even with Coil (3.x.x)? Code in 🧵
Right now I am using an
expect/actual
implementation to produce a
State
for the
ImageRequest
(Coil 3.x.x), on Android I will just do the following:
Copy code
@Composable
actual fun GalleryImage.imageRequest(): ImageRequest? =
    ImageRequest.Builder(LocalPlatformContext.current)
        .data(identifier)
        .build()
identifier
is the images
Uri
On iOS I am trying to achieve the same, so far I have the following:
Copy code
@OptIn(ExperimentalForeignApi::class)
@Composable
actual fun GalleryImage.imageRequest(): ImageRequest? {
    val context = LocalPlatformContext.current
    val request by produceState<ImageRequest?>(null) {
        val imageObject = PHAsset.fetchAssetsWithLocalIdentifiers(listOf(identifier), null)
            .firstObject()
        val result = imageObject as? PHAsset ?: return@produceState
        val imageManager = PHImageManager.defaultManager()
        imageManager.requestImageForAsset(
            asset = result,
            targetSize = CGSizeMake(920.0, 1080.0),
            contentMode = PHImageContentModeDefault,
            options = null
        ) { image, _ ->
            image?.toByteArray(80.0)?.let {
                value = ImageRequest.Builder(context)
                    .data(it)
                    .build()
            }
        }
    }
    return request
}
On
iOS
the
identifier
is a `PHPickerResult`s
assetIdentifier
, which comes from the iOS image picker This works but has a couple of drawbacks: 1. I need to specify the image size to load in pixels, which does not take any layouting into consideration (I can definitely hack this in there with
BoxWithConstraints
or something similar, but it feels wrong) 2. There is a couple conversions from identifier -> UIImage -> ByteArray, which I don’t know if its needlessly wasteful or might even lead to OOMs for many images?! 3. Threading is a mystery to me here, maybe its good, maybe its not, I cannot tell Is there a better way on iOS for achieving this? So far an iPhone 15 emulator does just fine displaying these images in a
LazyColumn
, but this might just be because its running on an m1 which has insane hardware resources.
h
Has anyone had any luck with this? I have a similar solution working, but it doesn't seem to capitalize on callback structure of
requestImageForAssetWithIdentifier()
, and is quite buggy 😕
a
Yes, I have switched to the excellent FileKit, as described here: https://kotlinlang.slack.com/archives/C3PQML5NU/p1725779289384419?thread_ts=1723273305.211709&cid=C3PQML5NU This allows for using the uri on android and the nsurl on iOS (via expect/actual) which can directly be passed to coil, works like a charm! I only tested this for iOS and Android, which is good enough for my usecase - other platforms should work too, but I haven’t tested that.
h
I just switched myself! Should out @Vincent!! FileKit is awesome!
❤️ 1
Thank you for your response @Alex!
118 Views