Binish Mathew
06/11/2025, 1:51 PM@Composable
fun Feck() {
AsyncImage(
modifier = Modifier
.size(96.dp)
.clickable {
},
onLoading = { successState ->
println("Image loading...")
},
onSuccess = { successState ->
println("Image loaded successfully!")
},
onError = { errorState ->
println("Image loading failed: ${errorState.result.throwable.message}")
},
model = Res.getUri("drawable/settings_icon_filled.svg"),
colorFilter = ColorFilter.tint(color = Color.Red),
contentDescription = null
)
}
This code works on my sample Android app and iOS app within the kmp project.
I wanted to use the module in another existing ios app. So, I have exported an XCFramework with resources and verified that the resources are bundled.
fun FeckUIViewController() = ComposeUIViewController {
Feck()
}
import UIKit
import SwiftUI
import Foundation
import common
import chatui
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
let fileManager = FileManager.default
print("--- Listing Main Bundle Contents ---")
// Corrected line: Access bundlePath directly as it's a String, not an Optional
let bundlePath = Bundle.main.bundlePath
print("Main Bundle Path: \(bundlePath)")
do {
let bundleContents = try fileManager.contentsOfDirectory(atPath: bundlePath)
print("Contents of Main Bundle:")
for item in bundleContents {
print("- \(item)")
}
} catch {
print("Error listing main bundle contents: \(error.localizedDescription)")
}
print("\n--- Checking for compose-resources directly in main bundle ---")
if let composeResourcesURL = Bundle.main.url(forResource: "compose-resources", withExtension: nil) {
print("Found compose-resources directory at URL: \(composeResourcesURL.path)")
// Optionally, list contents of compose-resources if found
do {
let resourcesContents = try fileManager.contentsOfDirectory(atPath: composeResourcesURL.path)
print("Contents of compose-resources:")
for item in resourcesContents {
print("- \(item)")
}
} catch {
print("Error listing compose-resources contents: \(error.localizedDescription)")
}
} else {
print("compose-resources directory NOT found in main bundle.")
}
print("\n--- Checking for composeResources directly in main bundle (alternative casing) ---")
if let composeResourcesURL = Bundle.main.url(forResource: "composeResources", withExtension: nil) {
print("Found composeResources directory at URL: \(composeResourcesURL.path)")
} else {
print("composeResources directory NOT found in main bundle.")
}
return FeckViewControllerKt.FeckUIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeView()
.ignoresSafeArea(.keyboard)
}
}
But coil fails to find the resource file.
--- Listing Main Bundle Contents ---
Main Bundle Path: /Users/binishmathew/Library/Developer/CoreSimulator/Devices/AB7ABA72-71AC-4578-89E9-79B6A72AB285/data/Containers/Bundle/Application/4C921F2E-698A-4B4F-A07B-03064D8BD661/ios.app
Contents of Main Bundle:
- _CodeSignature
- ios.debug.dylib
- __preview.dylib
- ios
- Frameworks
- Info.plist
- PkgInfo
--- Checking for compose-resources directly in main bundle ---
compose-resources directory NOT found in main bundle.
--- Checking for composeResources directly in main bundle (alternative casing) ---
composeResources directory NOT found in main bundle.
Image loading...
Image loading failed: No such file or directory
Is there any way to fix this ?Konstantin Tskhovrebov
06/11/2025, 3:38 PMBinish Mathew
06/11/2025, 6:06 PMBinish Mathew
06/11/2025, 6:18 PMKonstantin Tskhovrebov
06/11/2025, 6:47 PMKonstantin Tskhovrebov
06/11/2025, 6:48 PMKonstantin Tskhovrebov
06/11/2025, 6:49 PMBinish Mathew
06/12/2025, 6:56 AM/**
* Determines the path to the compose resources directory.
* It first searches for a "/Frameworks/'*'.framework/composeResources" directory in the main bundle directory.
* If no such directory exists, it defaults to a directory named "compose-resources" in the main bundle directory.
*
* @return The path to the compose resources directory as a string.
*/
private fun findComposeResourcesPath(): String {
val mainBundle = NSBundle.mainBundle
val fm = NSFileManager.defaultManager()
val frameworkDirs = fm.findSubDirs(mainBundle.resourcePath + "/Frameworks") { it.endsWith(".framework") }
val frameworkResourcesDir = frameworkDirs.firstOrNull { frameworkDir ->
fm.findSubDirs(frameworkDir) { it.endsWith("composeResources") }.isNotEmpty()
}
val defaultDir = mainBundle.resourcePath + "/compose-resources"
return frameworkResourcesDir ?: defaultDir
}
@Konstantin Tskhovrebov I removed the common framework and the app started taking the icon from chatui framework. Now, I have a doubt. If I have two or more frameworks with compose resources, what would be the behaviour ?
If I add the framework to a KMP ios app, based on the statement below,
return frameworkResourcesDir ?: defaultDir
What would be the behaviour ?Konstantin Tskhovrebov
06/12/2025, 10:49 AMBinish Mathew
06/12/2025, 10:57 AMKonstantin Tskhovrebov
06/12/2025, 10:59 AMBinish Mathew
06/12/2025, 11:01 AMsweetclimusic
06/12/2025, 11:40 AMKonstantin Tskhovrebov
06/12/2025, 11:41 AMI have a 3rd party framework with CMPask to provide a KMP library instead.
Binish Mathew
06/12/2025, 12:57 PMBinish Mathew
06/12/2025, 12:57 PM