Bindings Bindings Bindings!! (Part 1)
Xamarin.iOS by itself is amazing, you have full access to iOS CocoaTouch libraries, the flexibility and elegance of a modern language like C# (or a functional one like F# and even VisualBasic), the power of the .NET Base Class Library (BCL) just to mention some of its features, but that doesn’t mean that in order to get all of this awesomeness you have to sacrifice all good 3rd party Objective-C libraries out there (mostly on CocoaPods) or your previously written ObjC code. You need Xamarin.iOS Bindings.
So Xamarin.iOS Bindings huh? What’s the deal?
Let’s say you found a great
Objective-C library that will make your life easier and will make you App look amazing.
Xamarin.iOS offers a way to use 3rd party Objective-C libraries and it is just mind blowing, all you need is the following:
Objective-Cstatic library (aka. libXyz.a file or a Foo.framework, I will cover Frameworks in a future blog post)
- An iOS Binding Project (Xamarin Studio)
- A cup of coffee or your favorite beverage.
- Having Binding Objective-C Libraries document open (Please do Read it!).
On this post I’m going to show you how to create a Xamarin.iOS Binding from the very beginning to the end using an awesome ObjC library named MBProgressHUD, it is an iOS drop-in class that displays a translucent HUD written by the great Matej Bukovinski. I must warn you, this might be a long blog post because I did not want to miss anything. I hope you enjoy this blog post as much as I did writing it!
Let’s get started
This post is comes in two parts
- This entry contains how to create an Objective-C Static Library from Objective-C source code
- The second part (coming soon) will show you how to create a Xamarin.iOS Binding Project using the static library and walk you through all the necessary steps to get that shiny assembly containing everything.
…If you already have a static library you might want to skip this steps and jump directly to the second part (coming soon)…
The Objective-C Static Library
You need a
CocoaTouch Static Library
In computer science, a static library or statically-linked library is a set of routines, external functions and variables which are resolved in a caller at compile-time and copied into a target application by a compiler, linker, or binder, producing an object file and a stand-alone executable. This executable and the process of compiling it are both known as a static build of the program …
Generally in iOS ecosystem you can find libraries in 3 flavors:
- As a precompiled static library file with
.aextension together with It’s
header(s)[.h files] ie. Google’s Analytics Library
- As a precompiled
Framework.In plain english It’s just a folder containing the static library, headers and sometimes additional resources with
.frameworkextension. ie. Google’s AdMob Library.
- As just source code files
.mmfor Objective-C ++) ie. MBProgressHUD.
On the first and second scenario you already have a precompiled CocoaTouch Static Library so I will focus on the third scenario.
Creating a CocoaTouch Static Library From Source Code
I will use MBProgressHUD as example on this post, but should be almost the same procedure for most Objective-C libraries distributed as source.
First go and grab a copy of MBProgressHUD, just click on Download Zip button. You should get the following folder structure or alike (I am using version 0.9.1 at the time of writhing this).
Now open Xcode
Select File -> New -> Project…
Now select Cocoa Touch Static Library and click Next
Select a name for your static library, in this case I will pick the same name of the library I will bind
MBProgressHUD and click Next.
Select a folder location for your project and click create. Your screen now will look like this
Now select MBProgressHUD.h that is at your left sidebar and you will see something like this
Now open MBProgressHUD.h that you downloaded from the internet, copy its contents and close it.
Paste the contents on your MBProgressHUD.h in Xcode and now it should look like this
Now do the same for MBProgressHUD.m
From MBProgressHUD README file it has some framework requirements:
You must add this Frameworks to our Xcode project, to do so select Xcode project -> MBProgressHUD target
Then click on Build Phases
Click on Link Binary With Libraries arrow to expand the section
Click on the + icon
And this dialog will show up, select UIKit.framework and then click Add
Then repeat for CoreGraphics.framework, Foundation.framework and now your Link Binary With Libraries section should look like this
Ok all set, but before going any further you must be familiar with a Fat Static Library concept but… What’s that? Let’s do a little of research here.
All iOS devices have processors powered by ARM Architecture and it comes in a few different versions developed over time, each one added new instructions and other improvements while being backwards compatible with the previous versions. On iOS devices we have armv6, armv7, armv7s, arm64 instruction sets, the iOS simulator is not powered by ARM it is a x86 and x86_64 powered simulator. So you must provide libraries on each instruction sets.
Yes this means that you will have a libMBProgressHUD.a for each architectures you want to support. But don’t worry Apple already silently dropped support for armv6 and also armv7s even more silently. Xcode Automagically creates armv7 and arm64 in one shot and i386 and x86_64 are just a click away.
But you might be wondering “hey but What is a Fat Static Library? You have not answered that question”… Yes you are right, a Fat library It’s just
.a file containing all supported architectures. Yes in the end you will have a single libMBProgressHUD.a containing armv7, armv64, i386 and x86_64 archs instead of having 4.
First we need to change our build to Release we do this by clicking Product -> Scheme -> Edit Scheme
And Change the Build Configuration under the Info tab to Release
Now lets build that fat library, on top left corner you will find the following controls
Now click on iOS Device and you will get the following drop down list. (ymmv on your iOS simulator list)
If you select iOS Device and build the project you will build an armv7 and arm64 library, if you select any simulator and build the project you will have a i386 and x86_64 library.
So select iOS Device and click Run button and you should get a Build Succeeded message
Now change it to any simulator and click Run Button again and you should get a Build Succeeded message too.
Ok, now you must find those freshly baked libMBProgressHUD.a libraries. Expand your Products folder on the left sidebar
Right click on libMBProgressHUD.a and choose Show in Finder
And you will see the following folder structure
As you might have guessed libMBProgressHUD.a inside Release-iphoneos is the armv7/arm64 archs and libMBProgressHUD.a inside Release-iphonesimulator is the i386/x86_64 archs. Now lets build that Universal Fat Library
So rename libMBProgressHUD.a inside Release-iphoneos to libMBProgressHUD-device.a and libMBProgressHUD.a inside Release-iphonesimulator to libMBProgressHUD-sim.a so you will have something like this
Now create a folder in your Desktop (or your favorite location) called MBProgressHUD and copy both libMBProgressHUD-sim.a and libMBProgressHUD-device.a to it, also copy the MBProgressHUD.h file located under include -> MBProgressHUD we will use it later. You will have something like this
In order to create the a Fat Library you must use a command line tool called lipo, you must have the Xcode Command Line Tools installed in your system (If you don’t please grab them here make sure you pick the right one according to your Xcode and OS X version).
If you made it this far you can close Xcode now 😉
Now Open Terminal.app, you can do it using Spotlight by using (cmd + space bar)
Once opened type
cd Desktop/MBProgressHUD (or your custom folder location) and hit the
xcrun -sdk iphoneos lipo and hit
return key and it will print all lipo options
So lets verify that we have armv7, arm64 and i386, x86_64 archs in libraries, run the following commands
xcrun -sdk iphoneos lipo -info libMBProgressHUD-device.a
xcrun -sdk iphoneos lipo -info libMBProgressHUD-sim.a
So in the output you can see that we have the desired architectures armv7, arm64 and i386, x86_64 listed, so in order to build our Fat library you should enter the following line
xcrun -sdk iphoneos lipo -create -output libMBProgressHUD.a libMBProgressHUD-device.a libMBProgressHUD-sim.a
So now in our folder you should have our new fat library named libMBProgressHUD.a
So lets check that it actually contains armv7, arm64 and i386, x86_64 architectures by running the following command
xcrun -sdk iphoneos lipo -info libMBProgressHUD.a
So if it does, now you are able to delete libMBProgressHUD-device.a and libMBProgressHUD-sim.a from your folder
So at this point you got what you need in order to begin with the Xamarin.iOS Binding Project Hoooorraay.
Please stay tuned for the second part of this series, if you can’t wait just head to the Xamarin.iOS Binding Objective-C Libraries Docs!