Is it possible to make a Swift struct implement a ...
# kotlin-native
t
Is it possible to make a Swift struct implement a Kotlin interface? For example in Swift:
Copy code
struct MyStruct : KotlinInterface {
}
And in Kotlin:
Copy code
interface KotlinInterface {
    ...
}
I tried this but it gives the following error:
Copy code
Non-class type 'MyStruct' cannot conform to class protocol 'KotlinInterface'
s
t
Thanks for the reply. This is quite disappointing because I would like to use the new SwiftUI. The view in Swift must be a
struct
and I want it to implement a Kotlin interface. (MVP, where the struct is the V)
@svyatoslav.scherbina Would you know about another way how I can call functions in a struct from Kotlin? (as I can not implement an interface). I think this issue makes it impossible to use SwiftUI if you need to change stuff from Kotlin. (e.g. change the text of a button)
s
I believe it is possible to define a class wrapping structure field and make it adopt Kotlin protocol. If your methods are mutating, then this field should be mutable and its value should be copied back (maybe some of this could be automated).
k
@Thomas Can you post some code on this? I want to understand how you’re trying to interface with the Kotlin code better.
t
@kpgalligan Of course. In short, my app is made like this:
Copy code
interface MainScreen {
    /**
     * On Android the View is a Fragment (in Kotlin/Java).
     * On iOS the View is a UIViewController (in Swift).
     * 
     * The view has commands to update the UI. These functions are called from the Presenter.
     */
    interface View : MvpView {
        fun setText(text: String)
    }

    /**
     * Presenter is implemented completely in Kotlin. It receives events from the View, like onButtonClicked.
     */
    interface Presenter : MvpPresenter<View> {
        fun onButtonClicked()
    }
}
This way I can share as much code as possible between Android/iOS. The “View” interface just gets commands to update the UI. I’m currently implementing the Kotlin
MainScreen.View
interface in the
UIViewController
. I’m now looking into the new SwiftUI which is a very good improvement over the UIViewController/storyboard. The SwiftUI view is not created as a class but as a struct. Something like this:
Copy code
struct MainView : View {
    var body: some View {
        Text("Hello world!")
    }
}
I need to find a way to change the text from the Presenter, via the View interface. As this is a struct, I cannot implement the
MainScreen.View
interface. I’m currently exploring other options. The SwiftUI also has a class
BindableObject
(with
EnvironmentObject
annotation). (See Section 4/5 at https://developer.apple.com/tutorials/swiftui/handling-user-input). This is a
class
, so I can implement a Kotlin interface. This might do what I need and I am currently looking into it. Let me know if you would like to see more details.
s
In SwiftUI the views aren't actual views. They're a shadow dom like implementation and are immutable. Any mutation you need to do to the view should be done against the state that the view is bound to.
t
@Sam So should I implement the Kotlin view interface in
BindableObject
? https://developer.apple.com/documentation/swiftui/bindableobject (See Section 4/5 at https://developer.apple.com/tutorials/swiftui/handling-user-input)
s
Without having actually programmed anything using SwiftUI yet, that would be my thought. Your presenter will command the bound data object to do something and that will get reflected in the updated view state.