From 8aeb0f7123a2b37d6f8775fc476efab58d3efb9a Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Wed, 26 Jun 2024 15:45:14 -0700 Subject: [PATCH 1/2] bump the bindings --- Sources/LibXMTP/libxmtp-version.txt | 4 +- Sources/LibXMTP/xmtpv3.swift | 146 +++++++++++++++++++++++----- 2 files changed, 122 insertions(+), 28 deletions(-) diff --git a/Sources/LibXMTP/libxmtp-version.txt b/Sources/LibXMTP/libxmtp-version.txt index ed9660a..8976d92 100644 --- a/Sources/LibXMTP/libxmtp-version.txt +++ b/Sources/LibXMTP/libxmtp-version.txt @@ -1,3 +1,3 @@ -Version: bbf05eac +Version: feb48641 Branch: main -Date: 2024-06-25 01:50:26 +0000 +Date: 2024-06-26 22:31:21 +0000 diff --git a/Sources/LibXMTP/xmtpv3.swift b/Sources/LibXMTP/xmtpv3.swift index cdf0357..7f5a410 100644 --- a/Sources/LibXMTP/xmtpv3.swift +++ b/Sources/LibXMTP/xmtpv3.swift @@ -1631,7 +1631,7 @@ public protocol FfiV2ApiClientProtocol: AnyObject { func setAppVersion(version: String) - func subscribe(request: FfiV2SubscribeRequest) async throws -> FfiV2Subscription + func subscribe(request: FfiV2SubscribeRequest, callback: FfiV2SubscriptionCallback) async throws -> FfiV2Subscription } open class FfiV2ApiClient: @@ -1731,13 +1731,13 @@ open class FfiV2ApiClient: } } - open func subscribe(request: FfiV2SubscribeRequest) async throws -> FfiV2Subscription { + open func subscribe(request: FfiV2SubscribeRequest, callback: FfiV2SubscriptionCallback) async throws -> FfiV2Subscription { return try await uniffiRustCallAsync( rustFutureFunc: { uniffi_xmtpv3_fn_method_ffiv2apiclient_subscribe( self.uniffiClonePointer(), - FfiConverterTypeFfiV2SubscribeRequest.lower(request) + FfiConverterTypeFfiV2SubscribeRequest.lower(request), FfiConverterCallbackInterfaceFfiV2SubscriptionCallback.lower(callback) ) }, pollFunc: ffi_xmtpv3_rust_future_poll_pointer, @@ -1787,14 +1787,31 @@ public func FfiConverterTypeFfiV2ApiClient_lower(_ value: FfiV2ApiClient) -> Uns return FfiConverterTypeFfiV2ApiClient.lower(value) } +/** + * Subscription to a stream of V2 Messages + */ public protocol FfiV2SubscriptionProtocol: AnyObject { - func end() async + /** + * End the subscription, waiting for the subscription to close entirely. + * # Errors + * * Errors if subscription event task encounters join error + */ + func end() async throws - func next() async throws -> FfiEnvelope + /** + * Check if the subscription is closed + */ + func isClosed() -> Bool + /** + * Update subscription with new topics + */ func update(req: FfiV2SubscribeRequest) async throws } +/** + * Subscription to a stream of V2 Messages + */ open class FfiV2Subscription: FfiV2SubscriptionProtocol { @@ -1835,9 +1852,14 @@ open class FfiV2Subscription: try! rustCall { uniffi_xmtpv3_fn_free_ffiv2subscription(pointer, $0) } } - open func end() async { + /** + * End the subscription, waiting for the subscription to close entirely. + * # Errors + * * Errors if subscription event task encounters join error + */ + open func end() async throws { return - try! await uniffiRustCallAsync( + try await uniffiRustCallAsync( rustFutureFunc: { uniffi_xmtpv3_fn_method_ffiv2subscription_end( self.uniffiClonePointer() @@ -1847,26 +1869,22 @@ open class FfiV2Subscription: completeFunc: ffi_xmtpv3_rust_future_complete_void, freeFunc: ffi_xmtpv3_rust_future_free_void, liftFunc: { $0 }, - errorHandler: nil + errorHandler: FfiConverterTypeGenericError.lift ) } - open func next() async throws -> FfiEnvelope { - return - try await uniffiRustCallAsync( - rustFutureFunc: { - uniffi_xmtpv3_fn_method_ffiv2subscription_next( - self.uniffiClonePointer() - ) - }, - pollFunc: ffi_xmtpv3_rust_future_poll_rust_buffer, - completeFunc: ffi_xmtpv3_rust_future_complete_rust_buffer, - freeFunc: ffi_xmtpv3_rust_future_free_rust_buffer, - liftFunc: FfiConverterTypeFfiEnvelope.lift, - errorHandler: FfiConverterTypeGenericError.lift - ) + /** + * Check if the subscription is closed + */ + open func isClosed() -> Bool { + return try! FfiConverterBool.lift(try! rustCall { + uniffi_xmtpv3_fn_method_ffiv2subscription_is_closed(self.uniffiClonePointer(), $0) + }) } + /** + * Update subscription with new topics + */ open func update(req: FfiV2SubscribeRequest) async throws { return try await uniffiRustCallAsync( @@ -3673,6 +3691,78 @@ extension FfiConverterCallbackInterfaceFfiMessageCallback: FfiConverter { } } +public protocol FfiV2SubscriptionCallback: AnyObject { + func onMessage(message: FfiEnvelope) +} + +// Put the implementation in a struct so we don't pollute the top-level namespace +private enum UniffiCallbackInterfaceFfiV2SubscriptionCallback { + // Create the VTable using a series of closures. + // Swift automatically converts these into C callback functions. + static var vtable: UniffiVTableCallbackInterfaceFfiV2SubscriptionCallback = .init( + onMessage: { ( + uniffiHandle: UInt64, + message: RustBuffer, + _: UnsafeMutableRawPointer, + uniffiCallStatus: UnsafeMutablePointer + ) in + let makeCall = { + () throws in + guard let uniffiObj = try? FfiConverterCallbackInterfaceFfiV2SubscriptionCallback.handleMap.get(handle: uniffiHandle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return try uniffiObj.onMessage( + message: FfiConverterTypeFfiEnvelope.lift(message) + ) + } + + let writeReturn = { () } + uniffiTraitInterfaceCall( + callStatus: uniffiCallStatus, + makeCall: makeCall, + writeReturn: writeReturn + ) + }, + uniffiFree: { (uniffiHandle: UInt64) in + let result = try? FfiConverterCallbackInterfaceFfiV2SubscriptionCallback.handleMap.remove(handle: uniffiHandle) + if result == nil { + print("Uniffi callback interface FfiV2SubscriptionCallback: handle missing in uniffiFree") + } + } + ) +} + +private func uniffiCallbackInitFfiV2SubscriptionCallback() { + uniffi_xmtpv3_fn_init_callback_vtable_ffiv2subscriptioncallback(&UniffiCallbackInterfaceFfiV2SubscriptionCallback.vtable) +} + +// FfiConverter protocol for callback interfaces +private enum FfiConverterCallbackInterfaceFfiV2SubscriptionCallback { + fileprivate static var handleMap = UniffiHandleMap() +} + +extension FfiConverterCallbackInterfaceFfiV2SubscriptionCallback: FfiConverter { + typealias SwiftType = FfiV2SubscriptionCallback + typealias FfiType = UInt64 + + public static func lift(_ handle: UInt64) throws -> SwiftType { + try handleMap.get(handle: handle) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + let handle: UInt64 = try readInt(&buf) + return try lift(handle) + } + + public static func lower(_ v: SwiftType) -> UInt64 { + return handleMap.insert(obj: v) + } + + public static func write(_ v: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(v)) + } +} + private struct FfiConverterOptionInt64: FfiConverterRustBuffer { typealias SwiftType = Int64? @@ -4473,16 +4563,16 @@ private var initializationResult: InitializationResult { if uniffi_xmtpv3_checksum_method_ffiv2apiclient_set_app_version() != 28472 { return InitializationResult.apiChecksumMismatch } - if uniffi_xmtpv3_checksum_method_ffiv2apiclient_subscribe() != 31004 { + if uniffi_xmtpv3_checksum_method_ffiv2apiclient_subscribe() != 48530 { return InitializationResult.apiChecksumMismatch } - if uniffi_xmtpv3_checksum_method_ffiv2subscription_end() != 54394 { + if uniffi_xmtpv3_checksum_method_ffiv2subscription_end() != 38721 { return InitializationResult.apiChecksumMismatch } - if uniffi_xmtpv3_checksum_method_ffiv2subscription_next() != 27536 { + if uniffi_xmtpv3_checksum_method_ffiv2subscription_is_closed() != 4358 { return InitializationResult.apiChecksumMismatch } - if uniffi_xmtpv3_checksum_method_ffiv2subscription_update() != 16562 { + if uniffi_xmtpv3_checksum_method_ffiv2subscription_update() != 24211 { return InitializationResult.apiChecksumMismatch } if uniffi_xmtpv3_checksum_method_ffixmtpclient_can_message() != 53502 { @@ -4536,11 +4626,15 @@ private var initializationResult: InitializationResult { if uniffi_xmtpv3_checksum_method_ffimessagecallback_on_message() != 5286 { return InitializationResult.apiChecksumMismatch } + if uniffi_xmtpv3_checksum_method_ffiv2subscriptioncallback_on_message() != 30049 { + return InitializationResult.apiChecksumMismatch + } uniffiCallbackInitFfiConversationCallback() uniffiCallbackInitFfiInboxOwner() uniffiCallbackInitFfiLogger() uniffiCallbackInitFfiMessageCallback() + uniffiCallbackInitFfiV2SubscriptionCallback() return InitializationResult.ok } From 49e31a863acd5e5295375eb1ad46ccc019b78e44 Mon Sep 17 00:00:00 2001 From: Naomi Plasterer Date: Thu, 27 Jun 2024 09:55:57 -0700 Subject: [PATCH 2/2] update the package --- LibXMTP.podspec | 4 ++-- Package.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LibXMTP.podspec b/LibXMTP.podspec index 24e10ae..dbbc2e4 100644 --- a/LibXMTP.podspec +++ b/LibXMTP.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'LibXMTP' - s.version = '0.5.3-beta2' + s.version = '0.5.4-beta0' s.summary = 'XMTP shared Rust code that powers cross-platform SDKs' s.homepage = 'https://github.com/xmtp/libxmtp-swift' @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.platform = :ios, '14.0', :macos, '11.0' s.swift_version = '5.3' - s.source = { :http => "https://github.com/xmtp/libxmtp/releases/download/swift-bindings-bbf05ea/LibXMTPSwiftFFI.zip", :type => :zip } + s.source = { :http => "https://github.com/xmtp/libxmtp/releases/download/swift-bindings-feb4864/LibXMTPSwiftFFI.zip", :type => :zip } s.vendored_frameworks = 'LibXMTPSwiftFFI.xcframework' s.source_files = 'Sources/LibXMTP/**/*' end diff --git a/Package.swift b/Package.swift index f0f58bd..6781fe2 100644 --- a/Package.swift +++ b/Package.swift @@ -27,8 +27,8 @@ let package = Package( ), .binaryTarget( name: "LibXMTPSwiftFFI", - url: "https://github.com/xmtp/libxmtp/releases/download/swift-bindings-bbf05ea/LibXMTPSwiftFFI.zip", - checksum: "b1e5c34294f1c47e183d67a634ac98ba8a174defcbc1087dd7865e7fe516fccb" + url: "https://github.com/xmtp/libxmtp/releases/download/swift-bindings-feb4864/LibXMTPSwiftFFI.zip", + checksum: "44754c7406251bcf64e8c578f4081a3fe6753dd7592c94f0c719424f26c9019" ), .testTarget(name: "LibXMTPTests", dependencies: ["LibXMTP"]), ]