Open hubercode opened 2 months ago
Thank you for your quick response. I get this IllegalStateException
:
kotlin.IllegalStateException:` Unable to find a fetcher for class NSURL
at 0 app-kmp 0x10121490b kfun:kotlin.Throwable#<init>(kotlin.String?){} + 119
at 1 app-kmp 0x10120def7 kfun:kotlin.Exception#<init>(kotlin.String?){} + 115
at 2 app-kmp 0x10120e117 kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 115
at 3 app-kmp 0x10120e6b7 kfun:kotlin.IllegalStateException#<init>(kotlin.String?){} + 115
at 4 app-kmp 0x1022f2cd3 kfun:io.kamel.core.utils#findFetcherFor__at__io.kamel.core.config.KamelConfig(0:0){0§<kotlin.Any>}io.kamel.core.fetcher.Fetcher<0:0> + 987
at 5 app-kmp 0x1022d9a43 kfun:io.kamel.core.loadImageBitmapResource$lambda$0#internal + 855
at 6 app-kmp 0x1022de4b7 kfun:io.kamel.core.$loadImageBitmapResource$lambda$0$FUNCTION_REFERENCE$0.invoke#internal + 151
at 7 app-kmp 0x10135a903 kfun:kotlin.coroutines.SuspendFunction1#invoke#suspend(1:0;kotlin.coroutines.Continuation<1:1>){}kotlin.Any?-trampoline + 115
at 8 app-kmp 0x101425b3f kfun:kotlinx.coroutines.flow.SafeFlow.collectSafely#internal + 199
at 9 app-kmp 0x10148b22f kfun:kotlinx.coroutines.flow.AbstractFlow#collectSafely#suspend(kotlinx.coroutines.flow.FlowCollector<1:0>;kotlin.coroutines.Continuation<kotlin.Unit>){}kotlin.Any-trampoline + 75
at 10 app-kmp 0x101427c6b kfun:kotlinx.coroutines.flow.AbstractFlow.$collectCOROUTINE$0.invokeSuspend#internal + 639
at 11 app-kmp 0x101427f3b kfun:kotlinx.coroutines.flow.AbstractFlow#collect#suspend(kotlinx.coroutines.flow.FlowCollector<1:0>;kotlin.coroutines.Continuation<kotlin.Unit>){}kotlin.Any + 295
at 12 app-kmp 0x10148b16b kfun:kotlinx.coroutines.flow.Flow#collect#suspend(kotlinx.coroutines.flow.FlowCollector<1:0>;kotlin.coroutines.Continuation<kotlin.Unit>){}kotlin.Any-trampoline + 115
at 13 app-kmp 0x10144453f kfun:kotlinx.coroutines.flow.$catchImplCOROUTINE$0.invokeSuspend#internal + 723
at 14 app-kmp 0x10144495b kfun:kotlinx.coroutines.flow#catchImpl#suspend__at__kotlinx.coroutines.flow.Flow<0:0>(kotlinx.coroutines.flow.FlowCollector<0:0>;kotlin.coroutines.Continuation<kotlin.Throwable?>){0§<kotlin.Any?>}kotlin.Any? + 295
at 15 app-kmp 0x101445573 kfun:kotlinx.coroutines.flow.object-18.$collectCOROUTINE$2.invokeSuspend#internal + 575
at 16 app-kmp 0x10144593f kfun:kotlinx.coroutines.flow.object-18.collect#internal + 295
at 17 app-kmp 0x10148b16b kfun:kotlinx.coroutines.flow.Flow#collect#suspend(kotlinx.coroutines.flow.FlowCollector<1:0>;kotlin.coroutines.Continuation<kotlin.Unit>){}kotlin.Any-trampoline + 115
at 18 app-kmp 0x10166aff7 kfun:androidx.compose.runtime.collectAsState$lambda$3$lambda$2#internal + 251
at 19 app-kmp 0x10166d367 kfun:androidx.compose.runtime.$collectAsState$lambda$3$lambda$2$FUNCTION_REFERENCE$4.invoke#internal + 139
at 20 app-kmp 0x10135a557 kfun:kotlin.Function2#invoke(1:0;1:1){}1:2-trampoline + 115
at 21 app-kmp 0x10121dbdf kfun:kotlin.coroutines.intrinsics.object-4.invokeSuspend#internal + 731
at 22 app-kmp 0x101359e73 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#invokeSuspend(kotlin.Result<kotlin.Any?>){}kotlin.Any?-trampoline + 67
at 23 app-kmp 0x10121a34b kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 623
at 24 app-kmp 0x101359f53 kfun:kotlin.coroutines.Continuation#resumeWith(kotlin.Result<1:0>){}-trampoline + 99
at 25 app-kmp 0x1014580cb kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1879
at 26 app-kmp 0x101486647 kfun:kotlinx.coroutines.Runnable#run(){}-trampoline + 91
at 27 app-kmp 0x10145aacf kfun:kotlinx.coroutines.internal.LimitedDispatcher.Worker.run#internal + 231
at 28 app-kmp 0x101486647 kfun:kotlinx.coroutines.Runnable#run(){}-trampoline + 91
at 29 app-kmp 0x10147db4f kfun:kotlinx.coroutines.MultiWorkerDispatcher.$workerRunLoop$lambda$2COROUTINE$0.invokeSuspend#internal + 2095
at 30 app-kmp 0x101359e73 kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#invokeSuspend(kotlin.Result<kotlin.Any?>){}kotlin.Any?-trampoline + 67
at 31 app-kmp 0x10121a34b kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 623
at 32 app-kmp 0x101359f53 kfun:kotlin.coroutines.Continuation#resumeWith(kotlin.Result<1:0>){}-trampoline + 99
at 33 app-kmp 0x1014580cb kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1879
at 34 app-kmp 0x101486647 kfun:kotlinx.coroutines.Runnable#run(){}-trampoline + 91
at 35 app-kmp 0x1013e8837 kfun:kotlinx.coroutines.EventLoopImplBase#processNextEvent(){}kotlin.Long + 1247
at 36 app-kmp 0x101486393 kfun:kotlinx.coroutines.EventLoop#processNextEvent(){}kotlin.Long-trampoline + 51
at 37 app-kmp 0x1014770bb kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 435
at 38 app-kmp 0x101475f1f kfun:kotlinx.coroutines#runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0§<kotlin.Any?>}0:0 + 1395
at 39 app-kmp 0x1014760ff kfun:kotlinx.coroutines#runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>;kotlin.Int){0§<kotlin.Any?>}0:0 + 239
at 40 app-kmp 0x10147bd33 kfun:kotlinx.coroutines.MultiWorkerDispatcher.workerRunLoop#internal + 183
at 41 app-kmp 0x10147cf9b kfun:kotlinx.coroutines.MultiWorkerDispatcher.<init>$lambda$1$lambda$0#internal + 67
at 42 app-kmp 0x10147e297 kfun:kotlinx.coroutines.MultiWorkerDispatcher.$<init>$lambda$1$lambda$0$FUNCTION_REFERENCE$5.invoke#internal + 71
at 43 app-kmp 0x10147e367 kfun:kotlinx.coroutines.MultiWorkerDispatcher.$<init>$lambda$1$lambda$0$FUNCTION_REFERENCE$5.$<bridge-UNN>invoke(){}#internal + 71
at 44 app-kmp 0x10135680f kfun:kotlin.Function0#invoke(){}1:0-trampoline + 99
at 45 app-kmp 0x101226d5f WorkerLaunchpad + 131
at 46 app-kmp 0x1013b7857 _ZN6Worker19processQueueElementEb + 2635
at 47 app-kmp 0x1013b6c97 _ZN12_GLOBAL__N_113workerRoutineEPv + 219
at 48 libsystem_pthread.dylib 0x1056db413 _pthread_start + 103
at 49 libsystem_pthread.dylib 0x1056d65df thread_start + 7
Can you provide me a quick example what you mean by "wrapping it in File"? I may I tried to wrap the path (data) in File, but this results in the following exception when building for iOS:
Caused by: java.lang.IllegalStateException: FIELD name:io_kamel_core_utils_File$stable type:kotlin.Int visibility:public [final,static]
@Composable // iOS
actual fun loadImageResource(data: String): Resource<Painter> {
// val nsUrl = NSURL.fileURLWithPath(data)
val file = File(data)
return asyncPainterResource(data = file) // exception gets thrown here
}
Thank you!
Here's the example in the sample:
It probably has to do with your path though. I don't think you can directly access files on your drive by absolute path from an ios simulator. Try bundling it as a resource like the sample does. This is probably relevant as well:
https://stackoverflow.com/questions/37574689/how-to-load-image-from-local-path-ios-swift-by-path
Problem Description:
I am working on a Kotlin Multiplatform (KMP) project where I need to load an image from the device’s file system. While the implementation works perfectly on Android, I am encountering issues on iOS where the image does not display. The path to the image seems correct, as I can verify the image exists on the iOS device’s file system. However, it does not render in the KamelImage.
Expected Behavior:
The image should load and display correctly on both Android and iOS devices using the same KMP codebase.
Actual Behavior:
• Android: Image loads and displays correctly. • iOS: Image does not display, even though the file path is correct.
Code Example:
Here is the relevant portion of my implementation:
Example FileName:
iOS: /Users/michael/Library/Developer/CoreSimulator/Devices/45D9A2D0-C80D-46E1-BC61-7AC048B75D47/data/Containers/Data/Application/9DD527DF-5093-46E5-BC6E-CB8B1FFBA835/Documents/story/images/img-3EdLqeuRN51sTaOcAvWMPFgW.png
Andorid: /data/user/0/ch.huber.storki/files/story/images/img-3EdLqeuRN51sTaOcAvWMPFgW.png
Request:
Could you provide guidance on how to properly load images from the file system on iOS using KamelImage? Are there any known issues or additional steps needed to ensure compatibility on iOS?
Any assistance or advice would be greatly appreciated. Thank you for your hard work on this project!