Shameless plug

Attention baseball fans! I’d like to take this opportunity to put in a shameless plug for an app near and dear to my heart.

I just released the 4.0 version of Pro Baseball Stats to the iTunes App Store. It is a free universal app for iPhone and iPad with iOS 7 or newer. If you are a baseball geek, please check it out.

BTW, a posthumous Happy Birthday to Jeff Healey, the fantastic blues guitarist who was taken from us far too soon.

Custom UITableViewCell with class and nib file

It is only a matter of time before you want to create a custom UITableViewCell with class and nib file on the iOS platform. There are a couple of things to keep in mind when doing this so that you do not bang your head against the wall, trying to figure out why it is not working.

In order to do this, you will probably create a .m and .h file for your code, and a .xib file for the UI. After creating a new nib file, you will have to remove the blank UIView and put a blank UITableViewCell on the design surface. Make sure to get into the habit right away of setting both the File’s Owner and the top level table view cell to your new class name.

Then, if you any IBOutlet controls, when you are assigning the pointers in Interface Builder, make sure that you are dragging to the top level cell and not the File’s Owner, otherwise you will get a crash when the cell is being built.

BTW, Happy Birthday to Gary Lockwood, most famously of 2001: A Space Odyssey and the 2nd Star Trek pilot.

Codemash 2015 recap

Well I have been home for a few days now after Codemash, and I must say it was a good conference. Because it is platform and technology agnostic, the content tends to be a bit thin in certain areas, such as my area of expertise, iOS development. I went to as many iOS presentations as I could, and then filled in the rest of the schedule with a smattering of soft skills talks and presentations on Microsoft technologies.

For me, the highlights were Ravi Desai’s presentation on Swift, and Chris Risner’s push notification presentation. Both of these had lots of good information that I can use at work and in my own projects that I like to putter around with.

BTW, a posthumous Happy Birthday to Captain Beefheart, an underrated performer by anyone’s measure.

Problems presenting view controller from clickedButtonWithIndex on iPad with iOS 8

As I work through my apps, I keep finding nifty iOS 8 issues. Such as one where I am having problems presenting a view controller from the clickedButtonWithIndex delegate method on an iPad with iOS 8.

From my research, it appears that under the covers, Apple is taking my UIActionSheet and morphing it into a UIActionController on the iPad in iOS 8. Unfortunately, weird things can happen if you try to present another view controller from within the clickedButtonWithIndex method, as the alert controller is still visible when the new controller is being presented. As a result, you get a warning message in the console that looks something like this:

Warning: Attempt to present <NewViewController: 0x12345678> on <OldViewController: 0x98765432> which is already presenting <UIAlertController: 0x24682468>

The solution to this seems to be to react to the didDismissWithButtonIndex method on UIAlertViewDelegate. When this is done, the alert controller appears to be gone on the iOS 8 iPad by the time that the new view controller is presented, and all is happy.

BTW, a posthumous Happy Birthday to Paul Butterfield, a fantastic artist who left us way too early. Luckily he is being immortalized in the Rock and Roll Hall of Fame, so more people should learn about him and experience his music.

CLGeocoder with built-in NSCache

In case you were wondering, Apple “recommends” that you only make one call per minute to their geocoding system. I can kind of understand the reasoning behind this, as they do not want to let people abuse the system. If you have a bunch of geocoding requests that you need to make within a short amount of time, you will not be cut off immediately if you push through a bunch of requests within seconds, but eventually you will get clipped. Now, if the requests you make are part of a table view that is scrolling, wouldn’t it be neat if you could find a CLGeocoder with built-in NSCache?

Well now you can. Please check out my GitHub repository for BPGeocoder:

This class inherits from CLGeocoder and you use it as a replacement for CLGeocoder, except that it maintains its own NSCache of addresses that it has geocoded, and if you pass in an address it has already seen, it does not bother contacting the Apple servers, it just returns back the cached results it found earlier.

BTW, Happy Birthday to Terry Farrell, who played Valerie in Back To School and Lt. Dax on Star Trek: Deep Space 9, which was the best Star Trek series, IMHO. (Additionally, I think we need to get an internet campaign going to get IMDb to change the cast photo on their DS9 page to be one with Terry. Leave a comment if you agree. Sorry, Nicole!)

EXC_BAD_ACCESS when creating Address Book records on iOS

I have this code in one of my apps that creates some test records in the Contacts app, so that I can quickly build up some address book data for testing purposes. However, I just uncommented out this code for the first time in a long time, and now I am getting some kind of object release EXC_BAD_ACCESS exception when creating Address Book records on newer versions of iOS.

