Friday, September 17, 2010

Building a ‘real’ Windows Phone 7 Twitter App Part 1

(Update – Added source code link to bottom)

In this series, I’m going to show how to build a ‘real’ twitter app.  One that uses oAuth to authenticate with twitter, can get your friend statuses, mentions and direct messages.  It will also have the ability to Tweet, Re-Tweet and view links from tweets.  I’ll show you how to localize it into the 5 languages that Windows Phone 7 Marketplace supports and how to support tombstoning (ability to restore state when the app gets interrupted by a phone call for example or the user hitting the start button then back again).  I’ll also show you how to work with Isolated Storage and the MVVM pattern.

If you saw my first post, I mentioned I was new to both Windows Phone Development and Silverlight development.  I’ve learned a great deal along the way and hope to share what I’ve learned.  I also have a lot to learn and hope that some of you will provide input on things I can improve.

I plan to make this blog very detailed so it could even beginners.  I’ll just assume you know some c#.  Hopefully more advanced folks can just skip some of these details.

Let’s jump right in.

Part 1: Solution Setup & House Cleaning

Step 1: Install the tools. 

Hopefully you’ve already done that and I won’t give any details except you can get the latest free RTM tools from: http://developer.windowsphone.com 

Step 2: Create a new project.

We’re going to make this a “Panorama” app, You could choose Pivot App instead.   The main difference is that the Panorama has a large ‘panorama’ background image.  I think the design looks great, however one draw back is the default layout gives you less room for your content than a pivot control.  The title area takes up much more space.  But I’ll leave it up to you to pick one.

You’ll want to hit the typical “File” –> “New” –> “Project” and give your app a name as well as a Location to store it.  I picked “Twitt” as my app name.

image

Hit “OK”

Wait a few seconds for the magic to happen, then build the solution.  Before you run it, there’s an important drop down at the top of Visual Studio where you can pick the target of where you want it to run.  It has two options, the emulator or a phone device.  Make sure it’s set to emulator:

image

Now you can run the app.  The emulator will launch; this takes a few seconds for the emulator to start if it’s the first time before your app is deployed.  You don’t need to shut down the emulator when you’re done.  In fact, just hit the “back” button on the bottom of the emulator and the app will exit or you can just stop debugging from within Visual Studio.  This will speed up your next launch if the emulator is kept running.  When you run it, you should see something like this:

image 

Try swiping on the screen to move to the next panoramic item:

image

Did you notice those funky looking numbers along the right edge?  Those are frame rate counters.  Open up the App.xaml.cs file and look at the constructor:

       public App()
       {
           // Global handler for uncaught exceptions.
           UnhandledException += Application_UnhandledException;

           // Show graphics profiling information while debugging.
           if (System.Diagnostics.Debugger.IsAttached)
           {
               // Display the current frame rate counters.
               Application.Current.Host.Settings.EnableFrameRateCounter = true;

               // Show the areas of the app that are being redrawn in each frame.
               //Application.Current.Host.Settings.EnableRedrawRegions = true;

               // Enable non-production analysis visualization mode,
               // which shows areas of a page that are being GPU accelerated with a colored overlay.
               //Application.Current.Host.Settings.EnableCacheVisualization = true;
           }

           // Standard Silverlight initialization
           InitializeComponent();

           // Phone-specific initialization
           InitializePhoneApplication();
       }

Notice the “EnableFrameRateCounter” property is set to true during debugging.  If you don’t care about this, you can set it to false or just ignore,.  It won’t appear when you’re not debugging the app.

Here’s a look at all the files that were created when you created the solution:

image

Under “Properties” you’ll see a few interesting files.  The AppManifest.xml doesn’t contain very much and in fact I’ve never had to touch it.  Assembly info contains information about the assembly that will be created such as the app title, version, etc…

Last in “Properties” is the WMAppManifest.xml file.  It looks like this:

