My Thoughts After Switching from iPhone to Android

Its been a month since I made the switch from iPhone to Android and I thought others might benefit from my experience. What do I miss about my iPhone? What do I love about my Android? How do they compare?

First some background
I have been a loyal iPhone user for the last three years (3GS). I also love Apple products and use a MacBook for my personal laptop even though I am primarily a Windows developer. I made the switch to Android because I wanted a bigger screen and wanted to see what an open platform had to offer. I am active in open source software development, so Android seemed to fit my personality. All that being said, I don’t feel that I am biased toward one platform or the other.

The Android phone I switched to is the Samsung Galaxy Nexus running Ice Cream Sandwich (Android 4.0).

What do I miss about my iPhone?
To be honest, if I had written this article only two weeks in to using my new Android, I would have said I wanted to go back to the iPhone. However, at this point (one month in), I can confidently say I am sold on Android. It took me a while to get comfortable (and overcome my co-dependence on iTunes), but I an over the hump and there’s no turning back. However there are a few things I do miss about my iPhone.

Touch free voice dialing
When voice dialing on the iPhone I never needed to look at, or touch the phone screen. Even when I had multiple numbers for the contact I was calling, it simply asked me which one I wanted to call and I could respond with my voice and it would call the correct number. It was all totally hands-free.

The Android is a completely different experience. I have to turn on the screen to find the voice button and push it. Then I can say “call <name>”. Then, I have to look at the screen again to confirm it found the right contact and select the number to call. I have to do this even if there is only one number for that contact. It’s very clumsy, and dangerous when driving. Luckily, I seldom make calls while driving.

Stability
I have rebooted my Android phone more times in the last month than I did my iPhone in the entire three years I owned it. Granted, I got the Galaxy Nexus phone the day it was released, and it is the first phone to run Ice Cream Sandwich (the latest version of android OS–a major version release), so it makes sense that stability would be somewhat of an issue. However, even when iOS 5 was first released (also a major version release), I didn’t experience this level of difficulty. The stability has been getting better lately. Its really not that big of a problem…more of an annoyance, but I am curious to see what the future holds.

App selection
Android’s app selection is quite good. There are just a few apps I had for the iPhone that are missing in the Android market. The iPhone appears to get development priority in the mobile app space. This is odd given that Android has a considerably larger market share. Apparently the cultures are quite different. iPhone users are far more willing to spend money in the app store than Android users. So currently, the iPhone presents a better ROI, so it gets implemented first. Hopefully this will change as the Android platform continues to mature. There has been a dramatic increase in both the quantity and quality of Android apps in the market in the last year–a trend I expect to continue.

What do I love about Android?
Diversity of hardware options
There are only a handful of iPhone models, which limits your options as a consumer. However, this limitation it comes with the added benefit of increased stability. Since there is a very limited set of hardware to support, Apple can guarantee that apps will run smoothly on all the current iPhone models.

Android, on the other hand, is an open platform that runs on a very diverse range of hardware. There are many models made by many manufacturers. This presents a diverse number of options to the consumer, but at the cost of stability. It simply isn’t feasible to test every app against every known hardware configuration.

But because the platform is open, and any manufacturer may enter the market (unlike Apple, which is the sole designer and manufacturer), there are more designers and manufacturers driving innovation in the hardware. As a consumer, this means you have more options to choose from: large phones, small phones, phones with 3D screens, phones with external memory cards, phones with HDMI outputs, etc. etc.

Customizable user experience
I really like the ability to customize and tweak my phone to work exactly how I want it to. For example, I am using a custom keyboard called SlideIT. Rather than typing each letter one at a time, I just slide over the letters to form words. It is much faster than conventional typing. I just showed it to my wife and she loved it and asked me to install it on her phone. “Sorry sweetie, your iPhone doesn’t allow custom keyboards.” I had to tell her.

The customizable nature of Android goes far beyond just keyboards. Its baked in to the OS–part of it’s very philosophy. Almost anything can be customized or tweaked. And if it can’t, you can always open the source code and change it yourself.

Better app integration
Android makes app integration much easier. The iPhone requires the developers of the app to explicitly integrate with one another. For instance, if you want to use files from your DropBox or other third party app on the iPhone, you must find an app where the developer explicitly wrote in support for DropBox. If they didn’t, the app wont integrate. On Android, any app can access your DropBox because it can just look at its files via the file system. The iPhone does not expose its file system to the user in the name of simplicity.

As another example, if you are want to integrate with your favorite Twitter app you can simply install it and any app that supports sharing will be able to share over your Twitter app natively. Integration on Android is an OS-supported concern, its not left up to the app developers to decide what apps to integrate with. Its based on what apps you have installed and what actions they can support. This allows for much greater flexibility and lets apps integrate with one another easily by decoupling them inherently in the OS.

