I am trying to write SocketIO wrapper to use in co...
# multiplatform
h
I am trying to write SocketIO wrapper to use in common code. I want to use
expect/actual
to do it. I have an interface like this is
commonMain
Copy code
expect interface ChatSocketService {

    suspend fun initialize(token: String, endpoint: String, broadcastUrl: String) : Resource<Unit>

    suspend fun emitEvent(event: Events, ids: ArrayList<Int>, chatKey: String)

    fun observeMessages() : Flow<SocketResponse>

    suspend fun closeSession()
}
Implementing this in
androidMain
is not a problem. It's the
iosMain
implementation that's causing problem. I can't import the native ios socket io client into
iosMain
module. Two questions. First how can I import native ios SocketIO library into
iosMain
and second question is if I will write native iOS code to handle socket io and put that class inside
iosMain
how can I import that into my
actual
implementation ?
p
Really expect interface is kind of redundant. But anyways, you need to implement the interface in swift/objective-c side, due to 3rd party dependencies. In your iosMain sourceset, create a setter that receives the interface. I believe the multiplatform plugin objectivec interop, will generate a type for you in the swift side. Implement that type, and use the setter to put the implementation in kotlin land. Xcode autocompletion will help you find the exported interface name.
j
https://kotlinlang.org/docs/multiplatform-mobile-ios-dependencies.html#with-cocoapods Should be able import with pods as of example and use iOS socket in your iOSMain kotlin code :)
h
can I put Swift file in
iosMain
and import it into Kotlin code?
j
I think need kmmbridge if want ship like pod swift code into kotlin multiplatform. Not sure can do direct interop. I know can do other direction. I personally would check if Ktor multiplatform is an option. They have websocket support.
But I havent tried mix swift and kotlin code in same kotlin multiplatform, maybe work somehow but need to tell Gradle somehow :)
h
Ktor has websockets but sadly socket io is different than websocket. I guess this is the bad side of multiplatform. I will need to implement socket handling on platform spesific viewmodels instead of common code
j
Yeah complex with bi-directional interop. Had similar issue with navigation stuff but not this level. Probably is some library or such I am not aware of yet doing what you want.
h
there's actually a library present but that library also has it's own problems so I stuck in the middle of nowhere 😄
j
Checking moko socket io: https://github.com/icerockdev/moko-socket-io/tree/master/socket-io%2Fsrc%2FiosMain Looks like can mix swift and kotlin but need some mapper back to commonMain I think
h
yes this is the library but it has a problem that needs to be fixed. if you are using emulator to test ios app this library won't compile
j
I was thinking test how they structure iosMain and do it yourself :) To see if works. Like test simple swift case and build pods from it.
h
oh 🙂 good idea
will try now
j
I am very curious myself learning these things, how to get best from Swift and iOS native when needed in Kotlin / compose multiplatform. In past I also had implement custom websocket protocols so know the struggle. Most often used some basic websocket library allow me do custom Protocol.
h
so should I try to implement socket io interface on top of websocket?
if that will work I don't need to do this stuff
j
Not sure, I dont know socket.io protocol. But imagine if ktor or such allows custom. If worst case using http socket with websocket on top works but a little pain.
https://www.artandscienceofcoding.com/science/avoid-this-kmm-technique/ Interesting post about this topic btw :) If can use obj-c instead of Swift seems full interop.
h
I literally read that yesterday in the hope that maybe there's a simpler way to all this
seems like there isn't 😄
j
Yeah this feels like similar downside when using Flutter or React Native. We need pure bi-directional interop bridges to solve these kind of stuff, at least a way put swift modules in parallell also can use expect or inject bridged linking on the fly. I would presume limitation is LLVM that KMM using. I mean all possible but if threshold to high its not worth the silver bullet multiplatform. But I am pretty sure this will or have to be solved to promote iOS KMM to stable in future. I think hard get good adoption rate without it.
h
agreed there's no point of multiplatform without bi directional interop
multiplatform compose and all that sounds good and fun until you need to call a ios library from your common code
j
There is interop with obj-c and swift libs using @objc wrapier its worth noting. There is work and discussions about support pure swift. But Kotlin also need support latest JS, new K2 compiler, latest JVM changes etc. I presume large scale out of resources. Yeah main idea with KMM sharing logic also means sharing network layer, decoupling network calls and such very hard. I mean shared websocket layer split between platforms. Most often need different expect interfaces to provide stuff required for each call variant. Like interception, headers etc. This is solveable but I guess using websockets painful. Can tell Websockets has been very hard within just one platform like Android earlier. Mostly because JVM stuff. But doesnt socket.io provide any obj-c layer?
h
no it doesn't. they linked the library you mentioned above as their multiplatform version and that's it
j
No I mean https://github.com/socketio/socket.io-client-swift/tree/master/Source%2FSocketIO It looks like they have objc pod but not sure. I am Android dev primary and still learning iOS stuff.
h
I can import this as pod into
iosMain
yes. I did that
j
h
I am also Android dev learning ios through erros and tries : )
by doing this I can import SocketIO library into iosMain
pod("Socket.IO-Client-Swift", version = "15.2.0", moduleName = "SocketIO")
then I can import it in Kotlin code through cocoapods.SocketIO
j
Can you use the classes/api after that?
h
yes I can
but certain classes are not available
j
Right, I guess they are pure Swift in that case. Seen some socket.io objc wrappers.
h
will try to do that right now
j
Good luck, hope it works out! :)
h
Thank you very much. I tried to implement using this method basically half of the library is not available because of this Swift problem. Classes like this https://nuclearace.github.io/Socket.IO-Client-Swift/Structs/SocketIOClientConfiguration.html are not available
there's a pure objective c version of socket io library but that dates back to 2015
This guys have pure swift implementation of SocketIO https://github.com/icerockdev/moko-socket-io/blob/a770aaa500fa7839f12c929b1e56d80a65f8fcb1/socket-io/src/iosMain/swift/SocketIo.swift if only that was possible to use that class inside the iosMain that would be amazing
SocketIO is a popular library I am also surprised why there isn't any alternative KMM libs for this
h
Hi @Hasan Nagizade, what is your final decision here? I faced the same problem, thinking about moko-socket-io. Looks like they added support for iOS simulator.
h
@hadzinets hi I will try that actually. Will let you know here
382 Views