<?xml version="1.0" encoding="utf-8"?>

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
  <App xmlns="" ProductID="{f0b6633a-b659-4a59-a587-027322b5e096}" Title="Twitt" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"  Author="Twitt author" Description="Sample description" Publisher="Twitt">
    <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
    <Capabilities>
      <Capability Name="ID_CAP_GAMERSERVICES"/>
      <Capability Name="ID_CAP_IDENTITY_DEVICE"/>
      <Capability Name="ID_CAP_IDENTITY_USER"/>
      <Capability Name="ID_CAP_LOCATION"/>
      <Capability Name="ID_CAP_MEDIALIB"/>
      <Capability Name="ID_CAP_MICROPHONE"/>
      <Capability Name="ID_CAP_NETWORKING"/>
      <Capability Name="ID_CAP_PHONEDIALER"/>
      <Capability Name="ID_CAP_PUSH_NOTIFICATION"/>
      <Capability Name="ID_CAP_SENSORS"/>
      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/>
    </Capabilities>
    <Tasks>
      <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
    </Tasks>
    <Tokens>
      <PrimaryToken TokenID="TwittToken" TaskName="_default">
        <TemplateType5>
          <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
          <Count>0</Count>
          <Title>Twitt</Title>
        </TemplateType5>
      </PrimaryToken>
    </Tokens>
  </App>
</Deployment>

The <App> node contains some app specific information that you can change if you like.

The <IconPath> node points to the icon that will appear for the installed app.  This icon is a 62x62 pixel icon and you can see the default “ApplicationIcon.png” file exists at the root of the project. 

The <Capabilities> section is important, it tells the OS what capabilities of the phone your application will be using.  We won’t be using most of the ones listed except for the web browser control and networking layer.  So I removed the rest of them:

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
  <App xmlns="" ProductID="{f0b6633a-b659-4a59-a587-027322b5e096}" Title="Twitt" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"  Author="Twitt author" Description="Sample description" Publisher="Twitt">
    <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
    <Capabilities>
      <Capability Name="ID_CAP_NETWORKING"/>
      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/>
    </Capabilities>
    <Tasks>
      <DefaultTask  Name ="_default" NavigationPage="MainPage.xaml"/>
    </Tasks>
    <Tokens>
      <PrimaryToken TokenID="TwittToken" TaskName="_default">
        <TemplateType5>
          <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
          <Count>0</Count>
          <Title>Twitt</Title>
        </TemplateType5>
      </PrimaryToken>
    </Tokens>
  </App>
</Deployment>

Notice the <DefaultTask> node.  It points to Mainpage.xaml.  This is the first xaml page that will load when the app launches.  I personally like to put all the view xaml files in a folder called “Views”.  Right click on the project and add a folder called “Views”.  Then move the MainPage.xaml and MainPage.xaml.cs into this folder. It should look like this:

image

Now we have a “Views” directory and also a “ViewModels” directory that will contain the viewModels that go with each view (more about that in a future post).

Since we made this change we also have to change <DefaultTask> node we saw above to point to this new MainPage.xaml location, otherwise it won’t find it and will throw an exception when you run it.  Try running it if you don’t believe me!

Here’s the change:

<?xml version="1.0" encoding="utf-8"?>

<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2009/deployment" AppPlatformVersion="7.0">
  <App xmlns="" ProductID="{f0b6633a-b659-4a59-a587-027322b5e096}" Title="Twitt" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"  Author="Twitt author" Description="Sample description" Publisher="Twitt">
    <IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
    <Capabilities>
      <Capability Name="ID_CAP_NETWORKING"/>
      <Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/>
    </Capabilities>
    <Tasks>
      <DefaultTask  Name ="_default" NavigationPage="Views/MainPage.xaml"/>
    </Tasks>
    <Tokens>
      <PrimaryToken TokenID="TwittToken" TaskName="_default">
        <TemplateType5>
          <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
          <Count>0</Count>
          <Title>Twitt</Title>
        </TemplateType5>
      </PrimaryToken>
    </Tokens>
  </App>
</Deployment>

Try running it now!  Notice anything strange?  I got this:

image

EEK, what happened to the background panorama image?  Don’t panic, we’ll fix it.  Open up the MainPage.xaml file and locate where the PanoramaBackground.png is set in the <ImageBrush> node:

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <!--Panorama control-->
    <controls:Panorama Title="my application">
        <controls:Panorama.Background>
            <ImageBrush ImageSource="PanoramaBackground.png"/>
        </controls:Panorama.Background>

