Nuts & Bolts of Xamarin.iOS
In my previous post I gave a very high level overview of what Xamarin is and what Xamarin is not. Though my post was more conversational and explained by example, I left out the technical details. In this post, I’m going to focus on the nuts & bolts of Xamarin.iOS. But before we start off coding a sample application, it is (in my opinion) essential to understand what Xamarin.iOS is, how it is compiled, and how it executes on your iOS device. Though it is easy to jump right in and start coding, I believe it is essential to understand the Xamarin.iOS fundamentals, as well as the iOS operating system fundamentals. In the long run, this will be beneficial when you have to start debugging your apps. It will also help you troubleshoot issues and understand what is happening between the iOS operating system, Xamarin.iOS, and your own code.
Overview of a Xamarin.iOS Application
In my previous post, I explained at a high level that Xamarin.iOS was a C# wrapper around the iOS SDK. In other words, Xamarin.iOS allows you to use the same iOS SDK that Objective-C developers use to create iOS applications. The main difference is that you can access the iOS SDK via C#, instead of Objective-C. Though this explanation is adequate for most developers, it is important to understand how this is accomplished. Trust me, once you become a more experienced and accomplished mobile developer, understanding these concepts is essential to troubleshooting real-world problems that may occur in your application. It will also help you in optimizing your application for better performance and to consume less memory. In the mobile world, consuming as little memory as possible is critical for a high performing application.
What Is The Mono Framework?
Mono is a free and open source project whose goal is to create an ECMA standard-compliant version of Microsoft’s .NET Framework. Mono is based on the ECMA standards for C# and the Common Language Runtime. The project was originally started by Ximian in July 2001, founded by Nat Friedman and Miguel de Icaza. The goal was create an open source version of the .NET Framework that would not only run on Windows, but on Linux. Version 1.0 of Mono was release in June 2004, almost a year after the company was acquired by Novell. After Novell was acquired by The Attachmate Group in 2011, they laid off all US staff working on the Mono Project. But through a license agreement between Novell, now a subsidiary of Attachmate, a license agreement was reach between Friedman’s and de Icaza’s newly formed company Xamarin. Xamarin would now take stewardship of the Mono Project. Since then, Mono has evolved from creating desktop applications for Linux to creating applications on embedded systems, iOS, Android, Apple’s OS X, and other non-Windows platforms.
The Mono Framework consists of four components. They include the C# Compiler, the Mono Runtime, the Base Class Library, and the Mono Class Library.
The Mono C# Compiler
The Mono C# compiler is a feature complete compiler for C# 1.0, 2.0, 3.0, 4.0, and 5.0. It meets all EMCA specifications and includes support for generics, partial types, anonymous methods, lambda expressions, and async/await. So another words, all the unique and neat features you use for your C# .NET projects also applies to the Mono C# compiler.
The Mono Runtime
The Mono runtime is the equivalent of the Common Language Runtime in the Microsoft .NET Framework. It implements the EMCA Common Language Infrastructure (CLI). Just like the .NET CLR, the Mono Runtime provides a Just-in-Time (JIT) compiler, an Ahead-of-Time (AOT) compiler, and a Garbage Collector. Because it meets the EMCA specifications, the Mono Runtime is as feature complete as the .NET CLR.
The Mono Base Class Library
The Mono base class library is the equivalent of the Microsoft .NET Base Class Library. It provides a comprehensive set of classes, interfaces, and data types that are necessary to build applications using C#. It includes basic types such as integers, floats, doubles, strings, etc. One very important thing to note here is that not all .NET Base Class Library classes are implement in the Mono base class library. The Mono base class library only implements classes that are platform independent (i.e. that do not rely on the Windows operating system).
For example, many classes in the
System.Drawing namespace, such as
Bitmap, are .NET wrappers around GDI+. Since GDI+ is a graphics library specific to the Windows operating system, it can’t be implemented in Mono. However, to get around this, you’ll have to use the platform implementation of the class you’re looking for. In the case of
System.Drawing.Bitmap, you would use a
MonoTouch.UIKIt.UIImage in iOS, an
Android.Widget.Bitmap in Android, and a
System.Windows.Media.Imaging.BitmapImage for Windows Phone.
The Mono Class Library
The Mono class library is an extension of the Mono Framework. It provides many classes that are not included in the Microsoft .NET Base Class Library. These classes are very useful for building Linux applications, which includes Gtk+, LDAP, OpenGL, etc. This library is useful for desktop Linux applications, and don’t really apply to mobile development on iOS, and Android. But it is worth noting it does exist as a part of Mono, but does not apply to mobile development.
Xamarin.iOS & the iOS SDK
The iOS SDK is the framework that allows Objective-C developers create applications for the iPhone, iPod Touch, and the iPad. Just like the .NET Framework, it includes many components that help you create user interfaces (Cocoa Touch), access to media such as sounds and imaging (Media), and core services such as networking, location services, and threading. Usage of the SDK is done by using the Objective-C programming language and by using Apple tools and compilers (XCode).
Xamarin.iOS allows you to access the iOS SDK by using the C# programming language (via the Mono Runtime) and using either Xamarin Studio or Visual Studio as the IDE. In Figure 3, you can see that the namespaces with a black font color (
System, etc) are a part of the Mono Base Class Library. The namespaces with a purple font color (
UIKit, etc) are the Xamarin.iOS C# bindings to the iOS SDK. Now just pretend the top half of the figure is replaced with the Windows Presentation Foundation SDK, the Windows Phone SDK, or the Windows Communication Foundation SDK. When Microsoft develops a new Framework/Library, it just hooks into the .NET Base Class Library. So you can just think of Xamarin.iOS as just another library as if Microsoft developed it in the next version of .NET.
How Is A Xamarin.iOS App Compiled?
As any experienced .NET developer would know, a .NET application is compiled from C# into Microsoft Intermediate Language (MSIL). The MSIL binary can be an *.exe, *.dll, *.svc, etc. When the application runs, the .NET Common Language Runtime then interprets the MSIL using Just-in-Time (JIT) compilation and executes the MSIL as native (processor specific) code.
A Xamarin.iOS project is compiled in a slightly different way. This is a 2 step process:
- The Mono compiler compiles C# code into Intermediate Language (IL).
- The Mono compiler compiles IL into ARM native code using Ahead-of-Time (AOT) compilation.
The final executable is a native binary that is compiled for Apple’s A series ARM-based processor. The final binary is the same format as if it was compiled by XCode from Objective-C. The iOS operating system has no way of telling that the app was compiled using C# via the Mono Framework.
Why is this a different process than a regular .NET application? The iOS operating system has a security feature, or limitation (depending how you look at it), that prevents a Xamarin.iOS project from being compiled like a .NET project. The iOS operating system does not allow dynamic code generation. Because dynamic code generation is not allowed on iOS, JIT compilation is not possible. Because JIT is not possible, AOT compilation must be used.
AOT compilation is possible because this is Mono’s version of the Native Image Generator (Ngen.exe) in .NET. If you’re not familiar with .NETs NGen.exe, this allows your MSIL to be compiled to native code, rather than using JIT compilation. For certain types of applications, this provides increased performance.
Limitations of a Xamarin.iOS Project
As stated earlier, a limitation of the iOS operating system is that it does not allow dynamic code generation. This not only applies to how a Xamarin.iOS app gets compiled, it also applies to your source code as well. For the majority of applications, this is a non-issue. In .NET, you can dynamically generate IL code at runtime using the
System.Reflection.Emit namespace. This is especially useful if you are creating a scripting engine, or a compiler. But since this is probably not a good use-case on a mobile device, it is unlikely you will run into this limitation. For a full list of Xamarin.iOS limitations, refer to the Xamarin Documentation.
In order to develop an iOS application using Xamarin.iOS, you need the following tools:
- An Intel-based Macintosh computer running Mac OS 10.8 (“Mountain Lion”) or above
- The latest iOS SDK bundled with the latest XCode.
- Xamarin Studio or Microsoft Visual Studio 2010 or above
- Visual Studio Express is not supported because the Express editions do not support plug-ins.
Software & Hardware Requirements
The easiest and most common way to develop a Xamarin.iOS application is using Xamarin Studio on a Mac. Xamarin Studio is an IDE that was forked from the MonoDevelop IDE. Though different project types are supported, Xamarin Studio is best used for developing mobile applications for iOS and Android, and for developing Mac OS X applications. It is quite a powerful IDE that has many features you would expect from a modern IDE. It includes basic features like a debugger, intellisense, source control integration, and even Resharper like features.
Alternatively, you can use Visual Studio 2010 or above on a Windows machine to develop Xamarin.iOS applications. This is possible by Xamarin’s Visual Studio extension that gets installed when you install Xamarin Studio on a Windows machine. However, there is one caveat. You still need a Mac to act as the build host to compile your iOS application. This is because Xamarin.iOS uses the same compiling, code signing, and app publishing tools as XCode. These are all required in order to build a iOS application. In addition, Xamarin Studio and Visual Studio still need to deploy your app to the iOS Simulator. The iOS Simulator is an Apple tool that only is available on a Macintosh. You use the iOS Simulator to debug your application without having to have an actual iPhone, iPod Touch, or iPad.
If you plan to use Visual Studio to develop iOS applications, you generally have two options. You can have separate physical machines: One Mac, and one Windows PC. The Mac will act as the build host, and the Xamarin Visual Studio plug-in will communicate with the Mac Build Host as long as both machines are on the same wifi network. When you debug your app using the iOS Simulator, the Simulator launches on the Mac, not on the Windows PC. So you will have to switch over to the Mac in order to interact with your application, and back to the Windows PC to debug your code.
The second option is to run a Windows Virtual Machine on your Mac. The two most popular applications for creating a Windows VM on a Mac are VMWare’s Fusion and Parallels. The Windows VM can communicate with the Mac Build Host via networking. I prefer this method as I can develop iOS apps using Visual Studio without having to switch to different machines when debugging my app on the iOS simulator. For more information on connecting Visual Studio with the Xamarin Build Host, see the Xamarin documentation.
It is also worth nothing that you can not develop Xamarin.iOS applications with Xamarin Studio for Windows like you can with Xamarin Studio for Mac. So if you’re developing on Windows, your only choice is Visual Studio.
Pro Tip: Before you install the latest version of Xamarin Studio, make sure you install the latest version of XCode from the Apple App Store. The latest major version of Xamarin Studio must work with the latest major version of XCode. If the versions are not in sync, it can cause installation issues and cryptic error messages when trying to compile applications. Save yourself future headaches and perform this easy step before installation.
Though the iOS Simulator generally is useful when developing and debugging your application, it is highly recommended that you test your application on actually iOS devices. Apps running on the iOS Simulator may behave differently than on devices. Plus, when you submit your app to the App Store for approval, your app will be tested on real devices. So it is imperative that you test on real devices early, and often.
However, Apple makes it a little bit of a pain to debug and test on iOS devices. I also want to emphasis that this is a Apple’s doing, and not Xamarin. In order to deploy your application on an iOS device for debugging, you need to create a provisioning profile that is signed by a developer security certificate. This whole process is beyond the scope of this article, but in order to do this, you need to join the Apple Developer Program. The Apple Developer program costs $99 USD a year, so you’ll need to take that into account as an extra cost. You can create Individual Accounts or Company Accounts. Both cost the same, but with Company accounts, you can add multiple developers to the account, so that each developer does not have to pay $99 USD a year in order to debug on devices.
I hope this has given you a more detailed description on how Xamarin.iOS is architected and works. As I stated earlier, I feel it is important to know how Xamarin.iOS projects are compiled and how Xamarin.iOS relates to the iOS SDK before you start coding. But here are some key points to remember:
- Xamarin.iOS Projects use C# via the Mono Framework and Xamarin.iOS to create an iOS application.
- The Mono Framework is an open source implementation of the .NET Framework that works on Windows and non-Windows platforms.
- Not every .NET class is available in Mono. Only those that are not specific to the Windows operating system.
- Xamarin.iOS is a C# bindings (wrapper) to the iOS SDK (Objective-C).
- The bindings also includes wrappers that make the iOS SDK more “.NET Friendly”.
- Xamarin.iOS applications are compiled Ahead-of-Time (AOT).
- You ALWAYS need a Mac to develop iOS applications. Even if you’re developing on Windows with Visual Studio.
- Test and debug on real devices early, and often. As you’ll learn, your app can behave differently on iOS devices than on the iOS Simulator. Trust me on this.
As always, feel free to send me an email, or leave a comment below. Also, if you think your friends or colleagues will find this interesting, feel free to share it with them by using the share options below.