iPhone SDK vs Windows Phone 7 Series SDK Challenge, Part 1: Hello World!

In this series, I will be taking sample applications from the iPhone SDK and implementing them on Windows Phone 7 Series. My goal is to do as much of an “apples-to-apples” comparison as I can. This series will be written to not only compare and contrast how easy or difficult it is to complete tasks on either platform, how many lines of code, etc., but I’d also like it to be a way for iPhone developers to either get started on Windows Phone 7 Series development, or for developers in general to learn the platform.

Here’s my methodology:

  1. Run the iPhone SDK app in the iPhone Simulator to get a feel for what it does and how it works, without looking at the implementation
  2. Implement the equivalent functionality on Windows Phone 7 Series using Silverlight.
  3. Compare the two implementations based on complexity, functionality, lines of code, number of files, etc.
  4. Add some functionality to the Windows Phone 7 Series app that shows off a way to make the scenario more interesting or leverages an aspect of the platform, or uses a better design pattern to implement the functionality.

You can download Microsoft Visual Studio 2010 Express for Windows Phone CTP here, and the Expression Blend 4 Beta here.

Hello World!

simulator[1] Of course no first post would be allowed if it didn’t focus on the “hello world” scenario.  The iPhone SDK follows that tradition with the Your First iPhone Application walkthrough.  I will say that the developer documentation for iPhone is pretty good.  There are plenty of walkthoughs and they break things down into nicely sized steps and do a good job of bringing the user along. 

As expected, this application is quite simple.  It comprises of a text box, a label, and a button.  When you push the button, the label changes to “Hello” plus the  word you typed into the text box.  Makes perfect sense for a starter application. 

There’s not much to this but it covers a few basic elements:

  • Laying out basic UI
  • Handling user input
  • Hooking up events
  • Formatting text

So, let’s get started building a similar app for Windows Phone 7 Series!

Implementing the UI:

UI in Silverlight (and therefore Windows Phone 7) is defined in XAML, which is a declarative XML language also used by WPF on the desktop.  For anyone that’s familiar with similar types of markup, it’s relatively straightforward to learn, but has a lot of power in it once you get it figured out.  We’ll talk more about that.

This UI is very simple.  When I look at this, I note a couple of things:

  • Elements are arranged vertically
  • They are all centered

So, let’s create our Application and then start with the UI.  Once you have the the VS 2010 Express for Windows Phone tool running, create a new Windows Phone Project, and call it Hello World:

image

Once created, you’ll see the designer on one side and your XAML on the other:

image

Now, we can create our UI in one of three ways:

  1. Use the designer in Visual Studio to drag and drop the components
  2. Use the designer in Expression Blend 4 to drag and drop the components
  3. Enter the XAML by hand in either of the above

We’ll start with (1), then kind of move to (3) just for instructional value.

To develop this UI in the designer:

First, delete all of the markup between inside of the Grid element (LayoutRoot).  You should be left with just this XAML for your MainPage.xaml (i shortened all the xmlns declarations below for brevity):

    1:  <phoneNavigation:PhoneApplicationPage 
    2:      x:Class="HelloWorld.MainPage"
    3:     xmlns="...[snip]"
    4:      FontFamily="{StaticResource PhoneFontFamilyNormal}"
    5:      FontSize="{StaticResource PhoneFontSizeNormal}"
    6:      Foreground="{StaticResource PhoneForegroundBrush}">
    7:   
    8:      <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">
    9:   
   10:      </Grid>
   11:   
   12:  </phoneNavigation:PhoneApplicationPage>

We’ll be adding XAML at line 9, so that’s the important part.

Now,

  1. Click on the center area of the phone surface
  2. Open the Toolbox and double click “StackPanel”
  3. Double click “TextBox”
  4. Double click “TextBlock”
  5. Double click “Button”

That will create the necessary UI elements but they won’t be arranged quite right.  We’ll fix it in a second. 

Here’s the XAML that we end up with:

    1:  <StackPanel Height="100" HorizontalAlignment="Left" Margin="10,10,0,0" Name="stackPanel1" VerticalAlignment="Top" Width="200">
    2:           <TextBox Height="32" Name="textBox1" Text="TextBox" Width="100" />
    3:           <TextBlock Height="23" Name="textBlock1" Text="TextBlock" />
    4:           <Button Content="Button" Height="70" Name="button1" Width="160" />
    5:  </StackPanel>

The designer does it’s best at guessing what we want, but in this case we want things to be a bit simpler.

So we’ll just clean it up a bit.  We want the items to be centered and we want them to have a little bit of a margin on either side, so here’s what we end up with.  I’ve also made it match the values and style from the iPhone app:

    1:  <StackPanel Margin="10">
    2:      <TextBox Name="textBox1" HorizontalAlignment="Stretch" Text="You" TextAlignment="Center"/>
    3:      <TextBlock Name="textBlock1" HorizontalAlignment="Center" Margin="0,100,0,0" Text="Hello You!" />
    4:      <Button Name="button1" HorizontalAlignment="Center" Margin="0,150,0,0" Content="Hello"/>
    5:  </StackPanel>  

Now let’s take a look at what we’ve done there.

  • Line 1: We removed all of the formatting from the StackPanel, except for Margin, as that’s all we need.  Since our parent element is a Grid, by default the StackPanel will be sized to fit in that space.  The Margin says that we want to reserve 10 pixels on each side of the StackPanel.
  • Line 2: We’ve set the HorizontalAlignment of the TextBox to “Stretch”, which says that it should fill it’s parent’s size horizontally.  We want to do this so the TextBox is always full-width.  We also set TextAlignment to Center, to center the text.
  • Line 3: In contrast to the TextBox above, we don’t care how wide the TextBlock is, just so long as it is big enough for it’s text.  That’ll happen automatically, so we just set it’s Horizontal alignment to Center.  We also set a Margin above the TextBlock of 100 pixels to bump it down a bit, per the iPhone UI.
  • Line 4: We do the same things here as in Line 3.