Since we moved the MainPage.xaml out of the root and into a new folder and since the system is using relative paths, we’ll need to update the path for this image.  Here’s an addition I usually like to do with most apps.  Create a “Resources” folder for images and any other resources, such as localized resource files (more on those in a future post).

So once again right click on the project and “Add” –> “New Folder” and call it “Resources”.  Then add a child folder to this one called “Images”.  Now move the PanoramaBackground.png to the “Resources/Images” folder.  Your structure should now look like this:

image

We could also move the other images there but I’ll leave them at the root for now and leave the App.xaml there.

Now we can change the MainPage.xaml code to point to this new location:

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <!--Panorama control-->
    <controls:Panorama Title="my application">
        <controls:Panorama.Background>
            <ImageBrush ImageSource="..\Resources\Images\PanoramaBackground.png"/>
        </controls:Panorama.Background>

You should notice the background image comes back if you run the app.

Let’s go back for one more look at the WMAppManifest.xml file,.  There’s a “Tokens” node at the bottom, that looks like this:

<Tokens>
  <PrimaryToken TokenID="TwittToken" TaskName="_default">
    <TemplateType5>
      <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
      <Count>0</Count>
      <Title>Twitt</Title>
    </TemplateType5>
  </PrimaryToken>
</Tokens>

You may be wondering what the Background.png image is for.  This is a 173x173 pixel image that shows up on the Windows Phone start screen if the user “pins” the app.  To check this out, go back to the emulator.  As long as you didn’t close it, the app will still be on the emulator and you can run it from there.  You should see this screen:

image

Hit that top right arrow and as long as you’ve run the app at least once without shutting down the emulator you should get this:

image

There’s our “Twitt” app and that icon you see is the “ApplicationIcon.png” we talked about.  Now hold down the mouse button on “Twitt” and you will get a pop-up menu:

image

Select “pin to start” and it’ll take you back to the start page:

image

And voila, there’s the “Background.png” image.  Notice the text title that says “Twitt”.  You may want to remove the text and have an icon that has the name in the image.  To remove the name (or change it for that matter), go back to the WMAppManifest.xml and locate the title node:

<Tokens>
     <PrimaryToken TokenID="TwittToken" TaskName="_default">
       <TemplateType5>
         <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
         <Count>0</Count>
         <Title>Twitt</Title>
       </TemplateType5>
     </PrimaryToken>
   </Tokens>

You can clear it:

<Tokens>
     <PrimaryToken TokenID="TwittToken" TaskName="_default">
       <TemplateType5>
         <BackgroundImageURI IsRelative="true" IsResource="false">Background.png</BackgroundImageURI>
         <Count>0</Count>
         <Title></Title>
       </TemplateType5>
     </PrimaryToken>
   </Tokens>

Now re-run the app to deploy the xap file again to the emulator. 

By the way, when you compile a Windows Phone 7 app (or Silverlight app) you get a “xap” file (pronounced zap) that is really just a zipped file.  Go look in the output directory of our solution and if you change the extention to .zip  you can then unzip it and see what’s inside.  This one single file gets deployed to the phone.

Once you’ve re-run the app, exit the app.  Notice the text is still there?  It doesn’t update the pinned item for some reason when you redeploy, but if you “unpin” it then “pin” it again it will update and you’ll see the title is now gone:

image

Another neat thing about this image is its supported transparency.  If you make an icon with a transparent background it will pick up the user’s “accent” color and apply that to the background.  In this case it would be blue and match the Internet Explorer icon shown in the image.

The last image to look at is the SplashScreenImage.jpg.  This is the image that comes up briefly while the app is starting.  Notice it’s a jpg image and not a png image.  This is for performance reasons. JPG’s are lighter weight and you don’t want heavy processing going on like transparency while starting up the app.  In fact, if your app takes too long to start, it’s possible the OS will kill it before it completes. 

The default SplashScreen looks like this:

image

Right now our 3 images look pretty plain (AppliationIcon.png, Background.png and SplashScreenImage.jpg).  I’ll leave this as a side exercise but what I did is open each file up in Paint.Net .  You can use your favorite image editor instead or even Microsoft Paint. 

