(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.
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:
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:
Try swiping on the screen to move to the next panoramic item:
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:
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:
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:
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:
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:
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:
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:
Select “pin to start” and it’ll take you back to the start page:
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:
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:
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:
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">…
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
Big thanks Sam. Great article with interesting facts. Thanks for sharing.
ReplyDeleteHi Sam
ReplyDeleteWhere is the link to download the code?
Hi Sam
ReplyDeleteThe 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 :(
Same experience here with the download link. Good thing I have a Live home page :).
ReplyDeletetry this link http://cid-229b74769854b9a9.office.live.com/self.aspx/Twitt/Twitt%20Part%203.zip?client=wnf
ReplyDeleteThe source code can now be found at: http://twitt.codeplex.com/
ReplyDeleteSam! How's it going man?
ReplyDeleteHey, 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.
Hey Bruce!
ReplyDeleteThat is funny! Let's do lunch sometime!
Hello Sam,
ReplyDeleteBut I still confused because when I open AppManifest.xml they show the different code that doesn't like your code above.
Is any solutions?
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!)
ReplyDeletekeren euy!
ReplyDeleteOne of a nicest article i've read very informative keep it up. Buy USA Youtube Views
ReplyDeleteinteresting information, this would fasten the developments basically teaching how to start how to do it, you should try social media marketing in malaysia
ReplyDeleteIt’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.
ReplyDeletehow can i get Buy keek Package on keek and get followers on keek fast and free
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.
ReplyDeletehow can i get Buy keek Package on keek and get followers on keek fast and free
Great wordpress blog here.. It’s hard to find quality writing like yours these days. I really appreciate people like you! take care…
ReplyDeleteBuy Vine Package
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.
ReplyDeleteKeep 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.
ReplyDelete- 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
Thanks so much for this information. I have to let you know I concur on several of the points you make here and others may require some further review, but I can see your viewpoint.
ReplyDeletebuy youtube views
In order to create an application you'll need to sign in with a set of Twitter ... WP7 Twitter Figure 1. Figure 1. Once you click the “Create your ... by buy instagram followers cheap
ReplyDeletePublish and analyze Tweets, optimize ads, and create unique customer ... application that can be used to make authenticated requests to the Twitter platform. ... Search Tweets published in the last 7 days. ... "profile_use_background_image": true, "has_extended_profile": false, ... The number one guide for all things tech. by Buy Instagram Followers italy
ReplyDeleteI go through your post it’s really very amazing and very simple, thank you for sharing such a wonderful blog, looking forward to more blogs. Top 10 Makeup Artists in Kolkata
ReplyDeleteWe are So happy to see that you posted!! what you said is really helpful to Us and it was really interesting as well. you can buy 100% real stable and organic Youtube Views, Followers, likes and 24 hour customers support to Buy Real Youtube Views
ReplyDeletePERDE MODELLERİ
ReplyDeleteMobil Onay
mobil ödeme bozdurma
NFT NASİL ALİNİR
Ankara evden eve nakliyat
trafik sigortası
dedektör
web sitesi kurma
aşk kitapları
smm panel
ReplyDeletesmm panel
iş ilanları
İnstagram Takipçi Satın Al
hirdavatciburada.com
beyazesyateknikservisi.com.tr
Servis
Jeton Hilesi
It s a very useful page. Thank you. 9b7898625fe953091cdb3faf7a9b0413
ReplyDeletebozuyuk
serik
ayvacik
pinarhisar
sutculer
pertek
artvin
suhut
tavas
Congratulations on your article, it was very helpful and successful. b8619e47d20d4e77372162514555ba40
ReplyDeletewebsite kurma
sms onay
website kurma
Thank you for your explanation, very good content. 511c48f364f09a3f951cb6e9860661f3
ReplyDeletedefine dedektörü
Good content. You write beautiful things.
ReplyDeletehacklink
sportsbet
korsan taksi
sportsbet
vbet
mrbahis
hacklink
vbet
taksi
tunceli
ReplyDeleteurfa
uşak
van
yalova
8WGDJ
üsküdar
ReplyDeletekumluca
cekmekoy
cesme
FD1Z