Are there any plans we get Swift-dotnet anytime soon?

Since we have Swift-java now, wouldn't it be a good idea to have Swift-dotnet as well? Are there any plans to do it?
The advantages are similar to to the ones of having java interop (access to huge ecosystem), while on it might be easier to than JVM - since C# and Swift are somewhat closer semantically than Java and Swift.
In addition, a good interop (or even a version that targets dotnet) could make application level development for Windows (despite dotnet being open source and cross platform), and hence adoption of the language a easier - after all, unfortunately, Windows experience of Swift development is still not the best - which is a deal blocker for teaching Swift, or adopting it in education programs much harder - outside of US (most people don't own Apple machines, as they are not really affordable and non-Apple machines in 99% of cases come with Windows preinstalled).

1 Like

While I'm not entirely up to date how far along it is, but .NET has gained some calling convention support AFAIR?

As well as this work done by Xamarin:

So in some ways this is more support the .net platform provides to Swift than current day JDK which doesn't support Swift's calling convention.

If you'd like to help those efforts I'm sure the .NET folks would be able to point at what might need more work etc :slight_smile:

3 Likes

After following the conversations on the .NET side a bit:

  • It seems like .NET 9 had preliminary work done
  • This was followed in .NET 10 and they have an experimental POC
  • It's meant for internal products like MAUI so they're only supporting features used by specific targeted frameworks
  • It's one way interop (.NET calls into Swift) It's complicated
  • It'll work on Apple platforms only

So far they seem to have added a few runtime capabilities to support the calling convention and there seems to be experimental projection tooling (to generate C# bindings to call into Swift).

The runtime, tooling and documentation is in this repo.

They have a sample MacCatalyst app built with it.

2 Likes

Here's a copy of relevant details from the README for posterity.

Usage

The tooling can consume a Swift ABI file or a framework name from the standard library. If a framework name is provided, the tool generates the ABI file based on the .swiftinterface file. This ABI file contains a JSON representation of the abstract syntax tree of the .swiftinterface file. Multiple Swift ABI files and frameworks can be specified for bindings.

Description:
  Swift bindings generator.

Usage:
  SwiftBindings [options]

Options:
    -a, --swiftabi     Required. Path to the Swift ABI file.
    -d, --dylib        Required. Path to the dynamic library.
    -t, --tbd          Required. Path to the TBD file.
    -o, --output       Required. Output directory for generated bindings.
    -v, --verbose      Verbosity level. 0 = No logging, 1 = General information, 2 = Debugging information. (default: 1)

Supported scenarios

StoreKit in-app purchase example:

SwiftArray<SwiftString> productIdentifiers = new SwiftArray<SwiftString>();
productIdentifiers.Append(new SwiftString("id1"));
productIdentifiers.Append(new SwiftString("id2"));
Task<SwiftArray<SwiftString>> productsTask = Product.products<SwiftArray<SwiftString>>(productIdentifiers);
SwiftArray<Product> products = await productsTask;

Product product = products[0];
await product.purchase(new SwiftSet<Product.PurchaseOption>());

A complete list of supported scenarios is available in src/Swift.Bindings/tests.

If an unsupported syntax element is encountered in the ABI file, the tooling will ignore it and generate C# source code for known syntax elements. The generated C# bindings are published as source files to the output directory, allowing users to modify them before compilation.

Experimental packages

NuGet feed: https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet-experimental

StoreKit bindings:

Swift.Bindings.MacOSX.Experimental -version 1.0.0-alpha.25201.1
Swift.Bindings.MacCatalyst.Experimental -version 1.0.0-alpha.25201.1
Swift.Bindings.iPhoneSimulator.Experimental -version 1.0.0-alpha.25201.1
Swift.Bindings.iPhoneOS.Experimental -version 1.0.0-alpha.25201.1
Swift.Bindings.AppleTVSimulator.Experimental -version 1.0.0-alpha.25201.1
Swift.Bindings.AppleTVOS.Experimental -version 1.0.0-alpha.25201.1

Projection tooling:

Swift.Bindings -version 1.0.0-alpha.25201.1

Tried this one?

1 Like

There's also this made by @ericsink .
It would let you do


import dotnet; 
import aspnetcore; 

typealias WebApplication = Microsoft.AspNetCore.Builder.WebApplication;
typealias Func = System.Func_1;

public func swift_main() throws -> Swift.Int32 {
    let app = try WebApplication.Create()

    try app.MapGet(
        pattern: "/", 
        handler: 
            Func<System.String>
            { 
                () -> System.String in 
                "Hello World!" 
            }
        );

    try app.Run();

    return 0;
}

I can't get it to run on newer swift or dotnet but it did evidently work at one point.