Runar Ovesen Hjerpbakk

Science-based software development

Book Scanner

From UIAlertView to UIAlertController using Xamarin and async / await

UIAlertView has been deprecated by Apple from iOS8. From now on, UIAlertController is the way to go. UIAlertController is surely an improvement, but given the asynchronous nature of displaying alerts to the user, I wanted to use the API together with async and await.

Below is a screenshot of what I wanted to accomplish: Customer feedback sheet

A simple menu with two options and a Cancel-button.

UIAlertController lets you add multiple UIAlertActions, each with its own handler which is just a normal Action. I want to present the menu to the user and wait for her to select one of the items.

By using a TaskCompletionSource, I can accomplish this using async and await.

public static class CustomerFeelingSheet {
  public static Task<CustomerFeeling> ShowRatingDialogAsync(UIViewController parent) {
    var taskCompletionSource = new TaskCompletionSource<CustomerFeeling>();

    var alert = UIAlertController.Create(
      "howDoYouFeel".T(), null, UIAlertControllerStyle.ActionSheet);

    alert.AddAction(UIAlertAction.Create(
      "likeIt".T(), UIAlertActionStyle.Default,
      a => taskCompletionSource.SetResult(CustomerFeeling.LikeIt)));
    
    alert.AddAction(UIAlertAction.Create(
      "couldBeBetter".T(), UIAlertActionStyle.Default,
      a => taskCompletionSource.SetResult(CustomerFeeling.CouldBeBetter)));
    
    alert.AddAction(UIAlertAction.Create(
      "cancel".T(), UIAlertActionStyle.Cancel,
      a => taskCompletionSource.SetResult(CustomerFeeling.DontCare)));

    parent.PresentViewController(alert, true, null);
    return taskCompletionSource.Task;
  }
}

The TaskCompletionSource can be used to map an external asynchronous operation onto a normal C# Task. We can then use this task as we would any other.

In this case, the result of this task is the Enum CustomerFeeling with values corresponding to the users happiness. Thus, ShowRatingDialogAsync can be used like this:

var customerFeeling = await CustomerFeelingSheet.ShowRatingDialogAsync(parentVC);
switch(customerFeeling) {
  case CustomerFeeling.LikeIt:
    // "I like it!" was chosen 
    break;
  case CustomerFeeling.CouldBeBetter:
    // "It could be better..." was chosen
    break;
  default:
    // "Cancel" was chosen
    return;
}

The choice of the user can be awaited and UIAlertController now fits in perfectly with the rest of the C# code.

Read More

ERROR ITMS-9000: Invalid Image Path

I just submitted version 1.5 of Book Scanner to the App Store, but this time I needed two tries.

Book Scanner now fully supports iOS8 and the larger iPhones, and I've also update the app's icons. I use asset catalogs and had dutifully added icons in all the slots. Then I started uploading the app using Application Loader. After a while, this error message appeared: ERROR ITMS-9000: Invalid Image Path

ERROR ITMS-9000: "Invalid Image Path - No image found at the path referenced under key 'CFBundleIcons': 'AppIcons120x120'"

After a little trial and error, it turns out that the CarPlay icon was the culprit. I removed the CarPlay icon from the asset catalog and the upload completed successfully.

No CarPlay Icon

And I will update Book Scanner to 64bit soon...

Read More

Book Scanner promotional video

A promotional video for Book Scanner is now live on YouTube. It got some really inspirational music and amazing transitions. Check it out!

Read More

Book Scanner (iOS)

Scan a book

Buy it if you want

View all scanned books


My new app Book Scanner, also known as Book Barcode Scanner is now available worldwide on the App Store.

Book Scanner scans ISBN-barcodes and finds the books on iBooks. The app remembers your scanned books and you can buy them on iBooks at your convenience. Scanning book barcodes is faster than a manual search and the it's very useful in bookstores and other places with a lot of books.

Book Scanner is available free on the App Store and is of course written in C# using the Xamarin stack. I've learned a lot while writing this app, and I will share some of it here on this blog.

Read More