AgentStack
SKILL verified MIT Self-run

Swift Binding Assistant

skill-justinwojo-claude-skills-swift-binding-assistant · by justinwojo

Guide users through creating .NET C# bindings for Swift or Objective-C Apple platform libraries (iOS, macOS, Mac Catalyst, tvOS). Takes a user from an SPM package URL or xcframework to a validated NuGet package using the SwiftBindings.Sdk. Handles prerequisites, xcframework building, binding generation, error diagnosis, and optional binding review. Auto-detects whether the framework is Swift, Obj…

No reviews yet
0 installs
3 views
0.0% view→install

Install

$ agentstack add skill-justinwojo-claude-skills-swift-binding-assistant

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Swift Binding Assistant? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Swift & ObjC Binding Assistant

Guide users through creating .NET C# bindings for Swift or Objective-C Apple platform libraries using the SwiftBindings.Sdk. Supports iOS, macOS, Mac Catalyst, and tvOS. The generator auto-detects framework type (Swift, ObjC, or mixed) and runs the correct pipeline — no flags needed.

Documentation

The authoritative docs live in the project wiki. Always fetch the latest version from the raw URLs below when you need to reference them — do NOT rely on memorized content, as it may be outdated. Use whatever fetch mechanism is available (e.g., WebFetch, curl, browser, or built-in web tools).

| Doc | URL | |-----|-----| | Getting Started | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Getting-Started.md | | FAQ | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/FAQ.md | | Troubleshooting | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Troubleshooting.md | | Known Limitations | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Known-Limitations.md | | Supported Features | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Supported-Features.md | | How Bindings Map | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/How-Bindings-Map.md | | Customization | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Customization.md | | SwiftUI Interop | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/SwiftUI-Interop.md | | NativeAOT Deployment | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/NativeAOT-Deployment.md | | Ownership & Disposal | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Ownership.md | | Upgrading | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Upgrading.md | | Architecture | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Architecture.md | | Multi-Framework Libraries | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Multi-Framework-Libraries.md | | Publishing | https://raw.githubusercontent.com/wiki/justinwojo/swift-dotnet-bindings/Publishing.md |

Fetch docs proactively when:

  • The user hits a build error (fetch Troubleshooting)
  • The user asks what's supported (fetch Supported Features, Known Limitations)
  • The user asks how Swift types map to C# (fetch How Bindings Map)
  • You need to explain a gap or skip reason (fetch Known Limitations)
  • The user asks about memory management or disposal (fetch Ownership)
  • The user asks about upgrading versions (fetch Upgrading)
  • The user is binding more than one framework from the same vendor (fetch Multi-Framework Libraries)
  • The user is preparing to publish a NuGet package, sets up CI release workflows, or needs pack metadata details (fetch Publishing)
  • The user has a general question (fetch FAQ first — it may already be answered)

Workflow Overview

User Input
├── SPM package URL → Build xcframework (spm-to-xcframework)
├── GitHub release with xcframework → Download it
├── Local xcframework → Use directly
└── Vendor xcframework → Verify requirements
         │
         ▼
   Check prerequisites
         │
         ▼
   Create binding project (dotnet new swift-binding)
   Copy xcframework into project
   Configure dependencies if needed
         │
         ▼
   dotnet build
         │
    ┌────┴────┐
  Success   Errors → Diagnose (fetch Troubleshooting.md)
    │                      │
    ▼                      │
  dotnet pack    ◄─────────┘
    │
    ▼
  NuGet package ready
    │
    ▼
  Ask: "Would you like me to review the generated binding
        for completeness and usability?"

Framework type is AUTO-DETECTED during build — no flags needed:
  Swift  → Parser/Marshaler/Emitter pipeline → {Module}.cs + Swift wrapper
  ObjC   → Clang AST pipeline → ApiDefinition.cs + StructsAndEnums.cs + BgenDelegates.cs
  Mixed  → Both pipelines run → two projects emitted

Step 0: Gather Information