I changed my graphics to look like these:

image   image   image

Most people probably leave these details until the end, but sometimes it’s nice to get these out of the way early on.  I also think it looks better as you start showing people, since it gives it a real app feel.  You might also want to change the panoramic background but I decided to leave mine as is.

Let’s do one last thing, which is to set our app name in the MainPage.xaml instead of the default “my application”.

In the MainPage.xaml change the “Title” property to your app name:

<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
    <!--Panorama control-->
    <controls:Panorama Title="Twitt">

image

In summary, we have created a brand new Panorama based application, did a little house cleaning of the files, modified our icons and learned a little about the various project files.

Next up will be setting up Twitter Authentication which uses oAuth (Open Authentication). 

Two blogs that have been very helpful for me have been Jeff Wilcox's and Peter Torr.  These are both great resources to check out.

You can download the source code here: http://twitt.codeplex.com/

Sam

20 comments:

  1. Big thanks Sam. Great article with interesting facts. Thanks for sharing.

    ReplyDelete
  2. Hi Sam

    Where is the link to download the code?

    ReplyDelete
  3. Hi Sam

    The code link keeps redirecting me to my live profile. After loging in using my live account nothing happens. Unable to download the code. Am not sure if its just me :(

    ReplyDelete
  4. Same experience here with the download link. Good thing I have a Live home page :).

    ReplyDelete
  5. try this link http://cid-229b74769854b9a9.office.live.com/self.aspx/Twitt/Twitt%20Part%203.zip?client=wnf

    ReplyDelete
  6. The source code can now be found at: http://twitt.codeplex.com/

    ReplyDelete
  7. Sam! How's it going man?

    Hey, I stumbled across this because it is one of the top Google image results for "Don't Panic".

    Go figure.

    Anyway, thought I'd say hello since it is crazy that this randomly came up.

    ReplyDelete
  8. Hey Bruce!

    That is funny! Let's do lunch sometime!

    ReplyDelete
  9. Hello Sam,
    But I still confused because when I open AppManifest.xml they show the different code that doesn't like your code above.
    Is any solutions?

    ReplyDelete
  10. Sam, your blog is great!, had to change a few things to cater to the new stuff but overall.. awesome!. Was wondering if you cuold tell how to call things like trends, favorites,and all that new rest (twitter) stuff worked etc. becauase i understand how to do the rest service but how to do specifics is my question? guess im not ballin like you haha. No I was comparing this app to the actual twitter app and it hinkg this is WAY more amazing.. would you expand on all those bs details for fun? If not I'd like to learn and worth with u I'm a new but I've already made about 10 apps tryin to make some WP7 app happy (and cater to those newschool 8 fools too!)

    ReplyDelete
  11. I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work. Buy twitter followers

    ReplyDelete
  12. One of a nicest article i've read very informative keep it up. Buy USA Youtube Views

    ReplyDelete
  13. interesting information, this would fasten the developments basically teaching how to start how to do it, you should try social media marketing in malaysia

    ReplyDelete
  14. It’s awesome to pay a quick visit this web page and reading the views of all friends regarding this post, while I am also eager of getting knowledge.

    how can i get Buy keek Package on keek and get followers on keek fast and free

    ReplyDelete
  15. It’s awesome to pay a quick visit this web page and reading the views of all friends regarding this post, while I am also eager of getting knowledge.

    how can i get Buy keek Package on keek and get followers on keek fast and free

    ReplyDelete
  16. Great wordpress blog here.. It’s hard to find quality writing like yours these days. I really appreciate people like you! take care…
    Buy Vine Package

    ReplyDelete
  17. hi...Im student from Informatics engineering nice article,
    thanks for sharing :)

    ReplyDelete
  18. If you need a good tool for windows localization, I recommend https://poeditor.com/. You can translate your resx or xml files really fast using this tool, I am doing it for my apps.

    ReplyDelete
  19. Keep up the superb piece of work, I read few posts on this site and I believe that your blog is real interesting and holds circles of excellent info . Really thank you! Fantastic.
    - Buy Instagram Likes on instagram and get followers on instagram fast and free || Buy keek Likes on keek and get followers on keek fast and free

    ReplyDelete