I’m sure I knew this but now forget. How does one ...
# kotlin-native
k
I’m sure I knew this but now forget. How does one get around the 32bit/64bit interop situation where NSInteger is an Int in 32 and a Long in 64?
Type mismatch: inferred type is Long but NSInteger /* = Int */ was expected
l
Depends. For a
NSUserDefaults
wrapper, I wrote
iosArm32
specific code, and
apple64
specific code to use
NSNumber
for
Long
on 32 bits iOS, and use
toInt()
for
Int
on 64 bits apple devices. In some cases, using
toInt()
or
toLong()
and suppressing the warning for the case it's redundant when compiled for one or another architecture may be enough if you can't have unwanted overflows because of conversion.
a
convert()?
d
You can also use
convert()
l
You can also propagate usage of
NSInteger
if you want the number encoding to be dependent on the architecture and still can't have unwanted overflows by doing so. That approach only works when compiled for iOS or macOS though. If you need it for other native targets, you might want to define your own typealias, using
NSInteger
on Apple platforms.
k
It’s one of those situations where overflow would never ever happen (limit on Firestore query). Thanks for suggestions. Will check out.
l
Then using
toInt()
with warning suppress is okay and allow users to always use
Int
without dealing themselves with conversion.
k
👍 Thanks
s
Out of curiosity, what 32-bit devices are you looking to support? I guess if you're still supporting iOS 10 (<3% market share as of July) then 32-bit support makes sense.
k
I’m not really. Before I got replies here I just commented out the 32bit built. However, when publishing libraries, people still ask, so if possible I publish the artifact.
t
I ran into a crash issue on 32-bit devices in the Kotlin native code when using toInt(). Changing to convert() fixed these crashes for me.
To be precise, I was doing:
Copy code
.toLong() as NSInteger
so perhaps it was the casting that was the issue. But in any case the .convert() is much cleaner.
l
I'd definitely expect the casting to be the issue, but in your case, you were exposing an
NSInteger
, which is different from transforming
NSInteger
to stable width
Int
or
Long
. And since Kotlin allows me, I'd make libraries compatible with iOS 2+ unless there's an API or a bug that prevents me from doing so. That way, developers wanting to use your library to make an app for an old iPad (i.e. mostly nerdy children with no means to buy the latest), iPod touch, iPhone 5 or earlier, it's possible. My cousin uses an iPhone 4S on iOS 9.3.5, and his family still own a working iPhone 3GS on iOS 6. No need to accelerate planned obsolescence through software if it only saves you one or two integer conversions.
k
now I am banging my head against this issue
I am curious about this magic convert function that has been mentioned
t
I found a reference to it from the an issue somewhere: https://kotlinlang.org/docs/reference/native/c_interop.html#portability
k
yeah I am reading that but now I need to figure out how to actually use it
t
This is what I needed to cast from Kotlin Int to iOS NSInteger, otherwise crash would occur on 32-bit devices.
k
'Unresolved reference: convert'
t
The type system handle much of it for you. Here is how I used it:
Copy code
actual constructor(year: Int, month: Int, day: Int) {
        val components = NSDateComponents()
        components.year = year.convert()
        components.month = month.convert()
        components.day = day.convert()
        this.date = NSCalendar.currentCalendar.dateFromComponents(components) ?: NSDate()
    }
Copy code
import kotlinx.cinterop.convert
it is an extension function, and so has to be imported explicitly
k
ah, thanks. IDEA seems to think everything in this file is invalid so it's not giving me any hints
t
yeah, i dislike seeing any red in the code.
k
i've come to accept that as a fact of life when working with MPP
t
yup. This one has been in my code forever:
k
opening build.gradle gives me a fit every time
t
Yeah, I use the same shared project in multiple Android projects, and most of the time when I switch between them I have to ‘Sync Project with Gradle Files’
l
With some config, you can never encounter red code in MPP already. I'll share more about it later this week, I think it can be helpful.
k
sounds too good to be true 😉
l
@Kris Wong This code in
buildSrc
is part of the setup: https://github.com/LouisCAD/Splitties/blob/14ef6cf169354a5abf6c2929f2b02e6dcffdd510/buildSrc/src/main/kotlin/config/KotlinSourceSetsConfig.kt#L37 There's also two Kotlin scripts to help creating new modules and adding targets with the needed symlink setup.