Bindings, Bindings, Bindings!! Part1

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:

  • An Objective-C static 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

cat_3

This post is comes in two parts

  1. This entry contains how to create an Objective-C Static Library from Objective-C source code
  2. 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 …

From Wikipedia

Generally in iOS ecosystem you can find libraries in 3 flavors:

  • As a precompiled static library file with .a extension 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 .framework extension. ie. Google’s AdMob Library.
  • As just source code files .m and .h (.mm for 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).

Bindings1

Now open XcodeXcode6

Select File -> New -> Project…

Bindings2

Now select Cocoa Touch Static Library and click Next

Bindings3

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.

Bindings4

Select a folder location for your project and click create. Your screen now will look like this

Bindings5

Now select MBProgressHUD.h that is at your left sidebar and you will see something like this

Bindings6

Now open MBProgressHUD.h that you downloaded from the internet, copy its contents and close it.

Bindings7

Paste the contents on your MBProgressHUD.h in Xcode and now it should look like this

Bindings8

Now do the same for MBProgressHUD.m

From MBProgressHUD README file it has some framework requirements:

  • Foundation.framework
  • UIKit.framework
  • CoreGraphics.framework

You must add this Frameworks to our Xcode project, to do so select Xcode project -> MBProgressHUD target

Bindings9

Then click on Build Phases

Bindings10

Click on Link Binary With Libraries arrow to expand the section

Bindings11

Click on the + icon

Bindings12

And this dialog will show up, select UIKit.framework and then click Add

Bindings13

Then repeat for CoreGraphics.framework, Foundation.framework and now your Link Binary With Libraries section should look like this

Bindings14

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

Binding15

And Change the Build Configuration under the Info tab to Release

Bindings16

Now lets build that fat library, on top left corner you will find the following controls

Bindings17

Now click on iOS Device and you will get the following drop down list. (ymmv on your iOS simulator list)

Bindings18

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

Bindings19

Now change it to any simulator and click Run Button again and you should get a Build Succeeded message too.

Bindings20

Ok, now you must find those freshly baked libMBProgressHUD.a libraries. Expand your Products folder on the left sidebar

Bindings21

Right click on libMBProgressHUD.a and choose Show in Finder

Bindings22

And you will see the following folder structure

Bindings23

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

Bindings24

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

Bindings25

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)

Bindings26

 Once opened type cd Desktop/MBProgressHUD (or your custom folder location) and hit the return key

Bindings27

Now type xcrun -sdk iphoneos lipo and hit return key and it will print all lipo options

Bindings28

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

and

xcrun -sdk iphoneos lipo -info libMBProgressHUD-sim.a

Bindings29

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

Bindings30

So now in our folder you should have our new fat library named libMBProgressHUD.a

Bindings31

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

Bindings32

So if it does, now you are able to delete libMBProgressHUD-device.a and libMBProgressHUD-sim.a from your folder

Bindings33

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!

I'm passionate by the miracle of creation! Sometimes I look at the world and can see the lines of code behind it.