From ec9b66d0bf7eeb5c7462266694decc559827728d Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 9 Nov 2025 21:07:48 -0500 Subject: [PATCH 1/3] Add more bridging tests --- Package.swift | 4 +- .../Samples.swift | 45 +++++++++++++++++++ .../BridgeToKotlinCompatSamplesTests.swift | 16 +++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 7335123..96b1b04 100644 --- a/Package.swift +++ b/Package.swift @@ -1,9 +1,9 @@ -// swift-tools-version: 5.9 +// swift-tools-version: 5.10 import PackageDescription let package = Package( name: "skip-bridge", - platforms: [.iOS(.v16), .macOS(.v13)], + platforms: [.iOS(.v16), .macOS(.v14)], products: [ .library(name: "SkipBridge", type: .dynamic, targets: ["SkipBridge"]), .library(name: "SkipBridgeToKotlinSamples", type: .dynamic, targets: ["SkipBridgeToKotlinSamples"]), diff --git a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift index 204454b..9cde1d6 100644 --- a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift +++ b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift @@ -33,3 +33,48 @@ public class Compat { public struct CompatError: Error { } + +public struct CompatCallbacks: @unchecked Sendable { + // TODO: https://github.com/skiptools/skip/issues/534 + //public typealias AsyncCallback = () async -> () + public typealias AsyncCallback = () -> () + public typealias Callback = () -> () + public typealias URLCallback = (URL) -> () + + // `- error: invalid conversion from 'async' function of type '() async -> ()' to synchronous function type '() throws -> ()' + public let didLogin: AsyncCallback + public let didCancel: AsyncCallback + public let didSelectEmail: Callback + public let didSelectSettings: Callback + public let onURLSelected: URLCallback + + public init( + didLogin: @escaping AsyncCallback = {}, + didCancel: @escaping AsyncCallback = {}, + didSelectEmail: @escaping Callback = {}, + didSelectSettings: @escaping Callback = {}, + onURLSelected: @escaping URLCallback = { _ in } + ) { + self.didLogin = didLogin + self.didCancel = didCancel + self.didSelectEmail = didSelectEmail + self.didSelectSettings = didSelectSettings + self.onURLSelected = onURLSelected + } +} + +@Observable +@MainActor +open class CompatMainActor: Identifiable { + public nonisolated let id: String + public let scene: Int + + public init(scene: Int, id: String? = nil) { + self.id = id ?? "" + self.scene = scene + setup() + } + + public func setup() { + } +} diff --git a/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift b/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift index 731a894..6846b09 100644 --- a/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift +++ b/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift @@ -92,4 +92,20 @@ final class BridgeToKotlinCompatTests: XCTestCase { XCTAssertEqual(collected2, listOf(100, 200)) #endif } + + func testCompatCallbacks() async { + #if SKIP + // TODO: make functions async to reproduce https://github.com/skiptools/skip/issues/534 + let callbacks = CompatCallbacks(didLogin: { }, didCancel: { }, didSelectEmail: { }, didSelectSettings: { }, onURLSelected: { url in }) + callbacks.didSelectEmail() + await callbacks.didLogin() + #endif + } + + func testCompatMainActor() async { + #if SKIP + let compatMain = await CompatMainActor(scene: 123) + await compatMain.setup() + #endif + } } From 972ac1ba61a988e347d8492441a63ccf63029c13 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 9 Nov 2025 21:26:58 -0500 Subject: [PATCH 2/3] Update test cases --- .../Samples.swift | 21 +++++++++++++++++++ .../BridgeToKotlinCompatSamplesTests.swift | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift index 9cde1d6..d7adcc0 100644 --- a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift +++ b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift @@ -1,6 +1,7 @@ // Copyright 2024–2025 Skip // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception import Foundation +import Observation public class Compat { public let id: UUID @@ -78,3 +79,23 @@ open class CompatMainActor: Identifiable { public func setup() { } } + +public struct CompatMutableStruct { + public var str: String + public init(_ str: String) { + self.str = str + } + + public mutating func mutableFunc(_ str: String) { + self.str = str + } +} + +//public enum CompatMutableEnum { +// case a +// case b(String) +// +// public mutating func mutableFunc(_ update: String) { +// self = .b(update) +// } +//} diff --git a/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift b/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift index 6846b09..fda5902 100644 --- a/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift +++ b/Tests/SkipBridgeToKotlinCompatSamplesTests/BridgeToKotlinCompatSamplesTests.swift @@ -108,4 +108,11 @@ final class BridgeToKotlinCompatTests: XCTestCase { await compatMain.setup() #endif } + + func testCompatMutableStruct() async { + #if SKIP + var compatStruct = CompatMutableStruct("ABC") + compatStruct.mutableFunc("XYZ") + #endif + } } From da287547636d24847b56317902d866c9d89409f0 Mon Sep 17 00:00:00 2001 From: Marc Prud'hommeaux Date: Sun, 9 Nov 2025 21:59:19 -0500 Subject: [PATCH 3/3] Remove Observation from test due to missing _ZN5swift9threading5fatalEPKcz symbol --- Sources/SkipBridgeToKotlinCompatSamples/Samples.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift index d7adcc0..395707a 100644 --- a/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift +++ b/Sources/SkipBridgeToKotlinCompatSamples/Samples.swift @@ -1,7 +1,6 @@ // Copyright 2024–2025 Skip // SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception import Foundation -import Observation public class Compat { public let id: UUID @@ -64,7 +63,6 @@ public struct CompatCallbacks: @unchecked Sendable { } } -@Observable @MainActor open class CompatMainActor: Identifiable { public nonisolated let id: String