Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin-Swift interop issue: ArrayList has wrong count value when passed as NSMutableArray from Swift Code for Release builds

Let's assume a KMP Project which is set to have a Sample iOS app in which a KMP module's output framework is added as a dependency.

I am having a function sampleFuncForStringArrayList(names: ArrayList<String>) in KMP module which prints count and iterates and print ArrayList items.

When I call this function from the iOS sample app, I am getting index out of bound exception because NSMutableArray count which is 2 in iOS app environment, has count as 24576 when received as ArrayList in KMP module.

This issue happens only with releaseFramework. debugFramework works fine.

//Swift
let namesStringList = NSMutableArray(array: ["Alice", "Bob"])
print("NSMutableArray COUNT : \(namesStringList.count)")
Main().sampleFuncForStringArrayList(names: namesStringList)


//Kotlin
public class Main {
    public fun sampleFuncForStringArrayList(names: ArrayList<String>){
        println("names.isNullOrEmpty() ${names.isNullOrEmpty()}")
        println("names.count ${names.count()}")
        names.forEach {
            println("Hello $it")
        }
    }
}

Expected Output

NSMutableArray COUNT : 2
names.isNullOrEmpty() false
names.count 2
Hello Alice
Hello Bob

Actual Output:

NSMutableArray COUNT : 2
names.isNullOrEmpty() false
names.count 24576
CRASH

- CRASH -

Sample Project ZIP: https://drive.google.com/file/d/1SgmW4hfeWaEeD3vcidnZ81Q9vMJsU9zJ/view?usp=sharing

like image 762
Alex Avatar asked Oct 28 '25 15:10

Alex


1 Answers

I've tried with my KMM setup (using cocoapods) and even with a release build I got the right expected behaviour but I've used the right kotlin/swift interop mapping type MutableList

fun sampleFuncForStringMutableList(names: MutableList<String>) {
    println("names.isNullOrEmpty() ${names.isNullOrEmpty()}")
    println("names.count ${names.count()}")
    names.forEach {
        println("Hello $it")
    }
}

With ArrayList I see an empty array and then a crash (different from debug build where I see your expected behaviour too).

let namesStringList = NSMutableArray(array: ["Alice", "Bob"])
print("NSMutableArray COUNT : \(namesStringList.count)")
Main().sampleFuncForStringArrayList(names: namesStringList)
Main().sampleFuncForStringMutableList(names: namesStringList)
NSMutableArray COUNT : 2
names.isNullOrEmpty() true
names.count 0
names.isNullOrEmpty() false
names.count 2
Hello Alice
Hello Bob

So I suggest you to use the right mapping type and not another one.

like image 146
shadowsheep Avatar answered Oct 31 '25 05:10

shadowsheep