Ask the user what they're starting with:

  1. SPM package URL — a GitHub URL containing a Package.swift (e.g., https://github.com/kean/Nuke)
  2. Local xcframework — a path to a .xcframework directory on disk
  3. A library name — they may not know the format; help them figure out what they have

Also ask:

  • What's the library name? (for the NuGet package naming)
  • What platform are you targeting? (iOS is the default; also supports macOS, Mac Catalyst, tvOS)
  • Is it a Swift framework, an Objective-C framework, or are you unsure? (The tool auto-detects, but knowing upfront helps set expectations for output format.)
  • Does the library depend on any other frameworks? (for framework dependencies)

Step 1: Check Prerequisites

Run these checks and report results to the user:

# Host OS check — Apple platform binding generation requires macOS + Xcode.
# If this prints anything other than "Darwin", STOP and tell the user the
# workflow can't proceed on this host (Linux/Windows have no Xcode toolchain
# and can't compile the Swift wrapper xcframework).
uname -s

# Xcode check — requires Xcode 26 or later (not just Command Line Tools)
xcode-select -p
# Must show /Applications/Xcode.app/Contents/Developer or similar
# If it shows /Library/Developer/CommandLineTools, tell the user:
#   sudo xcode-select -s /Applications/Xcode.app

# Verify Xcode version
xcodebuild -version
# Must be Xcode 26.x or later

# .NET SDK check
dotnet --version
# Must be 10.x or later

# Platform workload check
dotnet workload list
# Must include the workload for the target platform:
#   iOS:           "ios"           → dotnet workload install ios
#   macOS:         "macos"         → dotnet workload install macos
#   Mac Catalyst:  "maccatalyst"   → dotnet workload install maccatalyst
#   tvOS:          "tvos"          → dotnet workload install tvos

# Template check
dotnet new list swift-binding
# If not found: dotnet new install SwiftBindings.Templates

If any prerequisite is missing, guide the user through installing it before proceeding. Do not continue until all prerequisites pass.

Hard stop on non-macOS hosts: if uname -s is not Darwin, the workflow cannot proceed — Apple platform bindings require Xcode, which only runs on macOS. Inform the user and stop. Do not try to suggest cross-compilation, Docker, or remote-build workarounds; there isn't a supported path today.

Step 2: Obtain the xcframework

From SPM (Swift Package Manager)

If the user provides an SPM package URL:

  1. Clone the spm-to-xcframework tool (if not already present):

``bash git clone https://github.com/justinwojo/spm-to-xcframework.git /tmp/spm-to-xcframework ``

  1. Determine the latest release tag for the Swift package. Do not use tail -5 on unsorted ls-remote output — git returns tags in lexicographic order, so 1.10.0 would sort before 1.2.0 and you'd pick the wrong version. Use a version-aware sort instead:

``bash # Sort tags by semver descending; suffix=- pushes prereleases (-rc1, -beta) below stable releases git -c versionsort.suffix=- ls-remote --tags --sort=-version:refname --refs \ | head -10 # Output: abc1234 refs/tags/12.7.3 # def5678 refs/tags/12.7.2 # ... # The first line after filtering prereleases is your latest stable tag. ` If the project uses non-semver tags or has unusual versioning, fall back to the GitHub releases page (https://github.com///releases/latest`) or ask the user which version they want.

  1. Build the xcframework (capture output — this can take several minutes):

``bash cd /tmp/spm-to-xcframework && swift run spm-to-xcframework \ --url \ --version \ --output /tmp/xcframeworks 2>&1 | tee /tmp/spm-build.txt ` For a local Package.swift directory: `bash cd /tmp/spm-to-xcframework && swift run spm-to-xcframework \ --path /path/to/package \ --output /tmp/xcframeworks 2>&1 | tee /tmp/spm-build.txt ` The output xcframework(s) will be in /tmp/xcframeworks/`.

  1. If the library has multiple products, ask the user which one to bind (or use --product to target one).
  1. If the library has dependencies that the user also wants to bind, use --include-deps.

The tool handles BUILD_LIBRARY_FOR_DISTRIBUTION=YES and dynamic framework building automatically.

From a local/vendor xcframework

Verify the xcframework meets requirements:

# Check it exists and has expected structure
ls /Library.xcframework/

# Check it's a dynamic framework (not static)
# Look for a .framework bundle with a Mach-O binary inside
# Use the appropriate slice directory for your target platform:
#   iOS:           ios-arm64_x86_64-simulator or ios-arm64
#   macOS:         macos-arm64
#   Mac Catalyst:  ios-arm64-maccatalyst
#   tvOS:          tvos-arm64_x86_64-simulator or tvos-arm64
file /Library.xcframework//Library.framework/Library
# Should say "dynamically linked shared library"
# If it says "current ar archive" → it's static, needs rebuild

# Check for Swift module (use appropriate slice directory)
ls /Library.xcframework//Library.framework/Modules/*.swiftmodule 2>/dev/null
# If present → Swift framework (uses ABI JSON pipeline)
# If empty → ObjC framework (uses Clang AST pipeline) — both are fully supported

# For ObjC frameworks, verify headers and module map exist
ls /Library.xcframework//Library.framework/Headers/ 2>/dev/null
ls /Library.xcframework//Library.framework/Modules/module.modulemap 2>/dev/null
# ObjC frameworks need public headers AND a module.modulemap for binding generation
# The generator uses module.modulemap as the validity check for ObjC frameworks

If the xcframework is static:

  • Static xcframeworks are supported for ObjC frameworks (e.g., Firebase/Google SDKs ship static xcframeworks and bind correctly).
  • Static xcframeworks are NOT supported for Swift frameworks — they must be rebuilt as dynamic with BUILD_LIBRARY_FOR_DISTRIBUTION=YES.
  • If the user controls the build, they can rebuild it. If not, suggest spm-to-xcframework if the source is available as SPM.
  • If neither option works, point them to Maui.NativeLibraryInterop as an alternative approach (hand-written C wrappers, works with any xcframework).

Step 3: Create the Binding Project

# Pick a working directory
mkdir -p ~/swift-bindings && cd ~/swift-bindings

# Create the project — naming convention:
#   Single library:        .Swift.           (e.g., Nuke.Swift.iOS)
#   Multi-vendor SDK set:  SwiftBindings..          (e.g., SwiftBindings.Stripe.Core)
# Platform suffixes: iOS, macOS, MacCatalyst, tvOS
# Use --platform to set the target (default: ios)

# iOS (default)
dotnet new swift-binding -n .Swift.iOS

# macOS
dotnet new swift-binding -n .Swift.macOS --platform macos

# Mac Catalyst
dotnet new swift-binding -n .Swift.MacCatalyst --platform maccatalyst

# tvOS
dotnet new swift-binding -n .Swift.tvOS --platform tvos

# Copy the xcframework into the project
cp -r  .Swift./

The generated .csproj will look like:


  
    net10.0-ios  
  

The SDK version (X.Y.Z) is pinned by the template at install time.

The SDK auto-detects the target platform from the TFM — no additional configuration needed beyond setting the correct TFM.

The same .csproj and SDK work for both Swift and ObjC frameworks. The SDK auto-detects the framework type during the build and runs the correct pipeline. No additional configuration is needed for ObjC frameworks.

Framework Dependencies

If the library imports other Swift frameworks, the user needs to provide them.

Auto-detection (default): The SDK ships with true enabled by default. The build analyzes the xcframework's binary linkage, finds matching sibling binding projects in the solution, and auto-injects `` items. If a needed dependency is missing, it emits SWIFTBIND080 with a suggested fix. In most multi-project solutions, you do not need to declare dependencies manually.

Option 1: `` (multi-project solutions — preferred)

For multi-product vendors (e.g., Stripe) where you're binding several frameworks in the same solution:


  

The SDK automatically resolves dependency xcframework search paths and module databases during wrapper compilation, propagates native references to the consumer's app bundle, and converts the reference into a transitive ` during dotnet pack` — no manual configuration needed.

Option 2: `` (external/pre-built or internal dependencies)

For dependencies that are pre-built xcframeworks (not sibling projects), or internal helper frameworks (e.g., ObjC-only support modules) that won't be published as their own NuGet package:


  
  

  
  

Each dependency also needs to be a built xcframework. If the user used spm-to-xcframework --include-deps, these will already exist in the output directory.

For published dependencies, both PackageId and PackageVersion are required for NuGet pack to declare the dependency (SWIFTBIND040 warns if missing). For internal helpers that won't be published separately, the warning is intentional — consumers will need to add a `` for the internal framework manually. See the Multi-Framework Libraries wiki page for the full pattern.

Step 4: Build

Always capture build output to a temp file — it can be very long:

cd .Swift.
dotnet build 2>&1 | tee /tmp/swift-binding-build.txt

Then read the output file to check the result.

On Success

For Swift frameworks, the build automatically:

  • Extracts ABI metadata from the xcframework
  • Runs the binding generator (produces .cs and .swift wrapper files)
  • Compiles the Swift wrapper into an xcframework
  • Builds the C# bindings into a DLL

For ObjC frameworks, the build automatically:

  • Runs clang -ast-dump=json on the framework's umbrella header
  • Parses the Clang AST into ObjC declarations
  • Filters platform type stubs (types already in .NET iOS SDK)
  • Generates ApiDefinition.cs (always), plus StructsAndEnums.cs and BgenDelegates.cs if applicable
  • Runs the .NET iOS binding tools (bgen) to compile the binding
  • No Swift wrapper is needed — ObjC frameworks link directly

For mixed frameworks (both Swift and ObjC surface), both pipelines run and two projects are emitted.

Tell the user the build succeeded and move to Step 5.

On Failure

Immediately fetch the troubleshooting guide from the URL in the doc table above, then diagnose the error. Here's a quick-reference for the most common errors:

| Error | Cause | Fix | |-------|-------|-----| | SWIFTBIND001 | No xcframework in project dir | Copy xcframework into the project, or add explicit ` item | | **SWIFTBIND002** | Multiple xcframeworks found | One xcframework per project — create separate binding projects for each | | **SWIFTBIND003** | xcframework path doesn't exist | Check the path in item | | **SWIFTBIND010** | Unsupported target framework | Use Apple platform TFM: net10.0-ios, net10.0-macos, net10.0-maccatalyst, net10.0-tvos | | **SWIFTBIND011** | Consumer targets older platform version than library requires | Update SupportedOSPlatformVersion to the version shown in the warning | | **SWIFTBIND030** | Missing architectures for packing | Set all | | **SWIFTBIND031** | Wrapper xcframework missing device or simulator slice | Verify xcframework has both slices, or set false for local-only | | **SWIFTBIND035** | Cannot resolve platform version for NuGet pack | Use a versioned TFM (net10.0-ios26.0) or install the platform workload | | **SWIFTBIND040** | missing PackageId/PackageVersion` | Add metadata if the dep is publi

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.