Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .github/workflows/release_swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,17 @@ jobs:
bash scripts/release/zip_xcframework.sh
- name: Bake SHA into Package.swift
run: bash scripts/release/swift_bake_sha.sh
- name: Read release tag from Package.swift
id: release_tag
run: |
V=$(grep -oE 'let releaseTag = "v[^"]+"' Package.swift | sed -E 's/.*"(v[^"]+)"/\1/')
echo "tag=$V" >> "$GITHUB_OUTPUT"
- name: Upload zip to draft GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bash scripts/release/swift_upload_draft.sh
uses: softprops/action-gh-release@v2
with:
draft: true
tag_name: ${{ steps.release_tag.outputs.tag }}
name: ${{ steps.release_tag.outputs.tag }}
body: "Draft release — promoted to published by release.yml on tag push."
files: IrohLib.xcframework.zip
fail_on_unmatched_files: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,5 @@ kotlin/android/src/main/jniLibs/

# Generated docs site (built by `cargo make docs-site`, deployed by docs.yml)
/site

/.xcode-verify-ddata
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "iroh-ffi"
version = "1.0.0"
version = "1.1.0"
edition = "2024"
publish = false
readme = "README.md"
Expand Down
57 changes: 47 additions & 10 deletions IrohLib/Sources/IrohLib/IrohLib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,11 @@ fileprivate struct FfiConverterString: FfiConverter {
return String()
}
let bytes = UnsafeBufferPointer<UInt8>(start: value.data!, count: Int(value.len))
return String(bytes: bytes, encoding: String.Encoding.utf8)!
// Use Swift's native UTF-8 decoder; `String(bytes:encoding:.utf8)` goes
// through Foundation's NSString and silently strips a leading U+FEFF BOM.
// Invalid UTF-8 substitutes U+FFFD instead of trapping (unreachable
// given Rust's `String` invariant).
return String(decoding: bytes, as: UTF8.self)
}

public static func lower(_ value: String) -> RustBuffer {
Expand All @@ -557,7 +561,8 @@ fileprivate struct FfiConverterString: FfiConverter {

public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String {
let len: Int32 = try readInt(&buf)
return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)!
// See `lift` above for why we avoid Foundation's NSString-backed decoder here.
return String(decoding: try readBytes(&buf, count: Int(len)), as: UTF8.self)
}

public static func write(_ value: String, into buf: inout [UInt8]) {
Expand Down Expand Up @@ -906,7 +911,11 @@ fileprivate struct UniffiCallbackInterfaceAddrChangeCallback {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceAddrChangeCallback> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceAddrChangeCallback> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfaceAddrChangeCallback>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -3500,7 +3509,11 @@ fileprivate struct UniffiCallbackInterfaceHomeRelayCallback {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceHomeRelayCallback> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceHomeRelayCallback> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfaceHomeRelayCallback>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -4253,7 +4266,11 @@ fileprivate struct UniffiCallbackInterfaceNetworkChangeCallback {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceNetworkChangeCallback> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceNetworkChangeCallback> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfaceNetworkChangeCallback>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -4480,7 +4497,11 @@ fileprivate struct UniffiCallbackInterfacePathChangeCallback {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePathChangeCallback> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePathChangeCallback> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfacePathChangeCallback>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -4707,7 +4728,11 @@ fileprivate struct UniffiCallbackInterfacePathEventCallback {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePathEventCallback> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePathEventCallback> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfacePathEventCallback>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -4922,7 +4947,11 @@ fileprivate struct UniffiCallbackInterfacePreset {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePreset> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfacePreset> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfacePreset>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -5116,7 +5145,11 @@ fileprivate struct UniffiCallbackInterfaceProtocolCreator {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceProtocolCreator> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceProtocolCreator> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfaceProtocolCreator>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down Expand Up @@ -5393,7 +5426,11 @@ fileprivate struct UniffiCallbackInterfaceProtocolHandler {

// Rust stores this pointer for future callback invocations, so it must live
// for the process lifetime (not just for the init function call).
static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceProtocolHandler> = {
//
// `nonisolated(unsafe)` is needed under Swift 6 strict concurrency.
// This is safe because the pointee is initialized once during static init
// and never mutated by either side of the FFI. Its fields are C function pointers.
nonisolated(unsafe) static let vtablePtr: UnsafePointer<UniffiVTableCallbackInterfaceProtocolHandler> = {
let ptr = UnsafeMutablePointer<UniffiVTableCallbackInterfaceProtocolHandler>.allocate(capacity: 1)
ptr.initialize(to: vtable)
return UnsafePointer(ptr)
Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import Foundation
// commit on the release branch, marked `[skip swift-release]`), so the value
// here always matches the IrohLib.xcframework.zip attached to the GitHub
// release — never a cross-host determinism game.
let releaseTag = "v1.0.0"
let releaseChecksum = "514b147f7965fe17acaece9a1157cf9421463b6c9282224983e871ea868b86ef"
let releaseTag = "v1.1.0"
let releaseChecksum = "ad46dadf09f9224157512992923562931ed60f252414230d50893a4d515c5776"

let packageDir = URL(fileURLWithPath: #filePath).deletingLastPathComponent()
let localBuiltBinary = packageDir
Expand Down
2 changes: 1 addition & 1 deletion iroh-js/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2024"
name = "number0_iroh"
version = "1.0.0"
version = "1.1.0"
license = "MIT OR Apache-2.0"
authors = ["n0 team"]
repository = "https://github.com/n0-computer/iroh-ffi"
Expand Down
Loading
Loading