Thomas
05/06/2019, 12:35 PMinterface View : MvpView {
// shows a dialog which returns a String.
suspend fun showDialog(): String
}
I’m not sure how I can implement this for iOS. I thought the following workaround would work:
interface View : MvpView {
// implement this in Android (Kotlin)
suspend fun showDialog(): String = suspendCancellableCoroutine { showDialog(it) }
// implement this in iOS (Swift)
fun showDialog(cont: CancellableContinuation<String>): Unit = throw NotImplementedError()
}
This would allow me to use suspend functions from the calling code and the Android implementation, and just a normal function for iOS. However, it looks like default functions for interfaces are not supported. (https://github.com/JetBrains/kotlin-native/issues/2638)
What would be the best way to solve this? Not use suspend functions at all?Tobi
05/06/2019, 12:51 PMsvyatoslav.scherbina
05/07/2019, 6:27 AMsuspend fun showDialog(): String = suspendCancellableCoroutine { showDialog(it) }
into extension.Thomas
05/07/2019, 7:35 AMsvyatoslav.scherbina
05/07/2019, 8:04 AMinterface View
interface IosView : View {
fun showDialog(cont: CancellableContinuation<String>): Unit
}
interface AndroidView : View {
suspend fun showDialog(): String
}
suspend fun View.showDialog(): String = when (this) {
is AndroidView -> this.suspendDialog()
is IosView -> suspendCancellableCoroutine { showDialog(it) }
else -> TODO()
}
Cyrille QUÉMIN
08/08/2019, 10:36 PMinterface View{
suspend fun myFunSuspend().
}
// for Android, normal implementation of co routine
// for iOS see below
class iOSViewWrapper(private val iOSImpl: IosView) : View {
override suspend fun myFunSuspend(){
return suspendCoroutine {
iOSImpl.doAsyncJob{ data, error ->
if(error != null){
it.resumeWithException(error)
}else{
it.resume(data)
}
}
}
}
}
interface IosView {
fun doAsyncJob((data: ByteArray, error: Throwable?)-> Unit)
}
the function doAsyncJob
implementation is done in Swift and is called many times inside my kotlin code.
I have defined a coroutine scope that is using the ios dispatch_get_main_queue
.
I have made sure that doAsyncJob
is execute AND invoke the closure on the main thread.
The code works but crashes always in the swift invocation of the closure.
Sometimes after 1 call sometimes after 6 or 10, ...
I tried to declare the closure of doAsyncJob
as a variable and call .freeze()
on it, but I get
kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for DispatchedContinuation[MainDispatcher@7d793018, Continuation @ $prepareCOROUTINE$11]. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
at 0 mylib 0x0000000100f81e98 kfun:kotlin.Error.<init>(kotlin.String?;kotlin.Throwable?)kotlin.Error + 24
at 1 mylib 0x0000000100f81bc0 kfun:kotlinx.coroutines.CoroutinesInternalError.<init>(kotlin.String;kotlin.Throwable)kotlinx.coroutines.CoroutinesInternalError + 24
at 2 mylib 0x0000000100f81818 kfun:kotlinx.coroutines.DispatchedTask.handleFatalException$kotlinx-coroutines-core(kotlin.Throwable?;kotlin.Throwable?) + 284
at 3 mylib 0x0000000100f82540 kfun:kotlinx.coroutines.DispatchedTask.run() + 1224
what am I doing wrong?Cyrille QUÉMIN
08/08/2019, 10:37 PM1.3.41
and coroutine 1.3.0-M2
with an mpp project android and ios @svyatoslav.scherbinasvyatoslav.scherbina
08/09/2019, 7:40 AMThe code works but crashes always in the swift invocation of the closure.Could you share the stack trace of such a crash?
I tried to declare the closure ofThis transitively freezes your continuation too (since it is captured), which is not correct.as a variable and calldoAsyncJob
.freeze()
Cyrille QUÉMIN
08/10/2019, 3:13 PM#0 0x000000010276db6c in UpdateHeapRef ()
#1 0x00000001026be4cc in blockDisposeHelper ()
#2 0x00000001af1dca48 in _Block_release ()
#3 0x00000001021e10c4 in ___lldb_unnamed_symbol13$$iosSampleApp ()
#4 0x00000001bcdfe9ac in _swift_release_dealloc ()
#5 0x00000001021e0e48 in ___lldb_unnamed_symbol12$$iosSampleApp ()
#6 0x00000001bcdfe9ac in _swift_release_dealloc ()
#7 0x00000001021c6280 in ___lldb_unnamed_symbol7$$iosSampleApp ()
#8 0x00000001bcdfe9ac in _swift_release_dealloc ()
#9 0x00000001021c6408 in block_destroy_helper ()
#10 0x00000001af1dca48 in _Block_release ()
#11 0x00000001af1dca48 in _Block_release ()
#12 0x00000001d8091cf0 in __destroy_helper_block_e8_32o40o48o56b ()
#13 0x00000001af1dca48 in _Block_release ()
#14 0x0000000102a46c88 in _dispatch_client_callout ()
#15 0x0000000102a4dbf8 in _dispatch_lane_serial_drain ()
#16 0x0000000102a4e7c8 in _dispatch_lane_invoke ()
#17 0x0000000102a59b88 in _dispatch_workloop_worker_thread ()
#18 0x00000001af304fa8 in _pthread_wqthread ()
Enqueued from com.apple.main-thread (Thread 1) Queue : com.apple.main-thread (serial)
#0 0x0000000102a4b0dc in dispatch_async ()
#1 0x00000001d8091b30 in -[Tag _sendWithData:completionHandler:] ()
#2 0x00000001d8091ea4 in -[Tag _send:completionHandler:] ()
#3 0x00000001021c60dc in Session.sendCommand(command:completionHandler:) at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/iosSampleApp/iosSampleApp/iosSampleApp/ReaderSession.swift:92
#4 0x00000001021e0410 in Transceiver.sendCommand(dataToSend:completionHandler:) at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/iosSampleApp/iosSampleApp/iosSampleApp/iOSController.swift:46
#5 0x00000001021e1034 in @objc Transceiver.sendCommand(dataToSend:completionHandler:) ()
#6 0x00000001027485dc in ___lldb_unnamed_symbol355$$myapp ()
#7 0x00000001027214fc in kfun:com.myApp.session.MessagingSession.$sendCommandCOROUTINE$12.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/session/MessagingSession.kt:53
#8 0x000000010271fdc8 in kfun:com.myApp.session.MessagingSession.sendCommand(com.myApp.Command)com.myApp.Response at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/session/MessagingSession.kt:38
#9 0x0000000102722708 in kfun:com.myApp.reader.FileReader.$readFirstBlockCOROUTINE$7.invokeSuspend#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/reader/FileReader.kt:106
Cyrille QUÉMIN
08/10/2019, 3:15 PM#10 0x000000010271ebf4 in kfun:com.myApp.reader.FileReader.readFirstBlock#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/reader/FileReader.kt:99
#11 0x000000010271e76c in kfun:com.myApp.reader.FileReader.$readCOROUTINE$5.invokeSuspend(kotlin.Result<kotlin.Any?>)kotlin.Any? at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/reader/FileReader.kt:51
#12 0x000000010271e5dc in kfun:com.myApp.reader.FileReader.read()kotlin.ByteArray at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/reader/FileReader.kt:48
#13 0x000000010271d6dc in kfun:com.myApp.reader.ReaderWorker.read(com.myApp.chipinfo.ChipInfo;com.myApp.session.MessagingSession?;com.myApp.reader.FileType;kotlin.Function2<kotlin.Int,<http://kotlin.Int|kotlin.Int>,kotlin.Unit>?)kotlin.ByteArray at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/reader/ReaderWorker.kt:120
#14 0x000000010271ca54 in <inlined-out:<anonymous>> [inlined] at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/Reader.kt:84
#15 0x000000010271c880 in kfun:kotlin.collections.forEach@kotlin.collections.Iterable<#GENERIC>.(kotlin.Function1<#GENERIC,kotlin.Unit>)Generic [inlined] at /Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/generated/_Collections.kt:146
#16 0x000000010271c880 in kfun:com.myApp.Reader.$read$lambda-0COROUTINE$0.invokeSuspend#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/commonMain/kotlin/com/my/app/Reader.kt:79
#17 0x000000010270568c in <inlined-out:<anonymous>> [inlined] at /Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt:30
#18 0x0000000102705650 in kfun:kotlin.with(#GENERIC;kotlin.Function1<#GENERIC,#GENERIC>)Generic [inlined] at /Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/kotlin/util/Standard.kt:53
#19 0x0000000102705650 in kfun:kotlin.coroutines.native.internal.BaseContinuationImpl.resumeWith(kotlin.Result<kotlin.Any?>) at /Users/teamcity/buildAgent/work/4d622a065c544371/runtime/src/main/kotlin/kotlin/coroutines/ContinuationImpl.kt:26
#20 0x0000000102709920 in kfun:kotlin.coroutines.resume@kotlin.coroutines.Continuation<#GENERIC>.(#GENERIC)Generic [inlined] at /Users/teamcity/buildAgent/work/4d622a065c544371/backend.native/build/stdlib/kotlin/coroutines/Continuation.kt:44
#21 0x00000001027098f0 in <inlined-out:<anonymous>> [inlined] at /opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Dispatched.kt:158
#22 0x00000001027098f0 in kfun:kotlinx.coroutines.withCoroutineContext$kotlinx-coroutines-core(kotlin.coroutines.CoroutineContext;kotlin.Any?;kotlin.Function0<#GENERIC>)Generic [inlined] at /opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/native/src/CoroutineContext.kt:47
#23 0x00000001027098f0 in kfun:kotlinx.coroutines.DispatchedTask.run() at /opt/buildAgent/work/44ec6e850d5c63f0/kotlinx-coroutines-core/common/src/Dispatched.kt:158
#24 0x000000010274a5a0 in kfun:com.myApp.util.MainDispatcher.dispatch$lambda-0#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/iosMain/kotlin/com/my/app/util/Coroutines.kt:24
#25 0x000000010274a550 in kfun:com.myApp.util.MainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$46.invoke#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/iosMain/kotlin/com/my/app/util/Coroutines.kt:23
#26 0x000000010274a51c in kfun:com.myApp.util.MainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$46.$<bridge-UNN>invoke()#internal at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/mpp/src/iosMain/kotlin/com/my/app/util/Coroutines.kt:23
Cyrille QUÉMIN
08/10/2019, 3:15 PM#27 0x000000010276846c in platform_darwin_kniBridge202 at /Users/teamcity/buildAgent/work/4d622a065c544371/platformLibs/build/konan/libs/ios_arm64/darwin.klib-build/kotlin/platform/darwin/darwin.kt:24587
#28 0x000000010277dce4 in __platform_darwin_kniBridge201_block_invoke ()
#29 0x0000000102a458ac in _dispatch_call_block_and_release ()
#30 0x0000000102a46c88 in _dispatch_client_callout ()
#31 0x0000000102a54ce8 in _dispatch_main_queue_callback_4CF ()
#32 0x00000001af5648bc in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
#33 0x00000001af55f8b0 in __CFRunLoopRun ()
#34 0x00000001af55edb4 in CFRunLoopRunSpecific ()
#35 0x00000001b986e328 in GSEventRunModal ()
#36 0x00000001b35b5e94 in UIApplicationMain ()
#37 0x00000001021bcfb4 in main at /Users/cyrille.quemin/Documents/git/mpp-trial-coroutine/iosSampleApp/iosSampleApp/AppDelegate.swift:12
#38 0x00000001af3ea424 in start ()
Cyrille QUÉMIN
08/10/2019, 3:16 PMThis transitively freezes your continuation too (since it is captured), which is not correct.
I am not sure what to do since it feels like the closure is freed from memory if not held in a member vsriable in the swift class. Which is what is causing the crash: The closure cannot be invokedsvyatoslav.scherbina
08/12/2019, 9:29 AMI am not sure what to do since it feels like the closure is freed from memory if not held in a member vsriable in the swift class. Which is what is causing the crash: The closure cannot be invokedNo.
Cyrille QUÉMIN
08/12/2019, 10:36 AMsvyatoslav.scherbina
08/12/2019, 11:35 AM