HI all, I'm having a problem with interfaces on iO...
# multiplatform
b
HI all, I'm having a problem with interfaces on iOS. In my common code, I define an interface, and expected interface implementation:
Copy code
interface CommonErrorPlugin {
    fun logMessage(message: String)
    fun recordStateValue(key: String, value: Any)
    fun setUserId(userId: String?)
}

expect interface ErrorPlugin: CommonErrorPlugin
In my iOS source set, I provide an actual implementation of the
ErrorPlugin
interface:
Copy code
actual interface ErrorPlugin: CommonErrorPlugin {
    fun logError(error: NSError)
}
This is crashing on iOS, and I'm not sure why? More info in the thread ...
In my swift code, I implement the
ErrorPlugin
interface protocol
Copy code
class FirebaseErrorPlugin: ErrorPlugin {
    private let crashlytics = Crashlytics.crashlytics()
    
    func logError(error: any Error) {
        crashlytics.record(error: error, userInfo: [:])
    }
        
    func recordStateValue(key: String, value: Any) {
        crashlytics.setCustomValue(value, forKey: key)
    }

    func logMessage(message: String) {
        crashlytics.log(message)
    }
    
    func setUserId(userId: String?) {
        crashlytics.setUserID(userId)
    }
}
I pass an instance of this class to a Kotlin object, which calls it's methods. For example, when a user logs in, it'll call the
setUserId()
method with the user's userid. In iOS, when any of these methods are called, my app crashes. It doesn't ever even get to the swift code. The crash happens on the actual plugin definition line in the ios source set:
actual interface ErrorPlugin: CommonErrorPlugin {
(see attached screen shot). the other thing is, I have have exception handling in place, both try/catch blocks in the kotlin code, as well as a do/catch in the swift code, and neither of them get called. I'm not sure what's going on here?
I still don't know why this happens, but I did figure out a solution. I eliminated the
CommonErrorPlugin
interface, and just put it's methods in my (expected)
ErrorPlugin
interface:
Copy code
expect interface ErrorPlugin {
    fun logMessage(message: String)
    fun recordStateValue(key: String, value: Any)
    fun setUserId(userId: String?)
}
then, include the methods again when I build the actual implementations. So, the ios implementation looks like:
Copy code
actual interface ErrorPlugin {
    actual fun logMessage(message: String)
    actual fun recordStateValue(key: String, value: Any)
    actual fun setUserId(userId: String?)
    
    // ios specific interface method 
    fun logError(error: NSError)
}
android (and other platforms) get a similar actual definition. It's a bit less DRY, as I have to repeat the "common" methods in the actual implementation on every platform ... but it works.
r
It's less DRY but it won't compile if you forget something so you're at least protected from messing something up
But sounds like it could be worth a youtrack
b
Thanks @russhwolf .. Yeah I wanted to check here to make sure it wasn't me doing something wrong/unsupported. But yeah, if people feel like it should work, I'll definitely file an issue.