Structs, enums, Date and Data across the Swift and Kotlin boundary
Method arguments, results, view props and callback arguments cross as JSON
by default, and four richer shapes cross with it: a Codable struct or
data class crosses as its object shape, a String or Int backed enum
crosses as its raw value, a Date crosses as an ISO string revived to a
Date, and Data or ByteArray crosses as base64 revived to a
Uint8Array.
struct Point: Codable { var x: Double var y: Double var label: String? = nil}
enum Direction: String { case north case south}
@MainActor final class Atlas: PeachModule { init() {}
func pin(_ point: Point) -> Point { point } func heading(_ direction: Direction) -> Direction { direction } func at(_ when: Date) -> Date { when }}data class Point(val x: Double, val y: Double, val label: String? = null)
enum class Direction { NORTH, SOUTH}
object Atlas : OneModule { fun pin(point: Point): Point = point fun at(when: Date): Date = when fun blob(data: ByteArray): ByteArray = data}import { Atlas, type Point } from './native/Atlas.swift'
const point: Point = { x: 1, y: 2 }await Atlas.pin(point)await Atlas.at(new Date())A struct field with a value is optional in TypeScript; Codable and the
generated Kotlin glue fill the default when the key is missing. A Kotlin
default must be visible to the generated glue. Structs nest, including
inside arrays and maps. An enum needs its cases listed without explicit raw
values or associated values. Every struct and enum lives in the file that
uses it, must be visible to the generated glue, and a Swift struct must
conform to Codable in its declaration. Anything else keeps failing with
the file and line that declares it.
Pass a real Date and a real Uint8Array: anything else throws before the
call leaves JavaScript. Native results revive the same way, so what arrives
is a Date and a Uint8Array, never the string on the wire.
Edit this page on GitHub.