I prefer Java over ObjectiveC
Yes, yes, I realize my aversion to ObjectiveC is somewhat subjective. To me, ObjectiveC feels like an antiquated language. It just doesn’t feel natural. It has a much steeper learning curve for the average developer than Java. I imagine this is a non-issue once you learn the language. But it presents a high cost of entry that many are unwilling to pay. I admit that being a C# developer does give me a certain bias towards Java since they are so similar.

Freedom
Apple is very restrictive in what apps they allow in the app store. It is commonplace for an app to be pulled from the app store if it allows you to do something Apple thinks you shouldn’t be able to do. This type of thing never happens in the Android market.

While I consider Apple’s tight-fisted control over their app store as a disadvantage, I must admit that it does result in higher quality apps on the app store. They have much higher standards for an app to be accepted into the app store, and reject apps that don’t meet them.

In conclusion
I think it all boils down to the type if user you are. If you are a power user who likes to tweak and hack, then android is right for you. If you value stability and simplicity and don’t mind being restricted in what you are allowed to do, then you will love the iPhone. To each his own.

Posted in Android, iPhone, Mobile | Tagged , , | 1 Comment

Error loading .NET 4.0 assembly in TeamCity using MSpec

When we migrated our tests from NUnit to MSpec (Machine.Specifications), we encountered the following error:

Could not load file or assembly 'file:///C:\BuildAgent\work\c7e220bd4bfc29dc\bin\dependencies\SomeProject.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

After some Googling, I realized that the default MSpec runner (MSpec.exe) was not built using .NET 4.0. Because our assembly (SomeProject.dll in the error above) was a .NET 4.0 assembly, we were getting this error.

The fix was to use the mspec-clr4.exe executable as the test runner instead. This exe is shipped with newer versions of MSpec (we're on Machine.Specifications version 0.5). The clr4 version of the runner is built on .NET 4.0 and works perfectly.

To do this in TeamCity, simply add the full path to the exe in the "Path to MSpec.exe" field in TeamCity's MSpec build step. Even though the field label says it is expecting MSpec.exe, if you give it a path to mspec-clr4.exe, it will use it.

Posted in .NET, Continuous Integration, MSpec, TeamCity | Tagged , , , | Leave a comment

Upgrading Java for Firefox on 64-bit Windows

If you are on a 64-bit Windows machine and are getting a notification that your Java plugin version is out of date in Firefox even after installing the latest version, you need to install the 32-bit version of Java.

Firefox runs as a 32-bit application on Windows, so it uses the 32-bit version of Java. I should have read the fine print on the Java website. It tells you to install both 64 and 32-bit versions if you are on a 64-bit system, but are running a 32-bit browser. I did, and now my Java version is up to date in Firefox.

If you are on a 64-bit Windows machine and run Firefox, you may want to make sure you are upgraded to the latest version of 32-bit Java. You can find out by going to the Addons Manager in Firefox, clicking the “Plugins” tab on the left, then click the “Check to see if your plugins are up to date” link at the top of the page. If Java is out of date, it will give you a red warning.

Posted in Tools | Tagged , , , | Leave a comment

You ARE protecting your passwords in your config files AREN’T YOU?

When we are writing software for our clients, we have a fiduciary responsibility to ensure the security of their site.

One way to increase security is to ensure that passwords and other sensitive information are not laying around in our config files unsecured (in plain text). All too many times I have seen something like the following in a config file:

Code Sample:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="UserName" value="PresidentSkroob" />
        <add key="Password" value="12345" />
    </appSettings>
</configuration>

Fixing this problem is as easy as using Microsoft’s Data Protection API. Just encrypt the value by calling ProtectedData.Protect(). And to decrypt the value, call ProtectedData.Unprotect().

Both methods take an entropy value (salt), and a DataProtectionScope value that defines the scope for which the value should be encrypted. The scope may be one of the following: CurrentUser – Only the current user can decrypt the value, or LocalMachine – The value can only be decrypted on the local machine. CurrentUser can be a little complicated since it may require you to impersonate users in certain cases, so I just use LocalMachine. This does mean that you can’t ship the config file with the values pre-encrypted because they will not be decryptable on the machine its installed on (it can only be decrypted by the machine that encrypted it).

The functions return a byte array, so I Base64 encode the values prior to writing them to the config file. To do this, I wrote a few extension methods. Here they are:

Encryption:

/// <summary>
/// Converts a string to a protected value (encrypted using Data Protection API)
/// </summary>
/// <param name="value">The value.</param>
/// <param name="entropy">The entropy.</param>
/// <returns></returns>
public static string ToProtectedValuethis string valuestring entropy )
{
    var entropyBytes = Encoding.UTF8.GetBytesentropy );
    var valueBytes = Encoding.UTF8.GetBytesvalue );

    var securedBytes = ProtectedData.ProtectvalueBytes,
                                              entropyBytes,
                                              DataProtectionScope.LocalMachine );
    
    return securedBytes.AsBase64();
}

