Git Product home page Git Product logo

swift-java-coder's People

Contributors

andriydruk avatar zayass avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

swift-java-coder's Issues

[dev/kotlin-support] Weird issue decoding structs that have enum properties

Given a swift struct that contains an enum-typed property (see below), its kotlin @SwiftValue-annotated counterparts, a single instance bridges perfectly back and forth over the bridge, via the JavaDecoder/JavaEncoder, with no loss in data. But when you have an ArrayList of instances of the kotlin data class that represents the swift struct, the value for the enum-typed property is lost and is nil on the swift side. I've chased this issue all the way down through JavaDecoder to where it tries to get the Field ID for the java object for the enum type. It fails to find the Field ID and prints an error (it's just logged because the missing field strategy that gets generated by swift-java-codegen is always .ignored) that says Ignored error: fieldNotFoundException for ....

Here's an example. Consider a scenario where you have a Swift and their Kotlin counterparts like below:

enum Category: String, Codable {
    case sedan, suv
}

struct Car: Codable {
    let description: String
    let category: Category
}

struct CarCollection: Codable {
    let cars: [Car]
}

Consider also their kotlin counterparts:

@SwiftValue
enum class Category(val rawValue: String) {
    sedan("sedan"),
    suv("suv")
}

@SwiftValue
data class Car(var description: String = "", var category: Category = null)

@SwiftValue
data class CarCollection(var cars: ArrayList<Car> = arrayListOf())

If I were to try to passing a CarCollection over the bridge from the kotlin side to the swift side, JavaDecoder would eventually try to decode a Car from the array list of Cars, and furthermore, eventually try to decode the category field on Car. This is where the problem shows up. The JNI bridging code tries to look up the FieldID for the category field on Car. However, when a type like Car that has a property that is an enum (maybe even just a string backed enum, not sure though), is in an array, the decoding process essentially fails to decode the whole object over the bridge because these properties that are enums end up failing to decode. If you were simply trying to decode a singular Car, that wasn't in an array list, everything would work properly.

I haven't been able to pin it down yet, but could there be a state issue with JavaDecoder when it creates JavaArrayContainer and then a JavaObjectContainer or is there something going on deeper in the JNI support code. Or could it be an issue with the bytecode generated by kotlin?

Thanks in advance for looking into this.

cc: @zayass @andriydruk

[dev/kotlin-support] Build error for 32-bit builds

I realize that support for 32-bit is probably not much of a concern as we move towards almost all 64-bit devices, but I am curious about how to fix the error below (I've abbreviated the file paths with /.../).

I am using the dev/kotlin-support. I found that by only building for arm64-v8a & x86_64, I don't get this error. You can get the same error in @andriydruk's [swift-weather-app] by adding armeabi-v7a to the abiFilter list in the swift-android gradle configuration block.

/.../swift-android/swift-java-coder/Sources/JavaCoderConfig.swift:97:41: error: cannot convert value of type 'jint' (aka 'Int') to expected argument type 'Int32'
            UInt(UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod)))
                                    ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    Int32(                                                  )
/.../swift-android/swift-java-coder/Sources/JavaCoderConfig.swift:118:36: error: cannot convert value of type 'jint' (aka 'Int') to expected argument type 'Int32'
            UInt32(bitPattern: JNI.CallIntMethod(value, methodID: NumberIntValueMethod))
                               ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                               Int32(                                                  )
/.../swift-android/swift-java-coder/Sources/JavaPrimitive.swift:83:38: error: cannot convert value of type 'jint' (aka 'Int') to expected argument type 'Int32'
        self.init(UInt32(bitPattern: javaPrimitive))
                                     ^~~~~~~~~~~~~
                                     Int32(       )
/.../swift-android/swift-java-coder/Sources/JavaPrimitive.swift:93:16: error: initializer 'init(bitPattern:)' requires that 'UInt32' conform to '_Pointer'
        return jint(bitPattern: uint32)
               ^
Swift.Int:2:23: note: where 'P' = 'UInt32'
    @inlinable public init<P>(bitPattern pointer: P?) where P : _Pointer
                      ^
/.../swift-android/swift-java-coder/Sources/JavaPrimitive.swift:122:31: error: cannot convert value of type 'jint' (aka 'Int') to expected argument type 'Int32'
        self.init(bitPattern: javaPrimitive)
                              ^~~~~~~~~~~~~
                              Int32(       )
/.../swift-android/swift-java-coder/Sources/JavaPrimitive.swift:126:16: error: initializer 'init(bitPattern:)' requires that 'UInt32' conform to '_Pointer'
        return jint(bitPattern: self)
               ^
Swift.Int:2:23: note: where 'P' = 'UInt32'
    @inlinable public init<P>(bitPattern pointer: P?) where P : _Pointer
                      ^
/.../swift-android/swift-java-coder/Sources/JavaDecoder.swift:154:24: error: cannot convert return expression of type 'jint' (aka 'Int') to return type 'Int32'
        return JNI.api.GetIntField(JNI.env, javaObject, fieldID)
               ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               Int32(                                           )

String backed enum

Hi @andriydruk

Before, it was possible to bridge String-backed enums. From what I can see in the diff of JavaDecoder.swift in the dev/kotlin-support branch, only number-backed enums are bridgeable. How do we bridge string-backed enums like the one below in kotlin? sealed classes?

enum Direction: String, Codable {
    case north, south, east, west
}

cc: @elkasvirElka

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.