GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat(swift-interop): generate and link thunks in app builds (4/7) by NathanWalker · Pull Request #521 · NativeScript/ios

Conversation

@NathanWalker

@NathanWalker NathanWalker commented Oct 21, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Summary

Swift interop stack — review bottom-up; each PR shows only its own commits. Merge in order; after a squash merge, rebase the next branch onto main. Design discussion: RFC NativeScript/rfcs#57.

  1. feat(metadata-generator): Swift symbol graphs to thunks and TypeScript declarations (Swift interop 1/7) #518 generator: symbol graphs → IR → thunks + .d.ts
  2. feat(runtime): ns:swift calls Swift through generated thunks (Swift interop 2/7) #519 runtime: ns:swift core
  3. feat(swift-interop): modules, generics, protocols, Observation and SwiftUI (3/7) #520 modules, generics, protocols, Observation, SwiftUI
  4. feat(swift-interop): generate and link thunks in app builds (4/7) #521 app builds ← this PR
  5. feat(swift-interop): returning closures, generic functions, tuples, Result and C structs (5/7) #522 more values: returning closures, generic functions, tuples, Result, C structs
  6. feat(swift-interop): adapter lifetime, cancellation, subscripts, Combine and operators (6/7) #523 adapter lifetime, cancellation, subscripts, Combine, operators
  7. feat(swift-interop): Any, UUID and Decimal, performance, and docs (Swift interop 7/7) #517 Any/UUID/Decimal, performance, docs

Apps get thunks for the Swift modules they name, and a benchmark compares the Swift path with the Objective-C one.

App_Resources/iOS/build.xcconfig
  NS_SWIFT_MODULES = WeatherKit MyPackage
nsld.sh (iOS and visionOS templates)
  build-step-swift-interop.py
    swift-symbolgraph-extract → generator --swift-verify → swiftc → link
    unchanged module → reuse the cached thunk object

The CLI needs no change. TestRunner/app/tests/SwiftInteropBenchmarks.js adds benchmarks of the same API through both paths.

Evidence

  • Before: thunks had to be generated and linked by hand.
    After: a real app (its own module, WeatherKit, a local SwiftPM package) builds through ns build ios and imports ns:swift in Debug and Release. App-level plugin modules and relative paths resolve. An unchanged module reuses its thunk object on relink.

Merge Danger

Door: two-way

Blast Radius: app builds

nsld.sh changes in the iOS and visionOS templates but does nothing unless NS_SWIFT_MODULES is set, so apps without it link exactly as before.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
  • X
  • Mastodon
  • Reddit
  • LinkedIn

Comment @coderabbitai help to get the list of available commands.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Oct 21, 2026
feat(metadata-generator): Swift symbol graphs to thunks and TypeScript declarations (Swift interop 1/7) #518
Draft
feat(runtime): ns:swift calls Swift through generated thunks (Swift interop 2/7) #519
Draft
feat(swift-interop): modules, generics, protocols, Observation and SwiftUI (3/7) #520
Draft
feat(swift-interop): returning closures, generic functions, tuples, Result and C structs (5/7) #522
Draft
feat(swift-interop): adapter lifetime, cancellation, subscripts, Combine and operators (6/7) #523
Draft
feat(swift-interop): Any, UUID and Decimal, performance, and docs (Swift interop 7/7) #517
Draft
@NathanWalker
NathanWalker marked this pull request as ready for review October 21, 2026 13:50
@NathanWalker
NathanWalker force-pushed the swift-interop/4-app-builds branch from 0cb1e1b to 91839dc Compare October 21, 2026 14:47
@NathanWalker
NathanWalker force-pushed the swift-interop/3-modules-protocols branch from b951726 to 39dac9d Compare October 21, 2026 14:47
@NathanWalker
NathanWalker marked this pull request as draft October 21, 2026 16:33
NathanWalker added 4 commits October 21, 2026 09:44
@NathanWalker
perf(swift-interop): benchmarks against the Objective-C path
e8a4988
SwiftInteropBenchmarks.js times matched operations through the
Objective-C/C metadata path and through Swift thunks:
- a function;
- class and instance methods;
- a string round trip;
- object construction;
- a property read.

It writes the results to Documents/swift-bench.txt and asserts nothing.
The fixture gains the Swift counterparts.

The benchmarks showed instance calls and property accesses copying their
member group on every call to filter a generic family's overloads by
receiver. Groups now record whether they mix owners, and only those are
filtered. With that, the Swift path matches or beats the Objective-C path
in a Debug simulator build (docs/swift-interop.md has the numbers).
@NathanWalker
feat(swift-interop): generate and link thunks in app builds
03f4ff8
Apps list the Swift modules JavaScript uses in NS_SWIFT_MODULES, in
App_Resources/iOS/build.xcconfig. SDK modules, SwiftPM packages and the
app's own module are all supported.

At link time, nsld.sh (iOS and visionOS templates) runs the new
build-step-swift-interop.py for each architecture, next to the
Objective-C metadata step:
- it extracts the modules' symbol graphs from the build products and the
  SDK;
- it generates and verifies them as one unit;
- it compiles the thunks to an object;
- it hands nsld the object and a -u flag per register symbol to link.

The script ships beside build-step-metadata-generator.py, so the CLI
needs no change.

Checked against Xcode-shaped environments: the SwiftDemo/SwiftDemoKit
modules and WeatherKit each produce an object that exports its register
symbols. A full `ns build` against a packed runtime has not been run yet.
@NathanWalker
fix(swift-interop): find plugin modules and relative paths in app builds
5f3ee05
The app build step now passes the app's header search paths to symbol
graph extraction and to the thunk compile, so clang modules from plugin
sources resolve. One example is @nativescript/core's NativeScriptEmbedder,
which an app's Swift module imports. Relative search paths are resolved
against SRCROOT, since the step runs from the metadata generator's
folder.

Validated with an app: the app's own Swift module plus WeatherKit, built
through `ns build ios` with the packed runtime. Debug and Release
simulator builds both pass a startup check of every ns:swift feature.
@NathanWalker
perf(swift-interop): reuse the thunk object across app builds
e76a9ec
The app build step keys the generated object on a hash of the extracted
symbol graphs, the generator binary, the step itself, and the generator
and compiler command lines. A relink with the same key reuses the
previous object instead of regenerating, verifying and recompiling, so an
unchanged module costs only its symbol graph extraction.
@NathanWalker
NathanWalker force-pushed the swift-interop/4-app-builds branch from 91839dc to e76a9ec Compare October 21, 2026 16:44
@NathanWalker
NathanWalker force-pushed the swift-interop/3-modules-protocols branch from 39dac9d to 83c8aff Compare October 21, 2026 16:44
@NathanWalker NathanWalker added this to the 10.0 milestone Oct 21, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

10.0

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@NathanWalker
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.