React to changes of focus in your Xamarin.tvOS applications

The focus engine introduced in UIKit for tvOS 9.0 is one of the key concepts you should know if you want to develop applications for the Apple TV.

It allows you to know what is the control that is currently focused on the screen, and to be notified when the focus changes from a view to another view (e.g. from a textfield to a button, from a collection view cell to the next cell, etc…).

Today I have created my first and simple application that uses a UICollectionView with few cells as you can see on the screenshot below. I was proud of my work until I realized that when the application is running, there is no visual indication that gives a feedback to the user of which cell is currently selected (cell #0 or cell #1).

tvOS - CollectionView without focus

I then looked for solutions to surround the focused cell with a white border to give an instant feedback to the user. The focus engine gives you this capability through the DidUpdateFocus method.

This method exposes a context to retrieve which views are focused (the previous and the next), and an animation coordinator to change attributes of these views within an animation.

When you know this method, it is very simple to accomplish your goal. The example below shows you how to remove the border for the old focused view, and add a border for the new focused view.

public override void DidUpdateFocus(UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
{
  base.DidUpdateFocus(context, coordinator);
  coordinator.AddCoordinatedAnimations(() =>
  {
    if (context.PreviouslyFocusedView != null)
    {
      var previousCell = (UICollectionViewCell)context.PreviouslyFocusedView;
      previousCell.Layer.BorderColor = UIColor.Clear.CGColor;
      previousCell.Layer.BorderWidth = 0;
    }

    if (context.NextFocusedView != null)
    {
      var nextCell = (UICollectionViewCell)context.NextFocusedView;
      nextCell.Layer.BorderColor = UIColor.White.CGColor;
      nextCell.Layer.BorderWidth = 5;
    }
  }, null);
}

The visual feedback is now more understandable for the user and he knows that the currently focused view is the cell #1.

tvOS - CollectionView with border when focused

It is good but if I want to have the same feature that is standard on the Apple TV (the cells sizes increase/decrease when they are focused/unfocused), what I need to do ?

If your cell is only composed with an UIImageView, you can select the option called “Adjusts image when focused” on the properties of this view in Xcode.

tvOS - ImageView adjusts image when focused

But when your cells are more complex like the sample below (each cell is composed with an UIImageView, a translucent UIView with a UILabel above), then you probably want to increase the size all the items inside the cell at the same time.

tvOS - CollectionView with scale when focused

No problem to achieve this goal with the same method that was previously mentioned. We just need to apply a transformation to the cell (CGAffineTransform.MakeScale(…)) when it receive the focus, and revert it (CGAffineTransform.MakeIdentity()) when the focus is lost.

public override void DidUpdateFocus(UIFocusUpdateContext context, UIFocusAnimationCoordinator coordinator)
{
  base.DidUpdateFocus(context, coordinator);
  coordinator.AddCoordinatedAnimations(() =>
  {
    if (context.PreviouslyFocusedView != null)
    {
      var previousCell = (UICollectionViewCell)context.PreviouslyFocusedView;
      previousCell.Transform = CGAffineTransform.MakeIdentity();
    }

    if (context.NextFocusedView != null)
    {
      var nextCell = (UICollectionViewCell)context.NextFocusedView;
      nextCell.Transform = CGAffineTransform.MakeScale(1.25f, 1.25f);
    }
  }, null);
}

As we have seen in this article, it’s pretty easy to interact with the focus engine of tvOS to apply any modifications on views, depending on the focus state of each of them.

Issue in the Xamarin.iOS binding library for Google Ads

This week, I had to work about an issue around the integration of Google Ads into a Xamarin.iOS application.

To integrate Google Ads in your application, Xamarin has published a binding library above the official iOS SDK (written in Objective-C). This library is available as a NuGet package.

After adding the package in your project, it’s very easy to use and in just few lines of code, you can create a search request and retrieve ads matching your criteria. The sample code below shows you how to achieve that (it has been simplified for brevity).

var request = new SearchRequest();
request.Query = "Xamarin Mobile Development";

var banner = new SearchBannerView(...); 
banner.LoadRequest(request);

Unfortunately, with the actual version of the NuGet package, this code won’t compile. The error is on line with the LoadRequest statement.

After some investigations, I’ve discovered the source of the problem. If you look at the official iOS SDK, you can see declarations like this :

@interface GADRequest : NSObject<NSCopying>
@interface GADSearchRequest : GADRequest

The GADSearchRequest class (aka. interface in the Objective-C terminology) inherits from the GADRequest class.

But if you look the source code of the binding library available on GitHub since few weeks (Xamarin has announced at Evolve 2016 that a lot of components are now open-source), you can see these declarations :

[BaseType(typeof(NSObject), Name="GADRequest")]
interface Request : INSCopying

[BaseType(typeof(NSObject), Name="GADSearchRequest")]
interface SearchRequest

As you can see, there is a difference compared to the official SDK, because the BaseType of the SearchRequest class is equal to NSObject rather than Request.

I’ve downloaded, modified and recompiled the source code with the following modification.

[BaseType(typeof(NSObject), Name="GADRequest")]
interface Request : INSCopying

[BaseType(typeof(Request), Name="GADSearchRequest")]
interface SearchRequest

With this simple modification, the LoadRequest statement is good and now, I’m able to compile and test the application successfully.

This issue has been submitted on GitHub and the pull request is waiting for approval.

In conclusion, if you encounter some compilation errors like this one (in this library or any other), take a look to the official SDKs, and compare the declarations with the binding library to ensure that everything is good.

How to remove the IOHIDLibFactory error when you start your Xamarin.iOS application in the simulator

When you will develop Xamarin.iOS applications, you will use the iOS simulator to test your application without having to use a real device like an iPhone or an iPad.

In Xamarin Studio (like in Visual Studio), the output window gives you some useful information to help you to debug your application (e.g. when you use Console.WriteLine(…) to print values).

When you start your application in the iOS simulator, it might happen that you see a lot of errors like this :

Error loading /System/Library/Extensions/IOHIDFamily.kext/Contents/PlugIns/
IOHIDLib.plugin/Contents/MacOS/IOHIDLib: dlopen(/System/Library/Extensions/
IOHIDFamily.kext/Contents/PlugIns/IOHIDLib.plugin/Contents/MacOS/IOHIDLib, 262):
no suitable image found. Did find: /System/Library/Extensions/IOHIDFamily.kext/Contents/
PlugIns/IOHIDLib.plugin/Contents/MacOS/IOHIDLib: mach-o, but not built for iOS simulator

Or also :

Cannot find function pointer IOHIDLibFactory for factory 13AA9C44-6F1B-11D4-907C-0005028F18D5 in CFBundle/CFPlugIn 0x7be04110 </System/Library/Extensions/
IOHIDFamily.kext/Contents/PlugIns/IOHIDLib.plugin> (bundle, not loaded)

It’s not a problem for your application and has no impact on it, but it’s often annoying to have a lot of errors in the output window, each time you start your application.

If you want to remove these errors, you just have to edit your iOS build settings, and change the linker behavior value from “Don’t link” to “Link Frameworks SDKs Only“.

Xamarin Studio - iOS Build Settings

Note that activating this option will increase the compile time of your application because the linker will have more work to do to generate your package.

[French] Integrate and use HockeyApp into your Xamarin applications

At the end of 2014, Microsoft has announced the acquisition of HockeyApp, a class leading service for mobile crash analytics and app distribution for developers building apps on iOS, Android, Windows Phone, Windows, OS X, etc…

Last week at Evolve 2016, the annual event about Xamarin products and technologies, some announcements were made and one of them concerns the first improvements integrated in HockeyApp, after the acquisition of Xamarin by Microsoft, earlier in March 2016.

If you speak french and re interested to discover what’s HockeyApp and how to integrate the service into your Xamarin applications, take a look at my new video available on Channel 9.

Introducing the new HttpClient implementation in Xamarin.iOS

In the upcoming days/weeks, Xamarin will release a whole set of new versions for its products to develop cross-platform mobile applications.

One of the most important (from my perspective) is Xamarin Studio 6.0 which will include lots of new features. If you want more information about those features, you can find a complete list on this page.

Today, I would like to talk about one of them which allows you to choose which implementation you want to use for network communications for your application iOS.

When you want to write cross-platform mobile applications, you avoid to use platform-specific APIs such as NSURLSession in iOS. Instead, you will prefer to use APIs that are available on all platforms such as the HttpClient class available in the .NET framework.

While this solution has many benefits for reusing your code on all platforms, the performance is worse than using specific API to the platform.

Fortunately, Xamarin Studio 6.0 (available on the Beta channel at this time) will introduce an option to use the underlying native APIs (NSURLSession, CFNetwork…) above HttpClient.

To activate this option, you just have to edit your Xamarin.iOS project settings and to go to the iOS Build section. On the screenshot below, you can see that 2 new options are available :

  • HttpClient Implementation
  • SSL / TLS Implementation

By default, your project will use the .NET implementation but you can switch to native APIs.

Xamarin Studio 6.0 - Choose your HttpClient implementation

There are many choices available and if you want more details, leave your cursor on the “blue I” on the right side of the selection lists. Below, the details about choices available for the HttpClient implementation.

Xamarin Studio 6.0 - HttpClient implementation tooltip

As mentioned in this tooltip, the usage of native APIs will result of better performance, support for latest standards (e.g. TLS 1.2) and smaller executable size.

[French] Configuring Visual Studio 2015 to develop Xamarin.iOS applications

As Microsoft MVPs, we have opportunities to collaborate with Microsoft teams and we have access to a lot of resources and tools which are not available to the general audience.

Today, I’m proud to announce that my first screencast (and certainly not the last) was published on Channel 9, the official Microsoft video portal for developers.

If you speak French (yes it’s my native language) and are interested by Xamarin development, you can discover how to configure your Visual Studio 2015 development environment to develop iOS applications.

Broadcast messages over the network from your Xamarin application

Since few days, I think and look for the best technical solutions to create a new tool to include in my mobile application development toolkit.

This tool requires, when a mobile application (let’s call it client) starts/stops on a device in the same network as my development machine, to send information over the network, to inform other applications (let’s call them listeners) that a new client is started and available on the network.

The “classic” way to achieve this goal is to create a webservice, an call it when the application starts/stops. It’s easy to do but in that case, it’s necessary to store the data sent over the network (e.g. a device identifier), and the listeners need to poll the webservice, to detect new clients.

It’s a good solution in some cases, but not what I want for my tool. I prefer to be notified in real-time when a new client is started/stopped and I don’t want to create a database to store information about clients (in-memory storage is enough).

Then I remembered that it’s possible to broadcast messages over the network through UDP (User Datagram Protocol).

Let’s take a look to this solution to check if it works with Xamarin.

UDP protocol / UdpClient class

UDP is a transport layer protocol defined for use with the IP network layer protocol. This is an unreliable service that provides no guarantees for delivery, packets order and no protection as TCP does (e.g. send an acknowledgment after that a packet was sent and received over the network, otherwise retry to send it). The simplicity of UDP reduces the overhead from using the protocol and the services may be adequate in many cases.

To use UDP from a .NET / Xamarin application, wether to create clients or listeners, the .NET framework offers an UdpClient class which covers all the needs (send, receive, broadcast, multicast, etc…).

Enough of theory, let’s go to the code:)

Create a simple UDP listener in C#

To test that we can use UDP from a Xamarin application, we first need to create a listener that will receive the messages sent by the application. To do this, I created on a PC, a console application with the following code :

using System;
using System.Net.Sockets;
using System.Text;

namespace UdpListenerDemo
{
  class MainClass
  {
    public static void Main(string[] args)
    {
      var listener = new UdpListener();
      listener.StartListening();
      Console.ReadLine();
    }
  }

  class UdpListener
  {
    private readonly UdpClient _udpClient = new UdpClient(15000);

    public async void StartListening()
    {
      while(true)
      {
        var result = await _udpClient.ReceiveAsync();
        var message = Encoding.ASCII.GetString(result.Buffer);
        Console.WriteLine(message);
      }
    }
  }
}

This console application will listen for all messages sent over the network through UDP, on port number 15000. When a message is received, it’s printed in the console.

Send messages over the network from Xamarin.iOS

The next part is to create a Xamarin application (a client) that will send messages over the network. For this part, I used the “Single View App” template and put a button on the main screen. Each time the user will tap the button, the application will send a message over the network.

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UIKit;

namespace UdpClientDemo
{
  public partial class ViewController : UIViewController
  {
    public ViewController(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
      base.ViewDidLoad();
    }

    public override void DidReceiveMemoryWarning()
    {
      base.DidReceiveMemoryWarning();
    }
 
    async partial void SendMessage(UIButton sender)
    {
      using(var client = new UdpClient())
      {
        client.EnableBroadcast = true;
        var endpoint = new IPEndPoint(IPAddress.Broadcast, 15000);
        var message = Encoding.ASCII.GetBytes("Hello World - " + DateTime.Now.ToString());
        await client.SendAsync(message, message.Length, endpoint);
        client.Close();
      }
    }
  }
}

The most important part of the code above, is the declaration of the endpoint. As you can see, we use the same port number (15000) that is declared in the listener, and we use the broadcast address instead of a specific IP address (because we don’t want to target a particular client).

For this sample, I used a Xamarin.iOS application but it also works with Xamarin.Android.

Use the listener and the client

Now that we have all the necessary parts, we can execute our Xamarin application (the client) to see if it works. As you can see on this screenshot, the interface is pretty simple.

Xamarin - UDP Client

If you tap on the “Send UDP Message” button, and if the listener is not started, nothing will happen. The message will be sent over the network but nobody will receive it.

Now if we execute the listener (our console application) then tap the button on the client (our Xamarin application), the message is sent over the network, then received and printed on the console as you can see below.

Xamarin - UDP Listener

Limitations

As we saw in this article, the solution based on UDP to broadcast messages over the network, can be used in Xamarin applications and it’s very easy to implement. But there are some limitations to understand if you use this solution.

The most important is that broadcast messages, generally don’t go through routers. It means that this solution only works if the listeners and the clients are on the same network segment.

Another limitation concerns the UDP protocol. As mentioned earlier, UDP is not reliable and it’s not guaranteed that a message will be delivered. It’s not guaranteed too, that messages are delivered in the same order where they were sent. It also may happen that a message is received many times. For all these cases, your application is responsible to react as you need.

But in my case, I just need to send a message when an application starts/stops. Because my need is very basic, this solution seems to be viable.

Signing your Xamarin.Android application package during the development phase

When you create an application using Xamarin.Android (or even if you use other tools such as Android Studio), it’s necessary to sign the application package (APK) to publish your application on the Google Play Store.

If you don’t know how how to proceed, Xamarin has published a step-by-step tutorial which explains how to achieve this goal.

This article is very useful when your application is finished, because it explains how to use the built-in tools to archive, sign and distribute your application.

But when you’re still in the development phase (e.g. to implement and test push notifications), it’s not convenient to use this workflow.

Fortunately, a more simple way to reach the same goal exist and is very easy to implement. Let’s take a look to this process.

Create a new keystore/certificate

The first step to sign an application is to generate a keystore, the container for the certificate associated to your application.

There are different ways to generate a keystore (e.g. command-line tools), but my preferred way is to use the GUI available in Xamarin Studio. To access this screen, go to Xamarin Studio > Preferences > Android Signing Keys.

Xamarin - Android Signing Keys

This screen lists all the keystores that you created on your computer. You are also able to import an existing keystore, or generate a new one by clicking to Create a new key.

When you create a new new key, you just have to complete some information on who you are (firstname, lastname, organisation…) and the security of your certificate (alias, password and validity).

Xamarin - Android Create Keystore

Once you created the new key, it’s stored in the folder ~/Library/Developer/Xamarin/Keystore/Your-Alias (if you’re using a Mac).

Sign your package with the keystore

The second (and last) step to sign your package is to associate the keystore to your project.

Once your project is open in Xamarin Studio, go to Project Options > Android Package Signing.

Check the box labeled “Sign the .APK file using the following keystore details” and fill the details with information used when you created the keystore.

If you have used the GUI to create the keystore, you probably noticed that there’s only one password value while there are 2 values (keystore password and alias password) in this screen. The GUI use the same value for both fields, but it’s possible to use different values if you use command-line tools.

Xamarin - Android Package Signing

Please note that it’s possible to use different keystores for debug and release modes. You can switch between these modes using the configuration list on the top of the dialog box.

Performing a search request with SharePoint REST API throws a Microsoft.SharePoint.Client.UnknownError

Most of Office 365 REST APIs use the OData v4.0 protocol for exchanging and formatting data between the client and the server.

When you develop an application that uses those APIs, you need to add some HTTP headers in all your requests to let the server know that you want to use this protocol version and to specify the desired verbosity of returned metadata as you can see below :

Accept: application/json;odata.metadata=minimal
OData-Version: 4.0

But if you use these HTTP headers with the SharePoint API to perform a search by calling…

POST https://tenant.sharepoint.com/_api/Search/PostQuery

… then you will receive the following error message :

{
  "error": {
    "code":"-1,
    Microsoft.SharePoint.Client.UnknownError",
    "message":"Unknown Error"
  }
}

You could be surprised because if you try to get information about a site collection by calling…

https://tenant.sharepoint.com/_api/Site

… with the same HTTP headers, it works without any issues.

It can look weird but in fact it’s normal.

If you ever call the following URL to retrieve the OData manifest for the SharePoint API…

https://tenant.sharepoint.com/_api/$metadata

… you can see that the API only supports OData v3.0 (cf. MaxDataServiceVersion).

<edmx:Edmx Version="1.0">
  <edmx:DataServices m:DataServiceVersion="3.0" m:MaxDataServiceVersion="3.0">
    ...
  </edmx:DataServices>
</edmx:Edmx>

So even if a lot of features in the SharePoint REST API are working with the OData v4.0 headers, you should better use the OData v3.0 headers such as below to avoid such issues :

Accept: application/json;odata.metadata=minimal
DataServiceVersion: 3.0

Microsoft Graph / OneDrive : The resource could not be found

Microsoft Graph gives you access to a large range of features and data (Outlook, Delve, Azure AD…) using its REST API.

Among these features, you are able to retrieve content from the “OneDrive for Business” service associated to your Office 365 account.

To do this, you just have to call the following URL that will return all the items stored in the root folder of your personal document library.

GET https://graph.microsoft.com/v1.0/me/drive/root/children

By calling that URL, the server will return a JSON response such as the following (the response shown here was truncated for brevity) :

{
  value = ({
    @odata.id = "users/31950312-e7dd-44de-bfaa-4d8274e4d6a0/drive/root/children/01ZWNXWXJYRUGTTJRMQZB2L2YE4NQK4CIF",
    createdBy = { ... },
    createdDateTime = "...",
    eTag = "...",
    folder = { ... },
    id = "01ZWNXWXJYRUGTTJRMQZB2L2YE4NQK4CIF",
    lastModifiedBy = { ... },
    lastModifiedDateTime = "...",
    name = "...",
    parentReference = { ... },
    size = 0,
    webUrl = "..."
  },
  {
    @odata.id = "users/31950312-e7dd-44de-bfaa-4d8274e4d6a0/drive/root/children/01ZWNXWXJ3G5EOS6XJRRCJ54PQZQAJIM3H",
    createdBy = { ... },
    createdDateTime = "...",
    eTag = "...",
    folder = { ... },
    id = "01ZWNXWXJ3G5EOS6XJRRCJ54PQZQAJIM3H",
    lastModifiedBy = { ... },
    lastModifiedDateTime = "...",
    name = "...",
    parentReference = { ... },
    size = 0,
    webUrl = "..."
  })
}

This sample has 2 folders with their respective properties. One of the important parts in the response is the parameter named “@odata.id” which is the URL associated to the object, and used by the API to uniquely identify an item.

In the case of a folder, it could have children (folders and files). If you want to retrieve these children, you have to concatenate “/children” to the unique identifier of the item.

With the first folder of the previous JSON response, it should look like this :

GET https://graph.microsoft.com/v1.0/users/.../drive/root/children/01ZWNXWXJYRUGTTJRMQZB2L2YE4NQK4CIF/children

But if you call that URL, you get the following error message :

The resource could not be found.

This message means that Microsoft Graph is unable to process your request. It’s weird because the URL was generated by the server and returned in the JSON response.

So how can you get to access the children of this item ?

Now that we have retrieved the ID for the item (see the ID value in the JSON response), we are able to build our own URL to retrieve its children.

In Microsoft Graph / OneDrive API, each item is accessible through an URL such as “…/v1.0/users/{user_id}/drive/items/{item_id}”. So if we build our URL by respecting that schema, it works without errors.

In our previous example, the URL to call will be :

GET https://graph.microsoft.com/v1.0/users/.../drive/items/01ZWNXWXJYRUGTTJRMQZB2L2YE4NQK4CIF/children

If you want to play with Microsoft Graph APIs with data stored on your tenant, you can use this site created and hosted by Microsoft : https://graphexplorer2.azurewebsites.net