Redth

code, ramblings, rants

Improvements Coming to Xamarin Google Play Services

| Comments

Google Play Services is a rapidly evolving library that Google has been using to combat fragmentation on the platform, and ensure their developers have access to great new API’s without having to worry about what Android version their users are actually on.

The rate at which this library has evolved recently has been especially challenging for us to keep pace with in getting bindings out for Xamarin.Android, but, rest assured, we are committed to bringing out a great Google Play Services experience in your Xamarin apps. Here are some of the improvements we’ve been making that are now available as pre-release!

Latest and Greatest

Google has rapidly iterated in the last few revisions. We went from 6.5 to 7.0 to 7.3 very quickly, and we’re happy to say we’re shipping the latest and greatest and expect to keep a better track record going forward on getting the latest out quickly!

NOTE: As of this post, the improvements are available on NuGet as 24.0.0-rc1 versioned pacakges.

NuGet what you Want

We’ve now split up Google Play Services into many NuGet packages to match the changes Google made to split them up into many .jar files. Using NuGet we’re able to manage the dependencies between all of the packages. For example, all packages depend on the Google Play Services - Base package, while others such as Location depend on Maps as well.

You can now grab only the packages you need in your app without bringing in everything else. This should help keep your app size down as Google continues to expand Play Services adding more and more features and API’s.

Finally, the old Google Play Services - All package has been kept around to help make the transition easier. It now depends on all of the individual NuGet packages.

Breaking Changes, Nicer Naming

In the process of binding libraries to make them more C# friendly, we often run into cases where casing is different between java and C#. For example, in java, we have cast.Cast which in C# translates into Cast.Cast. Since we cannot have a class named the same as its namespace in C#, this presents a problem. Traditionally we have renamed the class, for example to Cast.CastClass. This isn’t always very discoverable or nice to look at.

We’ve now decided to change the namespaces instead of renaming the conflicting classes. All namespaces now have Sdk appended to them, so we now have CastSdk.Cast for instance. This should be much more consistent and discoverable going foward.

The other area where this is a problem is with fields in java. For instance, Fitness.FITNESS_API and Fitness.FitnessApi in java both transform into Fitness.FitnessApi in a C# binding by default. To avoid conflicts and bring consistency across the bindings, we’ve decided to keep the java naming conventions in the C# binding.

You’ll now use the upper-cased Fitness.FITNESS_API fields to specify an Api to add in your IGoogleApiClient.AddApi (..) calls, whereas you’ll use the lower-cased Fitness.FitnessApi fields to actually invoke methods of the given Api.

Happier C# Developers

Our binding tooling generally does a good job at making java libraries more C#-ified. Google Play Services has a number of cases that are less friendly to our tooling and often this has created a sub-par developer experience from a C# perspective.

We’re continuing to work at improving this story in Google Play Services, and there are a couple of changes that should make life better:

IPendingResult.AsAsync

