question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Swift's flow.collect function only receives first value

See original GitHub issue

Having created a simple flow in common code to emit incrementing values with a delay as follows:

flow {
    (1..10).forEach {
        emit(it.toString())
        delay(1000)
    }
}.flowOn(Dispatchers.Default)

When observing using Swift with:

class AModel: Kotlinx_coroutines_coreFlowCollector {    
    func emit(value: Any?, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
        print("ios received " + (value as! String))
    }
}

val state: AModel = AModel()

flow.collect(collector: state) { (result: KotlinUnit?, error: Error?) in
    print("completion")
}

Actual: Only the first value is received and printed by the Kotlinx_coroutines_coreFlowCollector. Additionally the flows completion block is not executed. The same common code works on Android.

Expected: All values to be received and printed and the flow to complete once the last value has been received.

Kotlin: 1.4.10 Coroutines: 1.3.9-native-mt-2 Xcode: 12.0.1 iOS simulator: iPhone 11 running 14.0 Swift: 5

FYI @qwwdfsad this is the issue we discussed in the Kotlin 1.4 Online booth call.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
ciffacommented, Mar 3, 2021

Could it be that you’re not calling the completion handler and therefore not clearing the queue?

func emit(value: Any?, completionHandler: @escaping (KotlinUnit?, Error?) -> Void) {
    print("ios received " + (value as! String))
    completionHandler(KotlinUnit(), nil)
}
0reactions
mattmookcommented, Jun 24, 2021

Yes @ciffa calling the completionHandler does make this work (tested with 1.4.3-native-mt)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Combining Kotlin Flows with Select Expressions
A select expression is created to listen to the emission of both producers. The select expression runs until a value is received from...
Read more >
Listen to Kotlin coroutine flow from iOS - Stack Overflow
You can do it in swift, with the mentioned collect method FlowCollector is a protocol which can be implemented to collect the data...
Read more >
Closures — The Swift Programming Language (Swift 5.7)
method accepts a closure that takes two arguments of the same type as the array's contents, and returns a Bool value to say...
Read more >
Using Kotlin Flow in Swift - Better Programming
Working with asynchronous flows from Kotlin Multiplatform as ... Function to collect a Flow Wrapper Function in Swift (full source of ...
Read more >
Kotlin flow: collect only elements which repeat at least N times ...
suspend fun test() = coroutineScope { val flow = MutableSharedFlow<String>() launch { flow.repeated(3).collect { value -> println("received: $value") } ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found