https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
s

Simon Buechner

10/09/2023, 7:00 AM
Hi everyone, does someone has experience with KMP native Coroutines? I have a Stateflow with a list of CBPeripherals wrapped in a data class, so BluetoothDevice { peripheral: CBPeripheral, rssi: Int} but if I use the native coroutine I can only access rssi but not the peripheral on the swift side in the publisher. Maybe this question doesn’t really belong here but I am really stuck for now and I hope someone has experience with this in here 😬
r

Rick Clephas

10/09/2023, 7:02 AM
Could you possibly share the relevant code?
s

Simon Buechner

10/09/2023, 7:06 AM
Copy code
KMM Side
@NativeCoroutines
val discoveredDevicesFlow = session.discoveredDevicesFlow

iOS Side
        // Create an AnyPublisher for your flow
        let publisher = createPublisher(for: facade.discoveredDevicesFlow)

        // Now use this publisher as you would any other
        publisher.receive(on: mainQueue).sink { completion in
            print("Received completion: \(completion)")
        } receiveValue: { value  in
            self.discoveredDevices = value
        }.store(in: &cancellables)
r

Rick Clephas

10/09/2023, 7:14 AM
Anything special about the
BluetoothDevice
data class? KMP-NativeCoroutines shouldn’t change the way the Flow value is represented.
s

Simon Buechner

10/09/2023, 7:16 AM
not that i know @Rick Clephas
Copy code
data class BluetoothDevice(
    val peripheral: BluetoothDevice,
    var rssi: Int,
)
BluetoothDevice has a typealias for BluetoothDevice in android and CBPeripheral in ios
r

Rick Clephas

10/09/2023, 7:38 AM
In that case it might me a limitation of the ObjC interop. Do you see the
peripheral
property in Swift with type
Any
? (there is a limitation where Kotlin types implementing/inheriting ObjC types aren’t exposed to ObjC/Swift)
s

Simon Buechner

10/09/2023, 7:40 AM
i dont see it, if i try to access the property of the value on the swift side. i see it if i look into the fat framework, there has the attribute of bluetoothdevice the type of CBPeripheral.
r

Rick Clephas

10/09/2023, 7:42 AM
Hmm oke and the type of
value
(in Swift) is just an array of `BluetoothDevice`s?
s

Simon Buechner

10/09/2023, 7:42 AM
thats right.
i can use it, i can list the found devices if i display a list of device.rssi but i cannot use the full device for anything without getting an error: Conflicting arguments to generic parameter 'Content' ('ForEach<[BluetoothDevice], String, <<hole>>>' vs. 'ForEach<[BluetoothDevice], String, <<hole>>>' vs. 'ForEach<[BluetoothDevice], String, <<hole>>>' vs. 'ForEach<[BluetoothDevice], String, <<hole>>>') In my view.
r

Rick Clephas

10/09/2023, 7:47 AM
According to the error messages the
<<hole>>>
generics aren’t the same. What does the
ForEach
code look like?
s

Simon Buechner

10/09/2023, 7:50 AM
ah sorry posted an old data class:
Copy code
data class CustomDevice(
    val peripheral: BluetoothDevice,
    val identifier: String,
    var rssi: Int,
)
needed the identifier.
Copy code
List(viewModel.discoveredDevices, id: \.identifier){ device in
      Button("device.rssi", action: viewModel.connect(device:device)
}
if i use it like this, i can at least call the function and everything works, but accessing the peripheral is on the swift side again not possible:
Copy code
Text("\(digipen.rssi)")
        .onTapGesture { viewModel.connect(device: device) }
r

Rick Clephas

10/09/2023, 8:01 AM
That’s interesting, I haven’t experienced something like that yet.
i see it if i look into the fat framework
If that’s the case, it sounds more like a Swift issue than a Kotlin one.
s

Simon Buechner

10/09/2023, 8:09 AM
Mhm thats sad for finding my problem 😄 but thanks for your help @Rick Clephas Im not sure where it could be an swift issue, it just has no member peripheral directly in the publisher receive call. 😕
oh but at the moment i see the value has no members and it seems to be of type any therefore.
so it seems like it could be a cinterop problem actually @Rick Clephas
i just converted the value to [CustomObject] therefore i could access rssi because its a simple int value but peripheral could not be converted?? semms this reasonable ?
r

Rick Clephas

10/09/2023, 8:13 AM
If you cast the value to your data class you should be able to access all the properties not just
rssi
.
s

Simon Buechner

10/09/2023, 8:51 AM
mhm it was just a mad moment of mine ... i tried to access value but i forgot it is a list and not the object. i can just access the first list item and can see it has rssi and identifier so the simple values but it doesnt show the peripheral attribute.
@Rick Clephas ... i found my problem, thanks for your help. 😄 mondays is always hard ... the problem was the missing corebluetooth import ....
r

Rick Clephas

10/09/2023, 11:10 AM
Nice! Glad you find the issue 👍🏻
3 Views