Bind iOS Swift libraries

Important

We're currently investigating custom binding usage on the Xamarin platform. Please take this survey to inform future development efforts.

The iOS platform, along with its native languages and tooling, is constantly evolving and there are plenty of third-party libraries that have been developed using the latest offerings. Maximizing code and component reuse is one of the key goals of cross-platform development. The ability to reuse components built with Swift has become increasingly important to Xamarin developers as their popularity amongst developers continues to grow. You may already be familiar with the process of binding regular Objective-C libraries. Additional documentation is now available describing the process of Binding a Swift Framework, so they are consumable by a Xamarin application in the same manner. The purpose of this document is to describe a high-level approach to create a Swift Binding for Xamarin.

High-level approach

With Xamarin, you can bind any third-party native library to be consumable by a Xamarin application. Swift is the new language and creating binding for libraries built with this language requires some additional steps and tooling. This approach involves the following four steps:

  1. Building the native library
  2. Preparing the Xamarin metadata, which enables Xamarin tooling to generate C# classes
  3. Building a Xamarin binding library using the native library and the metadata
  4. Consuming the Xamarin binding library in a Xamarin application

The following sections outline these steps with additional details.

Build the native library

The first step is to have a native Swift Framework ready with Objective-C header created. This file is an autogenerated header that exposes desired Swift classes, methods, and fields making them accessible to both Objective-C and ultimately C# via a Xamarin binding library. This file is located within the framework under the following path: <FrameworkName>.framework/Headers/<FrameworkName>-Swift.h. If the exposed interface has all the required members, you can skip to the next step. Otherwise, further steps are required to expose those members. The approach will depend on whether you have access to the Swift framework source code:

  • If you have access to the code, you can decorate the required Swift member(s) with the @objc attribute and apply a few additional rules to let the Xcode build tools know that these members should be exposed to the Objective-C world and the header.
  • If you don't have the source code access, you need to create a proxy Swift framework, which wraps the original Swift framework and defines the public interface required by your application using the @objc attribute.

Prepare the Xamarin metadata

The second step is to prepare API definition interfaces, which are used by a binding project to generate C# classes. These definitions could be created manually or automatically by the Objective Sharpie tool and the aforementioned autogenerated <FrameworkName>-Swift.h header file. Once the metadata is generated, it should be verified and validated manually.

Build the Xamarin.iOS binding library

The third step is to create a special project - Xamarin.iOS binding library. It references the frameworks and the metadata prepared at the previous step along with any additional dependencies the respective framework is reliant upon. It also handles the linking of the referenced native frameworks with the consuming Xamarin.iOS application.

Consume the Xamarin binding library

The fourth and final step is to reference the binding library in a Xamarin.iOS application. It is sufficient to enable the use of the native library within Xamarin.iOS applications targeting iOS 12.2 and above. For those applications targeting a lower version, some additional steps are required:

  • Add Swift dylib dependencies for runtime support. Starting from iOS 12.2 and Swift 5.1, the language became ABI (application binary interface) stable and compatible. That's why any application targeting a lower iOS version needs to include Swift dylibs dependencies used by the framework. Use the SwiftRuntimeSupport NuGet package to automatically include required dylib dependencies into the resulting application package.
  • Add SwiftSupport folder with signed dylibs, which is validated by the AppStore during uploading process. The package should to be signed and distributed to the AppStore connect using Xcode tools, otherwise it will be automatically rejected.

Walkthrough

The approach above outlines the high-level steps required to create a Swift Binding for Xamarin. There are many lower-level steps involved and further details to consider when preparing these bindings in practice including adapting to changes in the native tools and languages. The intent is to help you to gain a deeper understanding of this concept and the high-level steps involved in this process. For a detailed step-by-step guide, refer to the Xamarin Swift Binding Walkthrough documentation.