Tag Archives: Xamarin.iOS

The many flavors of HttpClient

HttpClientHandler

When using Xamarin, you can use the standard .NET HttpClient. By default, HttpClient is Mono’s complete reimplementation of the entire HTTP stack. It is sufficient for many use cases but there are other alternatives out there that can be defined by selecting an alternative HttpClientHandler. For my Evolve talk, I put together an overview of the different HttpClientHandlers you can use:

HttpClientHandlers

CFNetworkHandler (iOS 6+) and the new NSUrlSessionHandler (iOS 7+, starting with Xamarin.iOS 9.8) are the handlers that utilize Apple’s native APIs instead of the Mono implementation. You can define which handler the HttpClient default constructor will use either in the IDE or by providing an argument to mtouch (e.g., --http-message-handler=NSUrlSessionHandler).

iOS options: HttpClientHandler

For Android, there is now AndroidClientHandler (starting with Xamarin.Android 6.1). There is no IDE option for defining the default handler yet but you can define it using the @(AndroidEnvironment) build action on a text file in your Android project to define an environment variable XA_HTTP_CLIENT_HANDLER_TYPE to the value Xamarin.Android.Net.AndroidClientHandler.

Alternatively, you can use ModernHttpClient by handing a NativeMessageHandler to the HttpClient constructor which will also use native implementations for making HTTP calls.

SSL/TLS

The default Mono implementation does not support the newest (and most secure) TLS standard 1.2 while the native handlers do. To use TLS 1.2 with the Mono implementation, Xamarin.iOS 9.8 introduced the option to swap the TLS implementation with P/Invoke calls into the Apple’s TLS implementation. This can be selected either in the IDE or by adding the --tls-provider=appletls option to mtouch‘s options.

iOS options: TLS

For Android, there is no such option but it is expected that BoringSSL support will be added soon.

Here’s the summary slide I showed in my talk:

HttpClient comparison

Xamarin have actually gone through the trouble of reimplementing the TLS code to support TLS 1.1 and 1.2. However, it is expected that it will be abandoned because of security considerations in favor of the native platform implementations, just as Microsoft has done for Windows.

Update (2017-02-15)

Here’s an update on the current state of HttpClient:

  • You can now specify that you want to use AndroidClientHandler your Android project’s properties page, just as you already could for iOS.
  • As expected, Xamarin have added TLS 1.2 support to the Mono (non-native) HttpClientHandler by incorporating Google’s BoringSSL into their codebase. For Android, this option is also selectable in your project’s properties page. BoringSSL also brings TLS 1.2 to the Unix/Linux implementations of Mono.
  • Contrary to my previous knowledge, ModernHttpClient does support certificate pinning using ServicePointManager. Thomas Bandt wrote an excellent blog post on how to get certificate pinning working with ModernHttpClient and even AndroidClientHandler.

And here’s the updated matrix:

HttpClient comparison

Calling C/C++ libraries from Xamarin code

The Xamarin platform allows developing iOS and Android applications entirely in C#. Sometimes, however, some legacy code may be too large or complex to make porting it to C# for your mobile app worthwhile. Most examples found online show you how to use existing Objective-C libraries in Xamarin.iOS and existing Java libraries in Xamarin.Android. However, it is entirely possible to call C code from a Xamarin app. Microsoft’s recent support for C/C++ on iOS and Android in Visual Studio can make this a simple task.

You will need the sources for the code you want to call to compile it for iOS and Android. The code cannot access any libraries which you only have binaries for that have been compiled for other platforms.

To get started, create a new C++ cross-platform project using Visual Studio 2015.
Create new cross-platform project
You will need to have the corresponding Visual Studio package installed to have this option available.
Visual Studio Setup Cross-Platform Mobile C++
This will create three projects: one for Android, one for iOS, and a shared project.
Project structure

It is important to understand the shared project concept for this. The code in the shared project does not result in a DLL or library being generated. A shared project can hold any type of file. Projects referencing the shared project can access code from any file in the shared project. The code will then be compiled in the context of the referencing project. If code is not referenced, it is not compiled. For this reason, it is necessary to have calls into all code needed contained in the platform-specific projects. This means that the platform-specific C/C++ projects need to contain code, too. This code can be identical in the Android and iOS projects and reside in the same files. Unlike in .NET projects, file linking is not needed for C++ projects; source code files do not have to reside inside a project’s folder or subfolder.

In the example, I’ve created a simple function clib_add_internal() that add two integers and resides in the shared project.


This code is called from a function in the platform-specific projects.

For the example code, this doesn’t make any sense. For a real project, you will put any call that needs to be directly invoked from the .NET code (your interface) into the platform-specific projects while underlying code can reside in the shared project.

The calls from .NET will be using P/Invoke since C++/CLI is not available on iOS or Android. So the basic P/Invoke rules apply for your interface’s code: Either the code is plain C or, if you are using C++, the calls are either plain functions or static methods and contain only POC parameters and return values.

For the iOS project, the output format needs to be changed to a static library (.a file) since iOS does not allow dynamically loading code. For Android, a dynamic library (.so) should be built.

