One of the most exciting announcements during this year’s Connect(); event was the ability to embed .NET libraries into existing iOS (Objective-C/Swift) and Android (Java) applications with .NET Embedding. This is great because you can start to share code between your iOS and Android applications, and you can also share the user interface between your apps when you combine .NET Embedding with Xamarin.Forms Native Forms. This means that you can leverage your existing investments and apps without having to re-write them from scratch to start adding cross-platform logic and UI. In fact, during the Connect(); keynote I showed how I was able to extend the open source Swift-based Kickstarter iOS application with .NET Embedding and Xamarin.Forms Native Forms. You can check out the clip below.
Today, let’s take a deeper look at how we can start sharing our native user interfaces and business logic in an iOS app written in Objective-C and an Android app written in Java using .NET Embedding.
Getting Started
.NET Embedding tooling is supported in both Visual Studio 2017 for Android, and Visual Studio for Mac for iOS, Android, and macOS. Since we will be working on an iOS and Android application, we will be using Visual Studio for Mac which can be downloaded from visualstudio.com. If you are on Windows you can still follow along for the Android portion.
.NET Embedding works by compiling a .NET assembly into a native library for the specified operating system. This can be a single .NET Standard Library or platform specific Xamarin.iOS and Xamarin.Android libraries that share code. The latter will enable us to access platform specific capabilities and utilize Xamarin.Forms’ Native Forms capability to share user interface code.
For this sample we will want to create three projects:
- HelloSharedUI – Portable Class Library
- HelloSharedUI.iOS – Xamarin.iOS Library
- HelloSharedUI.Droid – Xamarin.Android Library
Inside of Visual Studio for Mac we will find the multiplatform node in the New Project Dialog, where a Xamarin.Forms class library template exists. This will create a Portable Class Library for our shared code with the Xamarin.Forms NuGet package installed and some sample code. We’ll start with this.
Next, we will want to create the iOS and Android Class Libraries.
Then we must ensure that we have installed the Xamarin.Forms NuGet Package in the iOS and Android projects and that the shared portable class library’s NuGet is also up to date. If you are new to .NET Development, NuGet is package management for .NET project similar to CocoaPods and Maven packages.
Finally, we should ensure that our iOS and Android libraries have a reference to the portable class library that has our shared code.
Shared User Interface
The default template gives us the following shared user interface with a button that when clicked will update its label.
We will use this page for this example, but we can easily add additional pages written in XAML or C# with Xamarin.Forms.
Accessing Shared User Interface
With our shared user interface in place we need a way to get access to it from the iOS and Android libraries. Let’s add a class called UIHelpers.cs to the iOS and Android libraries that will contain helper methods to initialize Xamarin.Forms and display or return the page on each platform.
iOS UIHelpers
On iOS we are able to directly push the page on the navigation stack or display it modally. This is accomplished by creating an instance of MyPage, finding the root view controller, and presenting it:
Android UIHelpers
On Android we also have access to the navigation stack, but it is easier to directly return a Fragment that can then be used anywhere in the Android application:
With our code in place we are now ready to compile the libraries to embed in the native language apps.
Adding .NET Embedding NuGet Packages
The .NET Embedding tooling can be installed directly on to our development machine or added directly to the project via the Embeddinator-4000 NuGet package. This means we can add the NuGet package to our iOS and Android projects.
After we compile the library we need to run it through the .NET embedding tooling to generate the framework. This can easily be done by adding custom commands that run after the build is successful. These can be added by right clicking on the iOS project and going to options and finding Custom Commands. For this demo we will generate an iOS framework in debug mode with the following command:
For Android we will use a similar command:
Now, when we compile the library a folder named **iosoutput** will contain HelloSharedUI.iOS.framework that we can import into an iOS Objective-C or Swift project and another folder named **androidoutput** that will contain HelloSharedUI.Droid.aar for Android.
Calling .NET Code from Xcode and Objective-C
The final step for iOS is to import the .framework into Xcode and add it as an embedded binary. Follow the simple steps on our .NET Embedding documentation to import it. I created a simple UIViewController that has a button and a TouchUpInside Action that is all wrapped in a UINavigationController.
On the top of the ViewController.m we need to add an import for our header and then implement the click event to show the embedded page:
Now simply run the application to see the embedded page and C# logic:
Adding the Framework to Android Studio
Android goes through a similar process of importing the generated .aar that is explained on our .NET Embedding documentation page. After we have the .aar imported it is ready to be used an application. I generated the default application in Android Studio that displays a single Fragment in an Activity with a FloatingActionButton that has a click listener. Instead of displaying toast when the button is clicked, we can navigate to the shared user interface that we exposed as a Fragment. To get access we can import our library and then we can create the UIHelpers class, create our fragment, and replace the current view:
Now, let’s go ahead and run the app:
Embed Everywhere
In just a few minutes we were able to create shareable native user interface and business logic in XAML and C#, and embed it into a native language iOS and Android application. This is only the start as .NET embedding also supports creating embeddable libraries for not just iOS and Android, but also Objective-C/Swift macOS applications, and even C++ code for Linux based apps.
Learn More
Be sure to read through our full documentation on .NET Embedding to start leveraging .NET libraries in native language applications. You can grab the source code on my GitHub and also the full Kickstarter app source code that I demoed at Connect(); from my GitHub.
To get started with all of this, for free, head on over to VisualStudio.com and download Visual Studio 2017 or Visual Studio for Mac. You can learn more about .NET Embedding and all of our other announcements by reading our full announcement from the event.
James Montemagno, Principal Program Manager, Mobile Developer Tools
James has been a .NET developer since 2005, working in a wide range of industries including game development, printer software, and web services. Prior to becoming a Principal Program Manager, James was a professional mobile developer and has now been crafting apps since 2011 with Xamarin. In his spare time, he is most likely cycling around Seattle or guzzling gallons of coffee at a local coffee shop. He can be found on Twitter @JamesMontemagno, blogs code regularly on his personal blog http://www.montemagno.com, and co-hosts the weekly development podcast Merge Conflict http://mergeconflict.fm. |