Categorized | Code, iOS

Using TestFlight SDK with MonoTouch

When developing applications getting reliable and good feedback and information from your testers is vital to the quality of the application you are creating. A great tool that can help you with this as an iOS developer is TestFlight.

If you are unfamiliar with TestFlight check their website for detailed information, but in short; it is the easiest way to distribute beta builds of your application to your testers. In addition to distribution TestFlight has an SDK that you can implement in your code to track  usage and states in your application. With the SDK you can also ask the user questions that is related to a checkpoint, or also ask for general feedback. This can be implemented per view or for the whole application. The TestFlight SDK also has a log feature where you can for instance in your error handling automatically upload exception messages. Global application crashes is automatically logged to TestFlight.

Getting the SDK to work when you are using Objective-C and Xcode is easy, but as a MonoTouch/iOS developer using MonoDevelop it is a bit more tricky, not much but a little bit. Following is a step by step guide  on how you can use I use it and find it useful.

The guide assume you already have MonoDevelop installed with MonoTouch. If you just want to test the version i have created to see the question and feedback windows you can download my sample app on here:

You can also download the sample app source code from here.

1. MonoTouch bindings for TestFlight

The first thing you will need is the MonoTouch TestFlight binding library. Download that to you computer from

2. TestFlight iOS SDK

Download the TestFlight SDK zip file to your computer from

3. Create your TestFlight.dll library

When the download is complete, copy or move the zip file with the SDK to the “binding” folder inside the MonoTouch library you downloaded in the first step. then open a Terminal window and navigate to the same binding folder. Once there just run the command “make”.  The “make” command creates a TestFlight.dll file that you will use in your application.

4. MonoDevelop

Open or switch to MonoDevelop and create a new MonoTouch iPhone application and add a reference to the TestFlight.dll file you just created.

One that TestFlight uses is the uniqe device identifier (UDID).This has been deprecated as of iOS 5 so be sure to NOT include references to that in the version you plan to submit to the AppStore! But for  identifying devices in betatest it’s great! Some parts of TestFlight can also be used in live applications like the TestFight.Log(string message); feature, that you can use in case of errors in live applications, The feedback windows can also be useful if you haven’t created you own feedback system.  So, there’s only one way to have some code compile for release and some at other times and that is by using debug symbols like this

      // Some code to execute when the debug symbol is hit.
      // Other code to execute when the DEBUG symbol 
      // isn't present (for instance in RELEASE)

In my projects I always have at least three different configurations. Debug, Release and TestFlight. Debug I use while developing, Release for uploads to AppStore and TestFlight for uploads to TestFlight. To create a configuration for your app solution (that will apply to all projects in the solution) right-click on the solution and select options, then choose build -> Configurations. Add a configuration called TestFlight (or any other name you choose). If you have more than one project in your solution that the main app project depends on remember to set the configuration mapping too.

Secondly you need to configure the TestFlight Configuration. Right click on your project and choose Options. I always use the same configuration as for Debug since there’s no real difference except that I will upload this. There are two options you need to configure for the TestFlight configuration. under Build -> iPhone IPA Options you need to check the “Build ad-hoc/enterprice package (IPA), and create the debug symbol by going to Build -> Compiler and type “TESTFLIGHT;” without quotes. If you already use a DEBUG; symbol in your code you can append that here by typing “DEBUG;TESTFLIGHT;”, then all code that is marked for compiling while debug will also be compiled in the TestFlight build.

You can now use this in your code.

      // Some code to execute when the debug symbol is hit.
      // Other code to execute when the DEBUG symbol 
      // isn't present (for instance in RELEASE)

5. Development

The IDE is configured and you have the library, it’s time for implementation. This guide is how I have implemented it. It works and like this way of doing it, but I don’t know if it’s the best way or smartest way of implementing it so if anyone has suggestions for improvements I’ll be happy if you let me know.

The first thing I do is to Identify the device and start the TestFlight session by calling TakeOff. I do that in the Main.cs file.

static void Main (string[] args) {
      try {
         UIApplication.Main (args, null, "AppDelegate");
      catch(Exception ex) {
          TestFlight.Log("Unhandled Exception:" + ex.Message);
          // rethrow to resume normal action on unhandeled exceptions......
          // app crash...

So, here we use the TESTFLIGHT symbol to only use the UIDevice.CurrentDevice.UniqueIdentifier when we build for TestFlight. If this code is used in the release and uploaded to AppStore it will be rejected and we don’t want that. It is important to notice that if you use the SetDeviceIdentifier you can only distribute your app to testers defined as members in your TestFlight team. That means that you cannot distribute it to anonymous testers.

I have also surrounded the  load of AppDelegate with a Try/Catch to handle any errors that may bubble all the way up and crash my app. Things that I should have caught earlier in code. Now I at least have a mechanism to capture it and tell me and that is very useful.

Other methods we use in the TestFlight library is PassCheckpoint(string), Log(string) and OpenFeedbackView().

The PassCheckpoint method is used to tag events in your app that the user reaches. It could for instance be when a button is pressed or a view is loaded.

TestFlight.SubmitFeedback(string feedback)

This can be used in live apps to gather user feedback.
MonoDevelop has full support for direct upload of apps to TestFlight and have a good guide on how to do it here Uploading to TestFlight is as easy as compiling.
How you use the TestFlight web site is an article for later so until then, play around and you’ll figure it out.


Use Facebook to Comment on this Post

Comments are closed.