Add Swift bindings using UniFFI similar to Kotlin bindings#22
Add Swift bindings using UniFFI similar to Kotlin bindings#22
Conversation
|
Important Review skippedBot user detected. To trigger a single review, invoke the You can disable this status message by setting the 📝 WalkthroughWalkthroughThis pull request adds comprehensive Swift bindings support for the Lightning Node Interface (LNI) library. The changes include a new Rust crate for binding generation, a build script automating UniFFI-based Swift code generation and iOS XCFramework creation, complete documentation, configuration files, and a functional SwiftUI example iOS application demonstrating usage with multiple node types. Changes
Sequence DiagramsequenceDiagram
participant User
participant build.sh
participant Cargo
participant UniFFI
participant lipo
participant xcodebuild
participant iOS as Output:<br/>XCFramework
User->>build.sh: ./build.sh [--release] [--ios]
build.sh->>Cargo: cargo build (host)
Cargo-->>build.sh: libname.so/.dylib
alt --ios flag
build.sh->>Cargo: cargo build --target aarch64-apple-ios
Cargo-->>build.sh: libs/aarch64-apple-ios
build.sh->>Cargo: cargo build --target x86_64-apple-ios-sim
Cargo-->>build.sh: libs/x86_64-apple-ios-sim
build.sh->>lipo: lipo -create (sim libs)
lipo-->>build.sh: libname_sim.a
end
build.sh->>Cargo: cargo build --bin uniffi-bindgen
Cargo-->>build.sh: uniffi-bindgen binary
build.sh->>UniFFI: uniffi-bindgen generate
UniFFI-->>build.sh: Sources/LNI/*.swift
alt --ios flag
rect rgba(144,202,249,0.3)
note right of build.sh: iOS XCFramework Phase
build.sh->>xcodebuild: xcodebuild -create-xcframework
xcodebuild-->>iOS: LNI.xcframework
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Comment |
Co-authored-by: ntheile <1273575+ntheile@users.noreply.github.com>
Co-authored-by: ntheile <1273575+ntheile@users.noreply.github.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In @bindings/swift/Cargo.toml:
- Around line 11-12: Update the uniffi dependency version in the Cargo.toml from
"0.29.0" to the latest stable "0.30.0" (or at minimum to "0.29.5" if you must
stay on 0.29.x); locate the [dependencies] entry containing uniffi = { version =
"0.29.0", features = ["cli"] } and change the version string accordingly, then
run cargo update / cargo build to verify compatibility and resolve any API or
feature changes introduced in 0.30.0.
In @bindings/swift/example/LNIExample/LNIExample.xcodeproj/project.pbxproj:
- Line 212: The project.pbxproj currently sets IPHONEOS_DEPLOYMENT_TARGET = 16.0
but the PR description says "iOS 15+ Simulator"; update the deployment target or
documentation to match: if you intend to support iOS 15+, change the
IPHONEOS_DEPLOYMENT_TARGET entries (search for IPHONEOS_DEPLOYMENT_TARGET in
project.pbxproj, including the occurrences at the shown spots) to 15.0, or
alternatively update the PR description/README to state iOS 16+ so they are
consistent. Ensure both occurrences (and any other IPHONEOS_DEPLOYMENT_TARGET
keys) are updated to the chosen target.
🧹 Nitpick comments (3)
bindings/swift/example/README.md (1)
57-64: Add language identifier to the project structure code block.The fenced code block displaying the project directory tree (lines 57–64) lacks a language identifier, which triggers markdown linting. Add
textortreeafter the opening backticks to resolve this.-``` +```text LNIExample/ ├── LNIExample.xcodeproj/ # Xcode project └── LNIExample/ ├── LNIExampleApp.swift # App entry point ├── ContentView.swift # Main UI └── Assets.xcassets/ # App assets -``` +```bindings/swift/example/LNIExample/LNIExample/ContentView.swift (1)
155-175: Placeholder implementations may confuse users.The test buttons show configuration documentation but don't perform actual connectivity tests. Consider adding a visual indicator (e.g., different button style or label) to distinguish the functional "Get Balance" from informational "test" buttons, or adding TODO comments to track future implementation.
bindings/swift/build.sh (1)
17-17: Unused variableEXAMPLE_DIR.This variable is defined but never used. Either remove it or add the intended usage.
🔎 Proposed fix
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)" -EXAMPLE_DIR="$SCRIPT_DIR/example"
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
Cargo.tomlbindings/swift/.gitignorebindings/swift/Cargo.tomlbindings/swift/README.mdbindings/swift/build.shbindings/swift/example/LNIExample/LNIExample.xcodeproj/project.pbxprojbindings/swift/example/LNIExample/LNIExample/Assets.xcassets/AccentColor.colorset/Contents.jsonbindings/swift/example/LNIExample/LNIExample/Assets.xcassets/AppIcon.appiconset/Contents.jsonbindings/swift/example/LNIExample/LNIExample/Assets.xcassets/Contents.jsonbindings/swift/example/LNIExample/LNIExample/ContentView.swiftbindings/swift/example/LNIExample/LNIExample/LNIExampleApp.swiftbindings/swift/example/LNIExample/lni.swiftbindings/swift/example/README.mdbindings/swift/uniffi-bindgen.rs
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
bindings/swift/example/README.md
57-57: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Shellcheck (0.11.0)
bindings/swift/build.sh
[warning] 17-17: EXAMPLE_DIR appears unused. Verify use (or export if used externally).
(SC2034)
🔇 Additional comments (19)
bindings/swift/example/LNIExample/LNIExample/Assets.xcassets/AppIcon.appiconset/Contents.json (1)
1-13: Standard iOS asset catalog metadata.This JSON correctly defines the App Icon asset for the iOS example project.
bindings/swift/README.md (2)
1-49: Comprehensive and clear build documentation.The prerequisites, build steps, and command examples are well-organized and actionable. The split between basic Swift binding generation and iOS-specific build flags is intuitive.
50-129: Strong usage examples with realistic patterns.The code examples demonstrate key workflows (node creation, async/await patterns, polymorphic node usage) clearly. The NWC example and factory function pattern help users understand how to work with multiple node types. The forward-looking note about future SPM support is good for setting expectations.
bindings/swift/example/README.md (2)
1-56: Excellent step-by-step setup and integration guidance.The Prerequisites, multi-step build process, and explicit Xcode linking instructions are clear and reduce friction for new users. The honest note about placeholder implementations (lines 123–125) sets appropriate expectations.
71-119: Practical example code with good commentary.The Strike node and invoice creation examples are clear, use proper Swift async/await patterns, and show realistic parameter usage. The examples align well with the bindings/swift/README.md examples and reinforce consistent API patterns.
bindings/swift/.gitignore (1)
1-60: LGTM! Comprehensive .gitignore for Swift bindings.The ignore patterns comprehensively cover all generated artifacts from the UniFFI binding generation workflow, including Swift sources, iOS libraries, XCFrameworks, and standard Xcode/Swift development artifacts.
bindings/swift/example/LNIExample/LNIExample/Assets.xcassets/Contents.json (1)
1-6: LGTM! Standard Xcode asset catalog metadata.This is standard boilerplate generated by Xcode for the asset catalog.
bindings/swift/uniffi-bindgen.rs (1)
1-3: LGTM! Standard UniFFI bindgen entry point.The minimal delegation to
uniffi_bindgen_main()is the recommended pattern for UniFFI binding generation tools.bindings/swift/example/LNIExample/LNIExample/Assets.xcassets/AccentColor.colorset/Contents.json (1)
1-11: LGTM! Standard Xcode color asset.This is standard boilerplate generated by Xcode for the AccentColor asset.
bindings/swift/Cargo.toml (1)
1-12: Package structure looks good.The crate metadata, binary target configuration, and dependency declaration follow Rust best practices. The
publish = falsesetting is appropriate for internal tooling.Cargo.toml (1)
7-7: LGTM!The Swift bindings crate is correctly added to the workspace members, following the same pattern as the existing Kotlin and Node.js bindings.
bindings/swift/example/LNIExample/LNIExample/LNIExampleApp.swift (1)
10-17: LGTM!Standard SwiftUI app entry point following best practices.
bindings/swift/example/LNIExample/LNIExample/ContentView.swift (3)
124-151: LGTM - Balance retrieval implementation.The balance calculation is correct: dividing millisatoshis by 1000 for satoshis and by 100 billion for BTC. The async/await pattern and error handling are properly implemented.
268-290: LGTM!Clean, reusable button component with proper async handling.
10-10: The generated Swift bindings are properly accessible. Bothlni.swiftandContentView.swiftare compiled into the sameLNIExampletarget (as shown in the build phases), which means they share the same module namespace in Swift. No explicit import statement is needed for files compiled together in the same target—they automatically have access to each other's public types. The code is correct as-is.Likely an incorrect or invalid review comment.
bindings/swift/example/LNIExample/LNIExample.xcodeproj/project.pbxproj (1)
52-61: Project structure places generated files at root level.The
lni.swiftandLNI.xcframeworkare placed at the project root rather than inside the LNIExample group. This is a valid approach for generated artifacts, keeping them separate from hand-written source files.bindings/swift/build.sh (3)
48-114: LGTM - iOS build logic.The iOS build section correctly handles both simulator architectures (arm64 and x86_64), creates a universal library with
lipo, and builds for the device target. The|| truepattern forrustup target addis appropriate for idempotent operations.
116-143: LGTM - Library detection and binding generation.The script correctly handles both Linux (
.so) and macOS (.dylib) shared libraries, with a clear error message if neither is found.
145-174: LGTM - XCFramework creation.The XCFramework is correctly assembled with separate library slices for simulator and device, sharing the same headers. The cleanup before creation ensures a clean build.
Adds Swift/iOS bindings for LNI using UniFFI, mirroring the existing Kotlin/Android implementation.
Changes
bindings/swift/- New Swift binding packageCargo.toml+uniffi-bindgen.rs- UniFFI bindgen setupbuild.sh- Generates Swift bindings, builds iOS static libs, creates XCFramework with headers.gitignore- Excludes generatedSources/LNI/,libs/,LNI.xcframework/bindings/swift/example/- iOS example app (SwiftUI)Root
Cargo.toml- Addedbindings/swiftto workspace membersUsage
Generated bindings include all node types (
StrikeNode,BlinkNode,NwcNode,ClnNode,LndNode,PhoenixdNode,SpeedNode), theLightningNodeprotocol, and factory functions for polymorphic access.Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
Summary by CodeRabbit
New Features
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.