I tracked the problem down to this line:

ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABPersonPhoneProperty);

While this used to work just fine, I needed to change it to this line:

ABMutableMultiValueRef phoneNumberMultiValue = ABMultiValueCreateMutable(kABMultiStringPropertyType);

And now my address book records are created without any kind of memory crash.

BTW, Happy Anniversary to Godzilla, who premiered in Japanese theaters on this day 60 years ago. Additional BTW, for U.S. readers, don’t forget to get out and vote tomorrow.

Monoprice mechanical keyboard

On a whim, I decided to take the plunge and pick up a Monoprice mechanical keyboard and see what all the fuss was about. Oh sure, I was alive during the clickety-clack days of the IBM PC-XT keyboard, which I am convinced was louder then using a Selectric typewriter.

The keyboard I purchased was a Monoprice MP-G9 mechanical gaming keyboard. This keyboard does not have backlighting, and has the Cherry MX Black switches. I must say I am impressed with the keyboard. It has that old timey feel without being deafeningly loud.

I could have spent a lot more money on a keyboard, but since I was not sure I was going to like this type of keyboard, I tried to spend as little as possible. I would have to say that my next keyboard purchase will be a more expensive model.

The only issue that I had with it was that I wanted to use it with my Mac, and the Windows and Alt keys are backwards from the configuration on my standard Apple keyboard. Luckily, the Keyboard section of System Preferences allows you to alter the modifier keys, so I went and assigned Option to the Command key and vice versa, and now all is happy.

BTW, Happy 45th Birthday to ARPANET, which first went online on this day in 1969.

Software update

(I have been waiting a while to post this picture, it seemed like a good idea to do it today what with the huge flap about the iOS 8.0.1 software update failure…)

I think my computer is trying to tell me that there is a software update…


BTW, Happy Birthday to Justin Bruening, who played Michael Knight on the Knight Rider TV series from 2008.

Cross a bridge at night

OK, here is a scenario. Four people on a journey together need to cross a bridge at night as quickly as possible. Among the four of them, they have one flashlight. They cannot continue their journey until all four reach the other side together. Since the bridge is narrow and slippery, and it is pitch black out being night and all, they decide to have two people cross with the flashlight, then one person returns with the flashlight back to the original side, and they continue until everyone is on the other side.

Oh, and also, the people can all walk at different paces, so when two people cross together, it takes them the amount of time that it takes the slower person to cover the distance.

For example, let’s say that the four people that need to cross can cover the distance of the bridge in 1 minute, 2 minutes, 5 minutes, and 10 minutes. What would be the shortest possible time?

The naive solution would be to have the 1 minute person be the primary flashlight runner and send them with the 2 minute person, return, then the 5 minute person, return, and finally cross with the 10 minute person, for a grand total of 19 minutes.

Now of course this is not the optimal solution, but more on that in a minute.

So how would we design an algorithm to solve this problem? Conventional wisdom says to create some kind of tree where you iterate through all of the possible combinations of initial crossings, then off those branches, combinations of reverse crossings, etc. Then once the tree is built, you can walk to all the branch tips and calculate the times, and then just display the shortest time.

But why do something logical? With all this computing power, I say that we implement my favorite algorithm for producing solutions to problems… The Monte Carlo method.