iOS Settings
Android Settings

While the Android library can be compiled within Visual Studio, compiling the iOS library needs a connection to a build agent on the Mac. This is not the regular Xamarin.iOS installation on a Mac but a Microsoft tool that is installed on OS X using npm. Visual Studio will communicate with this tool through TCP/IP.

Connection to build host

To call the native code, create a Xamarin project for iOS and Android each. Include the native libraries in the respective Xamarin projects.

On iOS, if you’re targeting multiple processor architectures (either supporting pre-iPhone 5s or supporting the simulator), you can build the iOS project for multiple platforms using the dropdown in the toolbar. Then, combine the libraries into one using lipo according the Xamarin docs. On Android, you’ll need to modify the .csproj according to the Xamarin documentation to specify the .so files for each platform.

The calls into the native code are regular P/Invoke calls (although DLLs don’t play a role here). On Android, you specify the name of the shared library.

On iOS, use the special Mono name __Internal to call into the static library.

And that’s it! You can find the example code at https://github.com/lothrop/XamarinNative. In the example, I put the C# marshaling code into another shared project that is referenced by the Xamarin.iOS and Xamarin.Android projects.

iOS User Interfaces with MvvmCross

When using MvvmCross in a cross-platform mobile project you have the choice of four different approaches for creating the iOS user interface. Xamarin.Forms is one of those approaches that can be a good choice for many use cases (even if there is not graphical designer at this point). However, if your view has very specific visual requirements, it may be necessary to create a native view. There are three different ways you can do this:

  • Hand-coded: Create all visual elements in code. This approach is more widespread on iOS than on most other popular platforms. It gives you the advantage of having the maximum control possible over your user interface.
  • XIB files: XIB files are XML files that describe the visual elements. XIB files are typically not edited by hand but created using Xcode’s Interface Builder. Since Xamarin 4, XIB files can also be visually created and modified in Xamarin Studio or Visual Studio.
  • Storyboard files: This is the newest approach. Storyboards are also XML files visually edited with Xcode, Xamarin Studio, or Visual Studio yet they contain not only a single view but a series of views along with the workflow to navigate between these views.

MvvmCross supports all three native approaches.

Hand-coded

This approach obviously produces the most code. It may be challenging for people new to the platform but it saves you the hassle of battling with the UI designers.

XIB files

If you’re already on Xamarin 4 and prefer a visual editor, this is likely the best choice for you. Create a new XIB View Controller file using Xamarin Studio or Visual Studio. The ViewController code will also be created for you. All you need to do for MvvmCross is to change the base class from UIViewController to MvxViewController. In the example, three UI elements were created using the designer and were given the (not so creative) names UiLabel, UiTextField, and UiButton. These elements are then referenced in the data binding code that is common to all three approaches.

Setting element names

Storyboard files

The big advantage of storyboards, the ability to design your screenflow in the designer, does not fit well with MvvmCross’s cross-platform navigation approach. If you define a transition from view A to view B in the designer it will only apply to the iOS platform. It is typically a better idea to move this navigation logic down into the cross-platform code inside your ViewModels. That is why it’s best to use a one-ViewController-per-storyboard approach when using storyboards in MvvmCross.

Setting the storyboard ID

In the editor, you need to set the storyboard ID to the name of your ViewController. As with the XIB approach, change the base class from UIViewController to MvxViewController. Create a constructor taking an IntPtr and passing that on to the base class’s constructor. The last step is to add the [MvxFromStoryboard] attribute to the class.

Summary

The good thing is: You don’t have to make this decision at project start. MvvmCross supports implementing your view with the technology that is best for each view. You only need to ensure you don’t have multiple views for the same ViewModel and the same platform.

I’ve updated the example in the MvvmCross Starter Pack Nuget (starting with 4.0.0-beta8) to use a XIB file instead of the previous hand-coded approach with absolute coordinates (from the auto layout days). That should make it easier for people to get started.

Making your iOS views scrollable

If you’re using iOS auto layout (you should) and you’ve ever tried to add a scroll view in Interface Builder or the Xamarin iOS Designer you might have noticed that it is not an easy task. If you’re interested, here are some instructions. This is especially true if you only realize that you need a scroll view after designing your view (after you’ve realized that the keyboard covers up parts of the view).

Here’s code to inject a UIScrollView at runtime to solve all your worries. Add this code to your base UIViewController for all controllers that should be vertically scrollable.

In Interface Builder or Xamarin iOS Designer you’ll need to make sure you’ve not only defined constraints for the vertical position of your elements but also a constraint to define the distance from the bottom of the bottom element to the bottom of the your view controller’s view. That way, you’ll have defined the vertical size of the scroll view’s content view.

Unified API: 64-bit support for Xamarin.iOS

There’s a deadline coming up for all iOS developers. Starting February 1, 2015, all apps and app updates submitted to the iOS app store must be built against the iOS 8 SDK and must include 64-bit support. While this is more of a routine update procedure for Objective-C developers, it has deeper implications for Xamarin.iOS developers.

