Hey folks question about <https://kotlinlang.org/d...
# kotlin-native
i
Hey folks question about https://kotlinlang.org/docs/reference/native/objc_interop.html#generics I know there are limitations but is list parameterized with nullable type is one of such limitation, I mean
List<SomeType?>
is translated to objectiveC / Swift as
[Any]
. @kpgalligan as far as I remember you were working on adding generics support, could you please advise?
b
I don't think you can represent array of optional without a special container in objc like NSPointerArray
If you remove the ?, it should work
s
ObjC is very forgiving about nulls until you try to put them into an array or dictionary. That is a fatal error.
i
Hm, so should then
List<SomeType?>
be translated as
[SomeType]
on ObjC side?
b
No there's no natural translation. You'll need to make a custom Optional wrapper class for your List element type, or something like that.
i
that's really sad, if to fix Swift dev experience we have to wrap list optional item type into some container at the same time we introduce pain for Kotlin devs by unwrapping value from this container.
s
Out of curiosity, why would you put a null in a list anyway? I think I would always be filtering out the null entries whenever I did anything with a list that could contain a null.
i
well, that reasonable question and I would agree with that, but in a context of GraphQL (we are working on migrating Apollo client to KN https://github.com/apollographql/apollo-android) The models are been generated out of the user GraphQL schema that in some cases can define array with nullable items. Yes in 90% that doesn;t make any sense having list with nullable items, but I can think of a case when the index of item means something, so there can be a business logic around
listOfThings.get(index) == null
. Interesting that Github API GraphQL schema defines list of commits in history as
Array<Commit?>
.
s
Very interesting. I don't know how Kotlin implements billable types but I can tell you how Swift does it. They're technically Optionals of type T with a some and none value. A wrapper type for your case wouldn't be too far out of the ordinary for Swift. It would just lack the syntax sugar that Swift has for its own optional type.
k
Apollo KMP status has been on our radar for a while, so maybe a good time to look into it. I’ve been pretty busy this week so just seeing this. I don’t know much about either Apollo or GraphQL, but we have a lot of people who ask. However, if you can point to the common definition that needs to be implemented I may have some thoughts. I will need to refresh myself on the details of how the collections translate, though.
We’ve been applying applying some swift extensions on top of the Kotlin Objc code to help in some cases. Most recently to create a coroutines to SwiftRX bridge. Reasonable success. There are some ugly translations in places, though.
s
A coroutines rxswift bridge is an exciting prospect. Once suspend functions are exposed to ObjC it ought to be trivial.
k
Well, not for flow
Trivial, I mean
The tricky bit is retaining generics
i
We ended up with this approach (not ideal, but better than nothing)
Copy code
data class FriendsConnection(
    /**
     * The total number of friends
     */
    val totalCount: Int?,
    /**
     * The edges for each of the character's friends.
     */
    val edges: List<Edge?>
  ) {
    
    fun edgesFilterNotNull(): List<Edge> = edges.filterNotNull()

}
in this sample for
List<Edge?>
we generate synthetic accessor
fun edgesFilterNotNull(): List<T>
that filters out nulls and returns non optional list. So if user doesn't care about nulls in the arrays (in most cases this is true), we just provide access to non optional list that makes swift happy to translate it to
[Edge]
.
s
I’m curious what happens if you feed ObjC an
NSArray
with a null in it. In ObjC, attempting to insert a null into an NSArray crashes a program. I’m guessing it inserts a
KotlinNothing
in there but not sure.