SwiftBindings SDK 0.18.0
·
52 commits
to main
since this release
SwiftBindings 0.18.0
0.18.0 focuses on making generated bindings more trustworthy: standalone generation now compile-checks its own output — the Swift wrapper and the emitted C# — withdraws members it can't bind soundly (with a recorded reason), and fails with a machine-readable report rather than emitting output it knows is broken. A number of real-world libraries that previously failed to generate, compile, or run now bind, and generated names get a readability pass that includes source-breaking renames.
Highlights
- Generation compile-checks its own output — standalone (
--xcframework) generation now compiles both sides of the binding, attributes compiler errors back to the Swift declarations that caused them, and withdraws those members rather than shipping them; SDK-driven builds run the same soundness gates, with the project build serving as the compile check. The intent: a library with unsupported corners should produce a smaller but usable binding instead of one that fails to compile. - Failures are machine-readable — a failed generation now writes
binding-failure-report.jsonwith the terminal reason, blocking diagnostics, and the declarations they attribute to, and the binding report records a disposition for every declaration the generator parsed. - Better cross-module support — types from sibling bindings resolve in more positions (existentials, class returns, protocol requirements), dependency modules are discovered transitively — including ones reachable only through a re-export — and generated projects derive their
PackageReferences from the namespaces they actually use. Multi-framework libraries benefit the most. - More real-world libraries bind — module names that collide with the BCL, ObjC frameworks needing the
-fmodulesretry, registered Apple integer enums, escaping closures in constrained extensions, protocols withT!requirements, and more. Degraded members that previously threwEntryPointNotFoundExceptionat runtime now throwSwiftBindingUnavailableExceptionwith the reason attached. - More readable generated names (source-breaking) — factory and member names are cleaned up in several areas, and pure-ObjC
[Native]enum members are now PascalCased. Regenerating on 0.18.0 renames identifiers; existing consumers will need to update call sites.
Generator improvements
- Naming changes (breaking) — closed-specialization factories get readable names (
FromByteArray, notFrombyteArr_); a type's sole bypass factory is plainCreate, keeping the hash suffix only on collision; digit-bearing acronyms keep their casing (SHA3_256,MP3); fluent builders lose the spuriousGetprefix (EqualToSuperview()); protocol requirement families fold argument labels consistently; ObjC[Native]enum members are PascalCased (Foo.center→Foo.Center). - Marshalling fixes — corrects
inoutparameter marshalling across the wrapper paths, fixes struct-field and existential-setter defects, and Swift operators returning classes and enums now compile, as do@objcexistential getters. - Newly supported shapes — per-conformer generic container properties,
NSCoding-style@objcdelegate reverse dispatch, honest projection ofNever-defaulted associated types, and Apple's registered integer enums (PKPaymentButtonType,HKWorkoutActivityType, …) including insideOptionaland arrays. - Apple SDK awareness — members referencing Apple types are checked against the installed
Microsoft.iOSreference assembly and withdrawn with a recorded reason when the type isn't there, and aSwiftBindings.ApplePackageReferenceis emitted wherever supplement types are used. - Narrower, more honest boundaries — tuple support is now stated explicitly and enforced, where some shapes were previously emitted in forms that could not work, and async closures outside the supported baseline emit
SB0005tombstone stubs instead of silently degrading to synchronous dispatch. - New convenience overloads —
stringoverloads forFoundation.URLparameters,int/uintoverloads for enum cases with native-int payloads, and truncated overloads that recover members whose only unbindable part was a trailing defaulted parameter.
Runtime and async
- Cancellation fixes — cross-module extension and generic-parent async members now honor
CancellationTokenand complete theirTaskasCanceledon cancellation, matching the behavior plain async methods already had; already-cancelled tokens short-circuit without crossing into Swift. Code that detected cancellation by catchingSwiftExceptionshould catchTaskCanceledExceptioninstead. - Memory fixes — escaping-closure contexts are released when Swift drops them, and a per-call argument buffer leak in callback marshalling is fixed.
SwiftUI.Textis public — the runtime's SwiftUI text projection moved fromSwift.SwiftUIto theSwiftUInamespace and is now publicly constructible (breaking for consumers who referenced the old namespace).
Diagnostics and failure reporting
- Integrity checks — new checks fail generation when a binding would otherwise ship a P/Invoke without its wrapper symbol, a reference to a suppressed proxy class, or an unresolved sibling-module dependency — each with a specific
SWIFTBINDcode naming the cause. - Declaration accounting — parser reconciliation must balance (every declaration parsed, withdrawn, or failed, with a recorded disposition), members of wholly-suppressed types now appear in the report, and the artifact manifest carries a row for every withdrawn declaration with its evidence.
- Build hygiene — a failed generation no longer stamps the build up-to-date (the next build retries instead of reusing stale output), wrapper
swiftcerrors are visible at normal verbosity, and aSwiftFrameworkDependencymissing its managed reference is flagged (SWIFTBIND081, withNativeOnly="true"to opt out for native-only deps).
Developer experience
- One file per type — generated bindings now split each top-level type into its own
{Module}.Types.{TypeName}.csalongside the{Module}.csprelude, plus a per-module{Module}.api-surface.mdmember table; the API surface itself is unchanged. Regenerated projects glob both patterns automatically — only hand-maintained csproj/CI globs need updating. - Parallel-build fixes — the SDK now coalesces its out-of-band builds with the authoritative project graph, fixing races that could break solutions with several bindings under
-mor IDE concurrency. - Cleaner IntelliSense — unavailable-member stubs and raw async-iterator plumbing are hidden from code completion while remaining callable.
- New CLI flags —
--emit-input-graph(dump the resolved input dependency graph),--verification-package-feed(offline feed for the C# verification build), and--no-verify-csharp(skip the C# verification leg).
Packages
| Package | Version |
|---|---|
SwiftBindings.Runtime |
0.18.0 |
SwiftBindings.Sdk |
0.18.0 |
SwiftBindings.Templates |
0.18.0 |
SwiftBindings.Apple is unchanged at 26.2.8 — it declares a floor-only Runtime range, so the published supplement rides forward without a republish.
See the GitHub wiki for installation and usage.