Here is the code for a C# .NET console app I threw together to solve this issue:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BridgeAtNight
    public class BridgeState
        public List<int> peopleOnLeft;
        public List<int> peopleOnRight;
        public int totalTime;
        public string peopleMovement;
        public BridgeState(int[] people)
            totalTime = 0;
            peopleMovement = "";
            peopleOnLeft = new List<int>(people);
            peopleOnRight = new List<int>();
        public void MoveLeftToRight(int leftToRight1, int leftToRight2)
            peopleMovement = peopleMovement + string.Format("{0}>> {1}>> ", leftToRight1, leftToRight2);
            totalTime += Math.Max(leftToRight1, leftToRight2);
        public void MoveRightToLeft(int rightToLeft)
            peopleMovement = peopleMovement + string.Format("{0}<< ", rightToLeft);
            totalTime += rightToLeft;
        public void SolveWithNaivete()
            while (peopleOnLeft.Count > 1)
                // move 2 people from the left to the right
                int leftToRight1 = peopleOnLeft[0];
                int leftToRight2 = peopleOnLeft[1];
                MoveLeftToRight(leftToRight1, leftToRight2);
                // move 1 person from right to left if there are any remaining people on the left
                if (peopleOnLeft.Count > 0)
                    int rightToLeft = peopleOnRight[0];
            Console.WriteLine("Solution with naivete:");
            Console.WriteLine(string.Format("Time: {0} minutes", totalTime));
            Console.WriteLine(string.Format("Sequence: {0}", peopleMovement));
        public void SolveRandomly()
            Random rnd = new Random();
            while (peopleOnLeft.Count > 1)
                // move 2 people from the left to the right
                var leftToRightRandom = peopleOnLeft.OrderBy(x => rnd.Next()).Take(2).ToList();
                int leftToRight1 = leftToRightRandom[0];
                int leftToRight2 = leftToRightRandom[1];
                MoveLeftToRight(leftToRight1, leftToRight2);
                // move 1 person from right to left if there are any remaining people on the left
                if (peopleOnLeft.Count > 0)
                    var rightToLeftRandom = peopleOnRight.OrderBy(x => rnd.Next()).Take(1).ToList();
                    int rightToLeft = rightToLeftRandom[0];
    class Program
        static void Main(string[] args)
            BridgeState naiveBridgeState = new BridgeState(new int[] { 1, 2, 5, 10 });
            List<string> bestTimeResults = new List<string>();
            int bestTime = 999999;
            for (int idx = 1; idx < 1000000; idx++)
                BridgeState randomBridgeState = new BridgeState(new int[] { 1, 2, 5, 10 });
                if (randomBridgeState.totalTime < bestTime)
                    Console.WriteLine(string.Format("Better random solution found in pass {0}:", idx));
                    Console.WriteLine(string.Format("Time: {0} minutes", randomBridgeState.totalTime));
                    Console.WriteLine(string.Format("Sequence: {0}", randomBridgeState.peopleMovement));
                    bestTime = randomBridgeState.totalTime;
                    bestTimeResults = new List<string>();
                else if (randomBridgeState.totalTime == bestTime)
                    if (!bestTimeResults.Contains(randomBridgeState.peopleMovement))
                        Console.WriteLine(string.Format("Sequence: {0}", randomBridgeState.peopleMovement));
            Console.WriteLine("Press any key to exit the application");

There are undoubtedly some optimizations I can make to this code above, such as ordering the times in the MoveLeftToRight function. However, I was kind of surprised to see this run, as sometimes the optimal solution of 17 minutes was found in the first few thousand random walk throughs, and other times it would take a few hundred thousand walk throughs before the 17 minute solution was found. To me, it did not seem like there were enough different combinations that would make it so difficult to randomly find the solution.

For those who cannot/will not run this code, the crux of the biscuit, given the times of the walkers above (1 minute, 2 minutes, 5 minutes, and 10 minutes), is to send the slowest people across together once there is someone faster on the other side. Or in other words, first send 1 and 2 across, then have 1 come back. Then, send 5 and 10 across, and have 2 come back. Then 1 and 2 make the final crossing.

BTW, Happy Talk Like A Pirate Day today.

VB.NET simpler Async Await example

Well, I couldn’t let this rest, so here is an even simpler example of doing Async Await in VB.NET.

For this example code, I created a simple forms application with two buttons named cmdSynchronous and cmdAsynchronous, a label called lblStatus, and just to demonstrate the UI locking up effect, a combo box with some entries in it. Here is the code behind this form:

Public Class Form1
    Sub LongOperation()
    End Sub
    Private Sub cmdSynchronous_Click(sender As Object, e As EventArgs) Handles cmdSynchronous.Click
        lblStatus.Text = "Running a long operation synchronously... (UI thread should lock up)"
        Application.DoEvents()  ' needed here so that the label will update

        lblStatus.Text = "Done running the long operation synchronously."
    End Sub
    Private Async Sub cmdAsynchronous_Click(sender As Object, e As EventArgs) Handles cmdAsynchronous.Click
        lblStatus.Text = "Running a long operation asynchronously... (UI thread should be fully responsive)"
        Await Task.Run(Sub()
                       End Sub)
        lblStatus.Text = "Done running the long operation asynchronously."
    End Sub
End Class

Notice that both button click events call the LongOperation method, which just sleeps for 5 seconds. However, the synchronous button click will lock up the UI (try to open the combo box, you will see that it waits until the sleep is done before displaying the choice list), whereas the asynchronous one will not.

Now in general, you would probably want to keep the tasks from piling up, as they would if you keep clicking the asynchronous button. I leave this as an exercise to the reader on preventing this problem.

BTW, Happy Birthday to Gary Hoey and Terje Rypdal, two of my favorite guitarists.