Here’s how the UI looks in the designer:

image

Believe it or not, we’re almost done!

Implementing the App Logic

Now, we want the TextBlock to change it’s text when the Button is clicked. 

In the designer, double click the Button to be taken to the Event Handler for the Button’s Click event.  In that event handler, we take the Text property from the TextBox, and format it into a string, then set it into the TextBlock.  That’s it!

    1:  private void button1_Click(object sender, RoutedEventArgs e)
    2:  {
    3:      string name = textBox1.Text;
    4:   
    5:      // if there isn't a name set, just use "World"
    6:      if (String.IsNullOrEmpty(name))
    7:      {
    8:          name = "World";
    9:      }
   10:   
   11:      // set the value into the TextBlock
   12:      textBlock1.Text = String.Format("Hello {0}!", name);
   13:   
   14:  }

We use the String.Format() method to handle the formatting for us. 

Now all that’s left is to test the app in the Windows Phone Emulator and verify it does what we think it does!

image

And it does!

Comparing against the iPhone

Looking at the iPhone example, there are basically three things that you have to touch as the developer:

1) The UI in the Nib file

2) The app delegate

3) The view controller

Counting lines is a bit tricky here, but to try to keep this even, I’m going to only count lines of code that I could not have (or would not have) generated with the tooling.  Meaning, I’m not counting XAML and I’m not counting operations that happen in the Nib file with the XCode designer tool.  So in the case of the above, even though I modified the XAML, I could have done all of those operations using the visual designer tool.  And normally I would have, but the XAML is more instructive (and less steps!).  I’m interested in things that I, as the developer have to figure out in code.  I’m also not counting lines that just have a curly brace on them, or lines that are generated for me (e.g. method names that are generated for me when I make a connection, etc.)

So, by that count, here’s what I get from the code listing for the iPhone app found here:

HelloWorldAppDelegate.h: 6

HelloWorldAppDelegate.m: 12

MyViewController.h: 8

MyViewController.m: 18

Which gives me a grand total of about 44 lines of code on iPhone.  I really do recommend looking at the iPhone code for a comparison to the above.

Now, for the Windows Phone 7 Series application, the only code I typed was in the event handler above

Main.Xaml.cs: 4

So a total of 4 lines of code on Windows Phone 7.  And more importantly, the process is just A LOT simpler.  For example, I was surprised that the User Interface Designer in XCode doesn’t automatically create instance variables for me and wire them up to the corresponding elements.  I assumed I wouldn’t have to write this code myself (and risk getting it wrong!).  I don’t need to worry about view controllers or anything.  I just write my code.  This blog post up to this point has covered almost every aspect of this app’s development in a few pages.  The iPhone tutorial has 5 top level steps with 2-3 sub sections of each.

Now, it’s worth pointing out that the iPhone development model uses the Model View Controller (MVC) pattern, which is a very flexible and powerful pattern that enforces proper separation of concerns.  But it’s fairly complex and difficult to understand when you first walk up to it.  Here at Microsoft we’ve dabbled in MVC a bit, with frameworks like MFC on Visual C++ and with the ASP.NET MVC framework now.  Both are very powerful frameworks.  But one of the reasons we’ve stayed away from MVC with client UI frameworks is that it’s difficult to tool.  We haven’t seen the type of value that beats “double click, write code!” for the broad set of scenarios.

Another thing to think about is “how many of those lines of code were focused on my app’s functionality?”.  Or, the converse of “How many lines of code were boilerplate plumbing?”  In both examples, the actual number of “functional” code lines is similar.  I count most of them in MyViewController.m, in the changeGreeting method.  It’s about 7 lines of code that do the work of taking the value from the TextBox and putting it into the label.  Versus 4 on the Windows Phone 7 side.  But, unfortunately, on iPhone I still have to write that other 37 lines of code, just to get there.

10% of the code, 1 file instead of 4, it’s just much simpler.

 

 

Making Some Tweaks

It turns out, I can actually do this application with ZERO lines of code, if I’m willing to change the spec a bit. The data binding functionality in Silverlight is incredibly powerful.  And what I can do is databind the TextBox’s value directly to the TextBlock.  Take some time looking at this XAML below.  You’ll see that I have added another nested StackPanel and two more TextBlocks.  Why?  Because that’s how I build that string, and the nested StackPanel will lay things out Horizontally for me, as specified by the Orientation property.

    1:  <StackPanel Margin="10">
    2:      <TextBox Name="textBox1" HorizontalAlignment="Stretch" Text="You" TextAlignment="Center"/>
    3:      <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,100,0,0" >
    4:          <TextBlock Text="Hello " />
    5:          <TextBlock Name="textBlock1"  Text="{Binding ElementName=textBox1, Path=Text}"   />
    6:          <TextBlock Text="!" />
    7:      </StackPanel>            
    8:      <Button Name="button1" HorizontalAlignment="Center" Margin="0,150,0,0" Content="Hello" Click="button1_Click" />
    9:  </StackPanel>

Now, the real action is there in the bolded TextBlock.Text property:

 Text="{Binding ElementName=textBox1, Path=Text}" 

That does all the heavy lifting.  It sets up a databinding between the TextBox.Text property on textBox1 and the TextBlock.Text property on textBlock1. As I change the text of the TextBox, the label updates automatically.

In fact, I don’t even need the button any more, so I could get rid of that altogether.  And no button means no event handler.  No event handler means no C# code at all. 

Want to see more? Check out Part Two.

HelloWorld.zip