When using <https://github.com/rickclephas/KMP-Nat...
# multiplatform
j
When using KMP-NativeCoroutines from SwiftUI, are we supposed to add an “import” statement? The documentation doesn’t mention anything I think. If I add
import KMPNativeCoroutinesAsync
I get
Could not find module 'KMPNativeCoroutinesAsync' for target 'x86_64-apple-ios-simulator'
and if I don’t add it I get
Cannot find 'asyncResult' in scope
(Yes I added the dependency from Xcode File > Add Packages. I use “branch” and “master” because it can’t resolve the dependency with version options)
r
Hi! Not really SwiftUI specific, but yeah you'll need an import.
KMPNativeCoroutinesAsync
is indeed the one for the
asyncResult(for:)
function.
Is
KMPNativeCoroutinesAsync
also part of your targets framework dependencies?
P.S. will update the docs to include the import. Those are indeed missing at the moment.
Regarding the dependency version. If I am not mistaken then it should work when used without the kotlin suffices. E.g.
1.0.0-ALPHA-13
should be accepted by Xcode.
a
Thanks @Rick Clephas for taking the time to update this it wasn't intuitive for me either the first time i used it, i think it would be more easier to specify a section in the documentation just for choosing between the package variants and breakdown every possible one. Also as @jean mentioned it's very important to include the import based on the variant and then a sample
@Rick Clephas Let me know if you want me to do this contribution i would be happy to help 🙏
s
@Rick Clephas is Alpha-13 already available??? i can only see alpha 10 in your repository
r
Thanks for the feedback @Ahmed Elshaer, much appreciated.
@SanjayKarki yeah 1.0.0-ALPHA-13 is available, it bumps the Kotlin version to 1.9.0: https://github.com/rickclephas/KMP-NativeCoroutines/releases/tag/v1.0.0-ALPHA-13
s
@Rick Clephas could you please tell me what i am doing wrong in this comments
Copy code
package com.outcodesoftware.outcodesuite.framework

import com.rickclephas.kmm.viewmodel.KMMViewModel
import com.rickclephas.kmm.viewmodel.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow


abstract class BaseVM<Event, VState>(val overrideSuccess: Boolean = false): KMMViewModel() {
    abstract fun initState(): VState
    abstract fun onHandleEvent(event: Event)

    abstract fun logState(state: VState)

    abstract fun <T> responseToState(it: AppResult<T>)

    protected val state: VState by lazy {
        initState()

    }

//    private var uiState = MutableStateFlow(viewModelScope = viewModelScope,value = state)
//    var uiStateUI = uiState.asStateFlow()


//
//     fun setState(newState: VState){
//        viewModelScope.coroutineScope.launch {
//            delay(200)
//            uiState.value = newState
//            logState(state)
//        }
//    }

}
r
@SanjayKarki I don't see anything obviously wrong. What issue are you facing exactly?
s
@Rick Clephas Well, if i uncomment bottom codes then it doesnot effect the IOS (works fine on ios without issues) but on android it shows following error.
r
Hmm oke that’s strange. Could you possibly share a reproducer?
j
I tried again with “exact version” and it worked this time. But I still get this error on the import level
Copy code
Could not find module 'KMPNativeCoroutinesAsync' for target 'x86_64-apple-ios-simulator'; found: arm64-apple-ios-simulator, at: /Users/.../Debug-iphonesimulator/KMPNativeCoroutinesAsync.swiftmodule
r
@jean could you verify that
KMPNativeCoroutinesAsync
is listed under “Frameworks, Libraries, and Embedded Content” in you targets general settings?
j
It is
By creating a new project in XCode and choosing “iOS > App” instead of “Multiplatform > App” then I don’t have the error on
import KMPNativeCoroutinesAsync
🤔
r
Alright that's interesting. Will take a look at that.
@jean just tried to reproduce the “could not find module” issue, however in my case both the iOS app and the multiplatform app are building fine (using Xcode 14.3.1). Could share some more details about your multiplatform app project setup?
j
I just created the project and tried to add the dependency, nothing special. Since it worked with the second project i created and that I only needed iOS support, I deleted the first one. I can try again when I have a moment and let you know how it goes.
I do have another issue though. I can’t figure out how to use my generated code from Swift
Copy code
// Generated code inside the shared library
public val HomeScreenHelper.stateFlow: NativeFlow<HomeScreenState>
  get() = state.asNativeFlow(null)

// Inside the ios app
@State private var viewState: HomeScreenState
...
private func observeStateChanges() {
    createPublisher(for: homeScreenHelper.stateFlow).sink { completion in
        print("Received completion: \(completion)")
    } receiveValue: { value in
        viewState = value
    }
}
It compiles but nothing happens. In the Readme page it says
let publisher = createPublisher(for: clock.time)
but I guess it should be
clock.timeFlow
?
r
Depending on the annotation it is indeed either
time
or
timeFlow
(or in your case
state
or
stateFlow
). The
@NativeCoroutines
annotation reuses the original property name for the
Flow
property, which would result in
time
. However if you use
@NativeCoroutinesState
then the name is reused for the value property, exposing the flow itself as
timeFlow
. So depending on your use case you can pick the annotation that will result in the most logical Swift property name.
Regarding the fact that nothing is happening. This is the actual code? In that case the Combine publisher will be immediately cancelled at the end of
observeStateChanges
since the
AnyCancellable
returned by
sink
gets deallocated. Storing the cancellable in a property will prevent that.
j
This is the actual code. Still no update even if I add
let cancellable = createPublisher...
🤔
r
Sorry about that I meant a class property:
Copy code
import Combine
 
class MyClass {
 
    var cancellable: AnyCancellable? = nil
 
    func observeStateChanges() {
        cancellable = createPublisher(for: ...).sink { ... }
    }
}
j
Nice! I didn’t know about that and it works now, thanks for the help!
👍 1
n
for anyone else experiencing this, I ran into an issue where it wasn't importing the correct version of KMP-NativeCoroutines. I tried adding it via the package.swift, which didn't work (my assumption was I need to add this to my own package.swift of the library that I am importing in). I then received the error: Cannot find 'asyncResult' in scope, and I couldn't import
KMPNativeCoroutinesAsync
either as they weren't found.I discovered that for some reason it was importing some really old version of
KMPNativeCoroutines
that probably didn't have
KMPNativeCoroutinesAsync
. Solution: remove the swift package (when you go to add a package, right click on the package in the "recently used" column, and click on remove. Add it back but this time select the master branch instead of specifying the version. It's probably not ideal but this is the only way I could get it to work. I know nothing about xcode and how it works so I probably did something wrong along the way.
r
Thanks for the info @Nick. Did you initially specify the version via the "exact version" option? As far as I know using the exact version (e.g.
1.0.0-ALPHA-14
) should work. Please let me know if that isn't the case.
n
sorry i missed this! It's a month later so I can be for sure... i believe I did specify the exact version (i followed the instructions on the github page).