Decryption:

/// <summary>
/// Converts a string to a protected value (encrypted using Data Protection API)
/// </summary>
/// <param name="protectedString"></param>
/// <param name="entropy">The entropy.</param>
/// <returns></returns>
public static string ToUnprotectedStringthis string protectedStringstring entropy )
{
    var entropyBytes = Encoding.UTF8.GetBytesentropy );
    var encryptedBytes = Convert.FromBase64StringprotectedString );
    
    var decryptedBytes = ProtectedData.UnprotectencryptedBytes,
                                                  entropyBytes,
                                                  DataProtectionScope.LocalMachine );
    
    return Encoding.UTF8.GetStringdecryptedBytes );
}

After encrypting these values appropriately, your config file will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <add key="UserName" value="ADZgAAwAAAABAAAACLYg+TEHoFh88HcfvNTg0yAAAAAASAAACgAAAAEAAAAMFLpAQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA8BdWygYhjUWaw3teJQo04AQAAAACAAAAAAXFMCeBnOURIBAl2DJoQAAAAN7+sLiIZl+x9vPjC16wcmRQAAADS4d9bdlcLF9CmKrsbgGWPM29zAQ==" />
        <add key="Password" value="AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA8BdWygYhjUWaw3teJQo04AQAAAACAAAAAAADZgAAwAAAABAAAAAhfu4ghotvmXphmGWOHFfbAAAAAASAAACgAAAAEAAAAMBMv0D9/mDwktrFSVNIPcwQAAAAwg2IDL1+MOHwdx2A1cax2RQAAACZLB62COjpupN2+pW4yT8LKR5Udg==" />
    </appSettings>
</configuration>

Now you and your clients can sleep a little better at night knowing their sensitive information is just a bit more secure.

Posted in .NET, C#, Configuration, Security | Tagged , , , | Leave a comment

Video: Padawan to Jedi – A Developer Jump-Start (my presentation at Austin Code Camp 2011)

Here is the video of my “Padawan to Jedi – A Developer Jump-Start” presentation I gave last week at the Austin Code Camp 2011. It touches on all the principles, patterns, practices, and such that I have learned in my many years being a developer. I designed the Padawan2Jedi talk to present knowledge in a two-fold manner:

  1. To cover a very wide range of topics so that newcomers to the craft can gain an understanding of the full scope of modern software development practices. As such, there is not time to cover any one topic in very much detail
  2. To provide links to detailed information on each topic so that anyone could dig in deeper to learn about anything presented that they wanted to begin putting into practice

This second manner of presenting information required a different medium. If I wanted people to have access to all these links, I knew that I couldn’t just put links on my slides…no one would want to write them all down. And after all, we are technologists…I had to use something suitable to the audience, so I thought Twitter would be a more suitable way to convey the links during my presentation. I did some searching and found a script that would send tweets from the presenter notes as you moved through the slides of an Apple Keynote presentation. The script is called Keynote Tweet 2.

So as I went through the slides, the resources were tweet(ed?) out over the #Padawan2Jedi hashtag. I really wanted them to walk away with all the links to the resources, and they did. The talk lasted 2 hours, and my screencast recording software (Camtasia) died halfway through, so if you notice a change in the audio, partway through, that is why. I also had to re-record the last half of the video of the slides, so if they aren’t perfectly in sync with the talk, that is why. (Its amazing how hard it is to anticipate when to change the slide…even when you were the one talking…)

Here is the abstract that I submitted for the talk:

Are you wanting to become a better developer, but don’t know where to start? Do the terms TDD, BDD, CI, SOLID, etc. seem foreign to you? This two part presentation will cover many of the modern development practices today that every developer should know. Learn about object oriented design principles, design patterns, testing (mocking, TDD, BDD), source control, continuous integration, agile practices, plus many useful tools and techniques. That’s a lot to cover, so while some topics will be discussed in-depth, others will be touched on lightly, with resources on where to get more information. The purpose of the presentation is to give a broad overview of how modern developers work and the tools they use to be efficient and productive and provide resources so that any aspiring developer can get on the fast-track to becoming better at their craft.

Posted in .NET, Agile, C#, Continuous Integration, Continuous Learning, Design, Humility, Leading, Mocking, Patterns, Presentations, Principles, Productivity, Simplicity, Soft Skills, Test-Driven Development, Testing, Tools | Tagged , , , , , , , , , , , , , , , , | Leave a comment