The original design of the MonoTouch API chose to use some of the builtin .NET types, such as System.Int32 (int), System.Single (float) and RectangleF. Unfortunately, these types are all either 32-bit types or consist of 32-bit types. What is needed now, though, is a type that is 32-bit on 32-bit platforms and 64-bit on 64-bit platforms.

For this reason, Xamarin introduced a breaking change that will affect all Xamarin.iOS developers. The good news is that they are using the opportunity to fix a few issues with the old API. If you’re interested in all the changes, there is an Evolve session by Miguel de Icaza available.

The new Unified API comes as an assembly called Xamarin.iOS.dll instead of the old monotouch.dll. It replaces the old numeric types as follows:

old new
System.Int32 (int) System.nint
System.UInt32 (uint) System.nuint
System.Single (float) System.nfloat
System.Drawing.PointF CoreGraphics.CGPoint
System.Drawing.SizeF CoreGraphics.CGSize
System.Drawing.RectangleF CoreGraphics.CGRect

Projects using the new Unified API need to use a new project type.

Unified API

From within the new project types, you can’t reference Classic API projects.

The word “Unified” in Unified API comes from Xamarin’s attempt to facilitate code sharing for iOS and Mac projects. This is also the reason the namespace MonoTouch was dropped entirely, making it possible to share some code between the two platforms that needed to have platform-specific implementations previously, e.g, through Shared Projects.

Updating your existing projects from Classic API to Unified API can be done by hand or semi-automated. Xamarin has published instructions for the manual steps as well as the automatic update script or update feature integrated in Xamarin Studio.

I’ve updated the iOS code in MvvmCross to the Unified API. Here are some of the things I stumbled across while porting the code.

  • A few method names were fixed (e.g., UINavigationController.PopViewControllerAnimated() is now UINavigationController.PopViewController(), CGContext.SetRGBFillColor() is now CGContext.SetFillColor(), NetworkReachability.SetCallback() is now NetworkReachability.SetNotification()).
  • Some methods with callbacks were replaced with awaitable versions.
  • Some deprecated methods were removed.
  • The new numeric types look like builtin types but don’t behave like builtin numeric types (e.g., they can’t be const, you can’t use System.Math.Max() on them, etc.).
  • MonoTouch.Foundation.NSAction seems to have been dropped in favor of System.Action.

Xamarin’s current stable channel contains a preview for the Unified API. The final version is expected to hit the alpha and beta channels by early December 2014. Every existing Xamarin.iOS project will need to be updated if submitted to the App Store after February 1, 2015. It’s time to start looking at updating your projects.

Update January 18, 2015:

  • The iOS Unified API is now available on the stable channel.
  • In the meantime, Apple has further detailed its announcement regarding the submission deadline: The February 1 deadline only applies for new apps. Updates for existing apps can still be submitted as 32-bit before June 1, 2015.
  • There have been breaking changes between Xamarin’s prerelease version Xamarin.iOS 8.4 and the final version 8.6.
  • Xamarin has provided the class System.NMath for arithmetic operations on the new types nint, nuint, nfloat.
  • To submit to the app store, the app will need to also be built against for the ARM64 architecture. This can currently only be set using Xamarin Studio or directly in the .csproj file for Visual Studio users.

DWX14 Follow-up: Introduction to Xamarin and MvvmCross


At this year’s Developer Week in N├╝rnberg I held a talk on cross-platform development using Xamarin and MvvmCross. I had a lot of fun with the live coding and enjoyed answering the questions.

My slides can be found on Slideshare in English and German. The code from live coding I created with the big help of Ninja Coder is up on GitHub.

An in-app status bar for Xamarin.iOS and MvvmCross

For an iPad app for our customer Smart Enterprise Solutions we wanted to display multiple messages to the user. These messages were mainly feedback from a business logic layer that communicated with a backend. The messages should be visible inside the app. Some messages needed to be confirmed by the user while others needed to disappear after a defined timespan.

This final status bar looks like this:

StatusBar

The code is available at https://github.com/lothrop/StatusBar.iOS.

The status bar view is called StatusView. To use StatusView, use auto-layouts to snap it to the left, right and bottom of your screen. StatusView is backed by the ViewModel MessageViewModel. MessageViewModel contains an ObservableCollection<IMessageItem>. You can insert items at any point in the collection, remove items or move items within the collection.

For a usage example, take a look at the MainViewController.cs file.

A big thanks to Smart Enterprise Solutions for letting me publish the code.

Animation fun with UIView.AnimateAsync()

Xamarin.iOS 6.4 brought async/await support to iOS devices. Apart from supporting the idiom with the Mono 3.0 compiler, Xamarin also invested into adding awaitable versions of all long-running calls in Apple’s iOS API. One of my favorites is

UIView.AnimateAsync()

taking an Action or lambda to animate asynchronously without blocking the UI thread.

The fun begins when you use this to chain animations. Here’s an example of doing a horizontal shake animation that could be used to indicate an invalid entry: