All posts by hedgehogjim

30+ years as a professional software dev, 17+ years developing mobile solutions, Pluralsight Author, Founder JWHH, LLC

Programming Stuff

Kotlin Properties and Constructors in XX Seconds

One of the great things about Kotlin is its brevity and as part of that brevity, Kotlin works hard to eliminate what we often refer to as boilerplate code .. blocks of code that we frequently write with little or no change.

As great as Kotlin’s brevity is (and I do love it), it can often make understanding Kotlin challenging when first learning the language. Consider the following Kotlin class declaration:

class PersonKotlin(val firstName:String, val lastName:String, var age:Int)

That’s a complete declaration of a class named PersonKotlin that includes a constructor and 3 properties.

A look at some boilerplate code

To give us some context, let’s look at what is essentially the same class declared in Java.

public class PersonJava {
    private String firstName;
    private String lastName;
    private int age;
    
    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public PersonJava(String firstNameIn, String lastNameIn, int ageIn) {
        firstName = firstNameIn;
        lastName = lastNameIn;
        age = ageIn;
    }
}

In the Java version of the class, things become a bit more clear. We basically want the class to have 2 read-only properties (firstName, and lastName) and one read-write property (age).

As we look at the Java version of the class, we can see just how much boilerplate code is required. We have to declare private fields to store the firstName, lastName, and age; we create getter methods for the 2 read-only properties along with both a getter and setter for the read-write property. Then we have our constructor whose only real job is to accept initial values and then assign those values to the fields that correspond to our properties. That’s a lot of boilerplate code (property getters, property setters, and assignments to give properties their intial values).

A closer look at the Kotlin class declaration

To help us understand what’s happening in the Kotlin class, let’s look at a slightly more expressive way we can write the Kotlin class.

class PersonKotlin(firstNameIn:String, lastNameIn:String, ageIn: Int) {
    val firstName = firstNameIn
    val lastName = lastNameIn
    var age = ageIn
}

With this we can see our 3 properties a bit more clearly. By declaring firstName and lastName with “val” we’re indicating that they’re read-only properties (can’t be changed once initially set). Using “var” to declare age indicates that it’s a read-write property. So the “val” and “var” keywords allow us to create properties and indicate whether they’re read-only or read-write without having to write boilerplate getter/setter code as we did in Java.

The 3 values in the parenthesis after the class name are the class’ constructor parameters. As is often the case, the only purpose of those parameters is to receive the values that we’ll use to initialize the class properties.

Back to brevity

Since the only purpose of the constructor parameters is to initialize the properties, Kotlin allows us declare the properties themselves right there in the constructor parameter list. This allows us to get rid of the boilerplate code required to explicitly assign the constructor parameter values to the properties.

So with that in mind, we can go back our original Kotlin class declaration.

class PersonKotlin(val firstName:String, val lastName:String, var age:Int)

With this, by including the val and var keywords in the parameter list we’re able to both declare the properties and have their initial values assigned as part of class construction.

So we can use our class like this…

val person = PersonKotlin("Maria", "Jones", 27)

// Set greeting to "Hello Maria Jones
val greeting = "Hello " + person.firstName + " " + person.lastName

// Happy birthday
person.age += 1;

We declare a local variable named person and create a new instance of PersonKotlin passing initial values for the firstName, lastName, and age properties. We then use the firstName and lastName properties to create a string that says “Hello Maria Jones”. Finally, we celebrate Maria’s birthday by increasing the age property by one.

… and we get all of this from a Kotlin class that we can literally declare in a single line.

Programming Stuff

Dynamically Adjust Google Maps Zoom with Xamarin.iOS

One of the challenges when displaying information within a map is determining the right zoom level. The map needs to be zoomed out far enough to allow the user to see a broad set of information but zoomed in close enough to provide enough detail to give the user context.

In our app at Spectafy, getting this right is very important to us. Since the focus of our app is providing user’s with information about things that are going on nearby them, we want to be sure to get that map zoom level just right.

For a user in a large city like San Francisco or New York, a zoom level that shows just a few blocks may show them everything they need. For someone like me who lives in Central Florida, we may need to zoom out a bit further.

To resolve this challenge, we have our app start initially at a reasonably zoomed-in level and then adjust the zoom level dynamically to to include a minimum number of markers.

Determining that appropriate zoom level is pretty straightforward because Google Maps’ zooming changes at a very predictable rate … each reduction in the zoom level (a lower zoom level value is further away) doubles the amount of map that’s visible.

Knowing that, we’re able to determine our perfect zoom level with a method like the following.

float CalculateMarkerInclusiveZoomLevel(
  MapView mapView, List<Marker> markers, 
  int minVisible)
{
 var bounds = 
   new CoordinateBounds(mapView.Projection.VisibleRegion);
 var initialZoomLevel = mapView.Camera.Zoom;
 var markerInclusiveZoomLevel = initialZoomLevel;

 var count = markers.Count(
   m => bounds.ContainsCoordinate(m.Position));

 while (count < markers.Count && count < minVisible)
 {
   // Each zoom level doubles the viewable area
   var latGrowth = 
     (bounds.NorthEast.Latitude - bounds.SouthWest.Latitude) / 2;
   var lngGrowth = 
     (bounds.NorthEast.Longitude - bounds.SouthWest.Longitude) / 2;
   markerInclusiveZoomLevel--;

   bounds = new CoordinateBounds(
      new CLLocationCoordinate2D(
          bounds.NorthEast.Latitude + latGrowth, 
          bounds.NorthEast.Longitude + lngGrowth),
      new CLLocationCoordinate2D(
          bounds.SouthWest.Latitude - latGrowth, 
          bounds.SouthWest.Longitude - lngGrowth));

   count = 
     markers.Count(m => bounds.ContainsCoordinate(m.Position));
 }

return markerInclusiveZoomLevel;
}

The above method accepts in a reference to the MapView being displayed, the list of markers on the map, and the minimum number of markers that should be visible to the user.

The method then gets the bounds of the map that’s visible at the current zoom level and what that zoom level is. From there it’s just simple math.

The app counts how many markers are visible within the current bounds. It then keeps doubling the size of the bounds and decrementing the zoom level (lower zoom level is further away) until the desired number of markers is visible within that bounds(either the value of minVisible or all of the markers if the list contains less then minVisible markers).

We can then use the above method similar to the following

// Assumes _mapView is already visible and contains the list of markers in _markers
var newZoomLevel = 
  CalculateMarkerInclusiveZoomLevel(_mapView, _markers, 10);
_mapView.Animate(
  CameraUpdate.SetTarget(_mapView.Camera.Target, newZoomLevel));

With this code, the map will now animate to the appropriate zoom level to make at least 10 markers visible.

That easily, we’re now able to give the user just what the want … the right amount of information with the right amount of context.

Programming Stuff

Use Xamarin.iOS to Control Google Maps Zoom Speed for a More Dramatic Look

We’re working on the next major update to our app at Spectafy and as part of that work, we plusing a lot of the visual effects.

One of the things we’ve discovered is that there are some scenarios where slowing down the rate we zoom in or out on the map is helpful in drawing the user’s attention to the new information exposed at the new zoom level.

Of course, there’s one problem …

Google Maps on iOS doesn’t expose a way to control the rate of zoom.

The good news is …

Google Maps uses standard iOS animation features to perform the zoom animation. As a result, we can use Core Animation classes to override the rate of zoom.

Here’s the code…

CATransaction.Begin();
CATransiaction.AnimationDuration = 3;
_mapView.Animate(CameraUpdate.SetTarget(new CLLocationCoordinate2D(lat, lng), zoomLevel));
CATransaction.Commit();

In the above code, we simply place the standard Google Maps call that triggers the zoom animation [ _mapView.Animate( … ) ] within a CATransaction, and set the AnimationDuration to 3 seconds within that transaction. That easily we’ve slowed down the animation so that the zoom effect takes 3 seconds.

Try it out … you’ll find that subtle changes in the zoom speed can have a dramatic effect on user experience.

Programming Stuff

My Xamarin Forms Course is Live at Pluralsight

My Introduction to Xamarin Forms course is now up on Pluralsight. The initial feedback has been fantastic.

Here’s a list of the modules from the course.

  • Building Your First Xamarin Forms App
  • Understanding Xamarin Forms
  • Providing UI Behavior with Views and XAML
  • Xamarin Forms ListViews
  • Xamarin Forms Layouts
  • Xamarin Forms Pages
  • Handling Platform Specific Requirements

The course is designed to give you a high-level look at Xamarin Forms and give you an idea of what working in Xamarin Forms is like. It’s super code intensive … lots of codes w/ very few slides.

I encourage you to check it out. I think you’ll like it.

BTW: If you haven’t worked in Xamarin (which is not the same thing as Xamarin Forms … but they’re closely related), you might want to check out my 2-part series Building Cross-Platform iOS/Android Apps with Xamarin, Visual Studio, and C#.

And if you’re looking to have a little more fun, I talk about using  Xamarin to build a Google Glass app in Creating a Google Glass App with C# and Xamarin.

I love writing these courses … I hope you enjoy them.

Programming Stuff

Force Activity Kills to Improve Xamarin.Android App Stability

Activities in Android/Xamarin.Android are far more than just screens. They are a first-class component of the Android runtime with a distinct lifecycle. An important aspect of that lifecycle is how the Activity behaves when your app transitions away from an Activity and then returns to it.

What Happens When the User Isn’t Looking?

When a user leaves an Activity (we’ll call it Activity-A) to view another Activity, sometimes the Android runtime will simply move Activity-A into the background, in other cases the runtime may destroy Activity-A. When the user returns to Activity-A, if its still running in the background, the runtime simply moves it into the foreground. But … if it was destroyed, the system creates a brand new instance of Activity-A and as developers we’re responsible to be sure that Activity-A is restored to the same state it was in when the user left it.

In other words, it’s our job to put the magic together that creates the illusion that Activity-A has been waiting patiently for the user to return even if that’s not actually the case.

Managing this lifetime correctly can be a bit of a challenge. It means that the state of every member variable must be persisted (normally stored by your Activity’s OnSaveInstanceState method) and then restored (normally handled in your Activity’s OnCreate and/or OnRestoreInstanceState methods). Restoring the Activity means that we must also assure that all of the behaviors dependent on those member variables are restored as well.

Why Does My Activity Only Break in the Field?

When developing and testing our apps, generally the only thing the test device is doing is running our app. This avoids many of the issues (depleting system resources, etc.) that cause the system to destroy an Activity when the user moves away from that Activity. The result is that we end up testing only the most simple case of our application … the Activity being initially created and then continuing to exist until we’re done with it.

However, when our app goes out into the field, it’s facing a much harsher environment. Our real-life users may have many different things running on their phones or maybe they’re using a phone with much more limited resources then our test phones. The in-the-field scenarios significantly increase the likelihood that an Activity will be destroyed when the user moves away from it and then fully recreated when the user returns.

This results in the app encountering scenarios in the field that we may have never experienced during our app development and testing.

Forcing Activity Kills

To assure that our apps work correctly in scenarios where the Activities are destroyed and restored, we must be sure to include that behavior in our app testing.

Under normal Android behavior, testing this case is difficult because keeping or destroying an Activity is something that occurs at the discretion of the Android runtime … what we need to do is get around this normal behavior of the Android runtime.

We need to force the runtime to kill our Activities when we move away from them so that we can verify that our Activities restore themselves correctly.

The Don’t Keep Activities Option

Fortunately, Android provides a series of Developer Options that allow us to alter the behavior of the Android runtime during our app testing. One of those options is “Don’t keep activities”.

As it’s name implies, when set, the runtime does not keep Activities running when the user moves away from them instead Activities are always destroyed.

To access this option, open up your device settings and locate “Developer options”. You’ll probably have to scroll pretty far down to find it.

BTW: Some 4.x versions of Android hide “Developer options” by default. See this post for instructions for unhiding it.

Android Developer Settings

Once your’re in the list of Developer Options, scroll down until you find “Don’t keep activities” (it’ll probably be near the end of the list of options). Select the check mark next to it to enable the option.

Don't keep activities option

And Now We Have Stability

With the “Don’t keep activities” option enabled, you can now fully test your Activities. Every time you move away from an Activity, it will be destroyed. When you return to the Activity, it will then go through its full restoration cycle. You’re now able to consistently test the most challenging part of the Activity life cycle.

Making use of the “Don’t keep activities” option during our testing has been a key part of how we assure that our Spectafy app remains stable in the field. Our users are highly diverse using a wide variety of phones. With the rich nature (maps, lots of images, complex data model) of many of our screens (Here’s just a few of them)…

A few Spectafy screens

… we need to be sure that each Activity provides that consistent, stable experience in all scenarios.

To that end, we regularly exercise our app with the “Don’t keep activities” option enabled. This practice allows us to be sure that each Activity correctly restores itself and provides our users with an uninterrupted, stable experience.

I encourage you to incorporate “Don’t keep activities” as regular part of your Xamarin.Android development and testing. (BTW: this option is equally useful for Java-based Android development as well). It’ll make a big difference in the field stability of your apps and help you avoid having to deal with a lot of painful I-can’t-reproduce-the-problem debugging headaches.

 

 

 

Programming Stuff

Simplify Using Xamarin.Auth with Async Tasks (A Twitter Example)

The Xamarin.Auth component is a huge time saver when interacting with services like Twitter and others that require authentication. In most cases, Xamarin.Auth makes authentication as simple as initializing an authenticator and then dealing with success or failure.

As an example, here’s the code to do Twitter authentication with Xamarin.Auth

void DoMyTwitterAuth()
{
  var auth = new OAuth1Authenticator(
    Constants.TwitterConsumerKey,
    Constants.TwitterConsumerSecret,
    new Uri("https://api.twitter.com/oauth/request_token"),
    new Uri("https://api.twitter.com/oauth/authorize"),
    new Uri("https://api.twitter.com/oauth/access_token"),
    new Uri("http://twitter.com"));

  auth.Completed += (sender, e) =>
  {
    if(e.IsAuthenticated)
    {
      var account = e.Account;
      // Do success work
    }
 };

  auth.Error += (sender, e) =>
  {
    // Do Error work
  };

  // iOS
  var ui = auth.GetUI();
  PresentViewController(UI, true, null);
  // Android
  //var ui = auth.GetUI(this);
  //StartActivity(UI)
}

Authenticating against any remote service requires communicating over the Internet which, of course, involves an indeterminate time delay. As a result, the auth.Completed or auth.Error event handlers get called asynchronously after some significant (in computer terms) delay.

We know that writing apps that use traditional asynchronous techniques can be complicated. To deal with this scenario, .NET provides the Task<T> class along with the async and await keywords. With these tools we get to code things using traditional linear programming techniques leaving the asynchronous details to .NET.

What Simpler Looks Like

If authentication was setup to use Task<T> we could write our authentication code something like this.

async void DoMyTwitterAuth()
{
  try
  {
    var account = await AuthHelper.OAuth1(
      Constants.TwitterConsumerKey,
      Constants.TwitterConsumerSecret,
      new Uri("https://api.twitter.com/oauth/request_token"),
      new Uri("https://api.twitter.com/oauth/authorize"),
      new Uri("https://api.twitter.com/oauth/access_token"),
      new Uri("http://twitter.com"));

    // Do success work
  }
  catch (Exception ex)
  {
    // Do error work
  }
}

That is so much simpler to work with than having to explicitly handle the callbacks in separate methods or lambda expressions.

The problem, of course, is that Xamarin.Auth doesn’t support that async/await programming style.

But! We Can Fix That

We can code up an AuthHelper.OAuth1 implementation that translates the Xamarin.Auth callbacks into Task<T> that’ll allow us to use async/await.

Here’s the OAuth1 implementation…

using Xamarin.Auth;
using System.Threading.Tasks;
// other usings elided for clarity

static class AuthHelper
{
  public static Task<Account>OAuth1(
      string consumerKey, string consumerSecret, 
      Uri requestTokenUrl, Uri authorizeUrl, 
      Uri accessTokenUrl, Uri callbackUrl)
  {
    TaskCompletionSource<Account> tcs = 
       new TaskCompletionSource<Account>();

    var auth = new OAuth1Authenticator(
        consumerKey, consumerSecret, requestTokenUrl,
         authorizerl, accessTokenUrl, callbackUrl);

    auth.Completed += (sender, e) =>
    {
      tcs.SetResult(e.IsAuthenticated ? 
          e.Account : null);
    };

    auth.Error += (sender, e) =>
    {
      tcs.SetException(e.Exception);
    };

    // iOS
    var ui = auth.GetUI();
    someViewController.PresentViewController(ui, true, null);
    // Android
    //var ui = auth.GetUI(someActivity);
    //someActivity.StartActivity(ui);

    return tcs.Task;
  }
}

Now That’s Better!

With that little helper method, we can now do our authentication code using a simple linear programming style with the help of async/await.

try
{
  var account = await AuthHelper.OAuth1(...);
  // do success work
}
catch(Exception ex);
  // do error work
}

The key to making this work is the TaskCompletionSource. It allows us to easily translate non-Task style asynchronous work to Task-style. Basically it creates a Task<T> instance that can be await’ed on. When the work completes we call the SetResult or SetException methods and the TaskCompletionSource handles the Task signalling details.

We use this technique at Spectafy and it has made our Xamarin.Auth programming so much easier.