Hello guys, on a shared library i have a function ...
# multiplatform
b
Hello guys, on a shared library i have a function that returns a kotlin
Result<String>
how can i parse it in Swift IOS ? I it is giving me
Any?
value
j
There are limitations to Objective-C generics, which affects interop from Kotlin. You should be able to cast the
Any?
value to
String
. You could create a Swift extension that does this cast to make the API nicer within Swift.
K 1
b
here is my function in kotlin
suspend fun process() : Result<MyCustom>{}
what will be the best way to parse it in Swift
k
I’m not sure this has to do with generics. Value classes can’t be sent over the objc-interop bridge and get cast to whatever their parent type is. Result is a value class so it might have something to do with that.
I’ve seen this behavior of upcasting to
Any?
when using value classes in swift.
j
Ah, that's true. If it weren't a value class, it would just be one level of generics. It's usually the generic generic types that lose the nested type.
k
Yup. To be honest I’ve never seen a value class cast to its contained type. Eg.
Copy code
value class Foo(val string: Stirng)
says it should be exposed as String in Swift, but I’ve never seen that. It always gets case to
Any?
for me.
j
Here's the YouTrack issue.
k
In my opinion I wish they would just box across the objc-bridge 🤷
j
I think that makes sense as well. Value classes can already be boxed in certain use cases on the JVM. Boxing them in Kotlin/Native would provide access to the value class's API and type safety, only sacrificing the inline optimization.
@brabo-hi you can workaround this by defining your own
Result
type that is a regular class, instead of value class.
b
@Jeff Lockhart if you could provide a sample that would be helpful. I mean i want to return
Result
like type with a
success
class or
failure
class depending on the operation
k
Copy code
sealed interface MyResult<out T> {
  class Success(val data: T) : MyResult<T>
  class Failure(val e: Throwable) : MyResult<Nothing>
}
j
If you want it to be just like the std lib implementation, you can use the source as a regular non-value class.
b
@Jeff Lockhart thanks for your help
👍 1
l
This is what I use:
Copy code
/**
 * Adapted from [Result](<https://github.com/google/iosched/blob/main/shared/src/main/java/com/google/samples/apps/iosched/shared/result/Result.kt>)
 * this class is used because [Kotlin.Result] can't be accessed from iOS.
 * This class won't be needed once the [Result.kt issue](<https://youtrack.jetbrains.com/issue/KT-32352/inline-classes-are-exported-as-id-to-objc-swift#focus=Comments-27-6766899.0-0>)  is addressed
 */
sealed class Result<out R> {
    data class Success<T>(val data: T) : Result<T>()
    data class Failure(val exception: Exception) : Result<Nothing>()

}

/**
 * `true` if [Result] is of type [Success] & holds non-null [Success.data].
 */
val Result<*>.isSuccess
    get() = this is Result.Success && data != null

val <T> Result<T>.data: T? get() = (this as? Result.Success)?.data

val <T> Result<T>.failureData: Exception? get() = (this as? Result.Failure)?.exception
b
@Loe thanks
👍 1