A little bit obscure maybe but we're looking to ca...
# touchlab-tools
j
A little bit obscure maybe but we're looking to call a Kotlin function from Swift that takes a Swift closure/lambda that Kotlin code will later call passing in a Kotlin lambda. This works fine as long as that lambda is not a suspending one. Does SKIE provide anything that would allow that to work i.e. using suspending lambda? (btw we are using SKIE in project right now) Firstly showing below what actually works
Copy code
// Kotlin
fun myFunc(val someSwiftClosure: (kotlinFunc: (Int) -> Unit) -> Unit)

// Swift 
myFunc(someSwiftClosure: { kotlinFunc in
   kotlinFunc(1) // invoking here immediately as example but plan would be to store and invoke later
})
if however I try something like following for example then I get
Cannot call value of non-function type 'any KotlinSuspendFunction1'
Copy code
// Kotlin
fun myFunc(val someSwiftClosure: (kotlinFunc: suspend (Int) -> Unit) -> Unit)


// Swift 
myFunc(someSwiftClosure: { kotlinFunc in
   Task {
       await kotlinFunc(1)
   }
})
t
That's a good question. What I'd recommend for now is to use a class rather than the
suspend (Int) -> Unit
. For example:
Copy code
data class SuspendFunction1Wrapper<P1: Any, Result: Any>(
  private val function: (P1) -> Result,
) {
  suspend fun invoke(p1: P1): Result = function(p1)
}

fun myFunc(someSwiftClosure: (kotlinFunc: SuspendFunction1Wrapper<Int, Unit>) -> Unit)

// Swift
myFunc { kotlinFunc in
  Task {
    try await kotlinFunc.invoke(p1: 1)
  }
}
It's not perfect, but at this point I don't think there's a different way to go around it. Also keep in mind
Task { ... }
in Swift breaks cooperative concurrency (it's the same as Kotlin's
GlobalScope.launch { ... }
in this case). I could see SKIE hiding the original implementation and replacing it with an extension function that'd replace
KotlinSuspendFunction1
with a real async lambda, but that's essentially a new SKIE feature.
j
Thanks, will try that. Btw was just using that Task to try and make example more minimal
🙌 1
t
Ah, I see. I just wanted to make sure 😄
j
Probably not a very common use case ;)
t
You'd be surprised
I'm working on an experimental feature for SKIE that'd allow implementing interfaces with suspend functions properly from Swift.
👀 1
And I can see the usecase where you have async function taking in async work closure. For example a
.map
function is a good example.
👍 1
j
Interesting
Just to confirm that approach worked, thanks again
🙌 1