A very common pattern in Google Play Services is to make use of the interface IPendingResult. This is sort of like a Task - it’s a promise or a future. You can .Await() it in a blocking manner (though you must do so off the UI thread), or you can .SetResultCallback (IResultCallback) which means you need to pass in an implementation of the interface which usually means creating an implementor class with some Actions or Events to make the code a bit less ugly (since we don’t have anonymous classes in C#).

You now have more options with IPendingIntent instances through some extension methods:

1
2
3
4
5
6
7
8
9
// 1. Turn it into a Task with the desired result type
var result = await SomeMethodReturningPendingIntent (...)
  .AsAsync<TypeOfStatus> ()

// 2. Pass in an Action<T> to the callback
SomeMethodReturningPendingIntent (...)
  .SetResultCallback<TypeOfStatus> (result => {
      // ...
  });

Helper Implementor Classes

There’s still a lot of areas that require you pass in some sort of class implementing a listener type of interface. ILocationListener is a good example. Instead of having to build your own class which implements this simple interface, we’ve added a class LocationListener which implements ILocationListener and exposes an event for you. Nothing earth-shattering here, but hopefully it saves you from writing the same boiler plate code over and over.

You can expect more implementation classes like this going forward.

GoogleApiClientBuilder

The first place you’ll probably notice the heavy use of interfaces is in the GoogleApiClientBuilder. The .AddConnectionCallbacks (..) and .AddOnConnectionFailedListener (..) methods both require instances of interface implementations as parameters. You can still call these methods like normal, but now there’s extension methods allowing you to pass Action’s into them as appropriate. Again, this is code you could easily write, but shouldn’t have to.

Less p0, p1, p2

This has always been a bit of an eye-sore, to see poorly named parameters. We’ve made some improvements in our tooling that are going to continue to help get better parameter names. We’ve started trying some of these techniques out already in Google Play Services!

Feedback?

I don’t always get to explore all of the API’s inside Google Play Services on a day to day basis, so I’m not always aware of where the pain points are.

I’m very open to feedback if there’s other areas you’d like to see some C# improvements to like we’ve started.

Please don’t be shy, mention me on twitter with any suggestions you have!

New and Improved Xamarin Studio Launcher

| Comments

UPDATE - Jan 12, 2015: Thanks to the wonderful @Vaclav, Xamarin Studio Launcher now has a proper icon! Please download the much prettier v4 at the end of this post!

Awhile back I made a quick little AppleScript based app called Xamarin Studio Launcher to help launch multiple instances of Xamarin Studio (it had a pretty little icon that you could keep in your dock to open new instances - which I recently updated to the newer Xamarin look).

Xamarin Studio Launcher

While it was cute, and relatively functional, as a recovering ex-Windows user, I found myself still constantly opening .sln files from finder, which would cause them to open in an existing instance of Xamarin Studio, closing whatever current solution happened to be open in that instance.

Now I know about the ability to open multiple solutions in the same Xamarin Studio instance, and generally I’m pretty good about forcing myself into learning the nuances of the platform I’m working on, however, having multiple instances of Visual Studio open was something I grew so accustomed to that I just couldn’t shake the habit of being on a Mac!

Not sure why it took me so long to make this, but here it is, finally!

Xamarin Studio Launcher v3

This new launcher app works first and foremost exactly like the previous Xamarin Studio Launcher I released. You can put it in your dock, and when you open it, it will launch a new, blank instance of Xamarin Studio.

The new feature is that it can now handle opening .sln files. If you choose to open a .sln file with this app, it will open that .sln file in a new instance of Xamarin Studio.

This means you can set Finder to open all .sln files with Xamarin Studio Launcher so any time you double click or otherwise open a .sln file from Finder, it will open in its own instance of Xamarin Studio!

How to set this as the default app for .sln files

Xamarin Studio Launcher

  1. Find a .sln file in Finder
  2. Right click the .sln file and Get Info (or highlight the file and cmd + i
  3. Under the Open With section, click the drop-down list and click Choose
  4. Navigate to and select Xamarin Studio Launcher
  5. Click Change All

Download

Here’s the .zip file containing Xamarin Studio Launcher.app:

Download Xamarin Studio Launcher v4

Smarter Xamarin Android Support V4 / V13 Packages

| Comments

If you’ve ever built an Android app, you’ve probably used the Android Support libraries. Google created these as a way to enable developers to use new features on older Android versions. The most common Support library is arguably Support-v4, however as older Android devices retire and newer versions of Android increase in market share, Support-v13 is becoming more commonplace.

Warning: This is going to be a bit geeky of a post. If you don’t want to know the details, skip down to the TL;DR section for the need-to-know bits :)

Finding Your Android App’s MD5 or SHA1 Signature From Your Keystore

| Comments

If you’ve ever used Google Maps or Amazon App Services in your Android app, you’ve probably gone through the pain of having to find an MD5 or SHA1 signature to give to the service so they could generate an API Key for you.

If you haven’t been through this experience, let me assure you: It’s painful, tedious, and annoying.

What Are App Links?

| Comments

So there’s this new thing called App Links. It’s backed by Facebook and some other big names, so you know it’s going to gain at least a bit of traction. But the problem is, everyone seems to have a hard time figuring out what they actually are and do. The video on AppLinks.org sort of helps, but it still left me confused, even after watching it a few times.

Here’s my attempt to explain what App Links are, why you would need or want them, and how they work. A word of caution: this post is aimed at mobile app developers, so it may be a bit confusing if you’re not familiar with some of the concepts of mobile app development.

Such Android API Levels, Much Confuse. Wow.

| Comments

I have been bitten more than once by the confusion of Android’s many API levels when building Xamarin.Android apps. It gets even more complex when you start referencing other libraries that target different API levels. Just the other day I had an issue come up with AndHUD where the resolution for a runtime error had nothing to do with the code itself. I decided it was time to finally write this post.

As if it weren’t confusing enough, Google generally gives three names to every API level: an integer API Level number, a version number, and a delicious sounding dessert name.

For example, Gingerbread was version 2.3 or API Level 9 (also Gingerbread had 2.3.7 and API level 10 as an update). Kit Kat is version 4.4, API level 19. Luckily Google has published the various versions in a table so you can figure out what is what.

When it comes to your Xamarin.Android apps, it’s important to be aware of all of the spots you can set API levels in your project settings. In particular, there are three places of interest:

  1. Project Settings -> General -> Target Framework
  2. Project Settings -> Android Application -> Minimum Android Version
  3. Project Settings -> Android Application -> Target Android Version

iTunes Media HotKey Disabler

| Comments

This simple application will allow you to disable or enable iTunes from listening to when you press the media keys (Play / Pause) on your keyboard. This is great for applications such as gTunes which make use of the hot keys but cannot themselves prevent iTunes from also responding to those keyboard keys.

iOS7: Fun Times With the New Full Screen Layout!

| Comments

In a mad rush, I had to prepare an app for iOS7 after its release. Yes, I know, shame on me for not listening to everyone telling me to start getting my apps ready early. How bad could it be anyway?

For the most part, not too bad. The worst part for me came in the shape of dealing with this new idea that every UIViewController now expands the bounds of the entire screen, including where the status bar and navigation bars could be. In any case, I had to do a bit of learning really quickly. If you don’t already know what I’m talking about, here’s a picture of one unpleasant conversion experience:

iOS7 Recipe: Background Fetching

| Comments

This is my entry into the Xamarin Recipe Cook-Off. Recipes, in Xamarin terms, are very simple demonstrations of how a single feature or piece of functionality is implemented. I thought background fetching would be useful to many developers, and it’s pretty easy to implement, especially after reading this recipe.

I’ve also included the recipe in this blog post:

Background Fetching Data

This recipe shows how to register your application to perform background fetching on intervals.

1. Recipe

In your application’s Info.plist file, add the value fetch to the UIBackgroundModes (Required background modes) property.

Next, in your AppDelegate class, in the FinishedLaunching override method, add the following code to register your application for background fetching:

1
UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval (UIApplication.BackgroundFetchIntervalMinimum);

Finally, in your AppDelegate class, override the PerformFetch method.

This method will be executed by the operating system when it sees best fit (eg: when the device is awake and connected already). You do not have complete control over how often or when fetching happens.

You should execute your own code to fetch new data in this method. It’s important to call the Action<UIBackgroundFetchResult> completionHandler parameter which is passed into this method with the appropriate result when you are done.

2. Sample PerformFetch

In this sample, a weather service is called by background fetching so that when the user opens the app, recent weather is available. The weather is cached locally after it’s fetched in the background, and the UI is also updated if there is new weather info.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public override async void PerformFetch (UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
{
  Console.WriteLine ("PerformFetch called...");

  //Return no new data by default
  var result = UIBackgroundFetchResult.NoData;

  try
  {
    //Get latest weather
    var w = await GetWeatherAsync("Windsor, Canada");

    if (w != null)
    {
      //Cache the weather locally
      CacheWeatherAsync(w);

      //Update the UI
      weatherViewController.UpdateWeather(w);

      //Indicate we have new data
      result = UIBackgroundFetchResult.NewData;
    }
  }
  catch
  {
    //Indicate a failed fetch if there was an exception
    result = UIBackgroundFetchResult.Failed;
  }
  finally
  {
    //We really should call the completion handler with our result
    completionHandler (result);
  }
}

3. Additional Information

  • Your PerformFetch has about 30 seconds to run before it’s killed
  • The operating system is more likely to grant more time (and more often) to your application for background fetching if you are efficient, which means executing quickly, and always calling completionHandler with an accurate result
  • You can tell the operating system the minimum time to sleep between waking up your application and calling its PerformFetch method if you know your app only updates at a certain interval, to avoid extra calls to PerformFetch and wasting battery life. You would specify the minimum time in seconds in the UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval (double minimumBackgroundFetchInterval) method
  • You can actually make calls to update your UI from the PerformFetch method so that the next time the user launches the app, everything is up to date