Some notes on starting Win8 App development

We are all at a pretty unique point in time right now. Although technically, every point in time is unique (as far as we know). What I mean is, we are approaching the beginning of a new era with launch of the Windows 8 App Store.

Now, whether you are a fan of Windows or not – or whether you think a Windows Tablet will take off or not, Windows has a remarkable amount of momentum. I read there are 1.25 BILLION Windows users. If ever there was a time to get in on the ground floor of something – now is that time.

From The 22 Immutable Laws of Marketing – it is better to be first than to be better. For example, right now – I use Windows 8 on my home machines. I use MetroTwit for twitter, and Readiculous for RSS/blog reading. They were the first apps to become available in the Store, so that’s what I installed. There could be a new RSS reader out right now, and I wouldn’t really know it – because I already have something that works. So – whoever has the first app out there, has a better chance of building tremendous momentum over the app that is better (and late).

All my point is, if you ever considered writing an app – the Windows 8 App Store launches on 10/26/2012 and that is the time when you want your app to be ready! Put another way, apps are going to fall into two categories – 1) the apps that are available on launch day and 2) all the other apps that are going to fight for that market share afterwards.

Now, I don’t have very ambitious goals for an app – but I did want to see what it would take to get an app into the app store and I did want to write an app that I would fine useful. So, I am writing a somewhat simple app – well, I’ve started to. Below are some of the lessons I’ve learned so far – some of these are things that took some time to find.

Use MVVM:
If you are coming from Silverlight, Windows Phone, or WPF realm, then you probably are already aware. However, if you are coming from the WinForms or ASP.NET world, you may not be familiar. Use MVVM (Model-View-ViewModel). XAML is capable of binding to objects. The UI updates automatically when the underlying data changes. This is done by classes implementing INotifyPropertyChanged and using ObservableCollection<T>’s. There is a lot written on this topic – go research. This is absolutely the way to write XAML apps. Even though you can do Button_Click event handlers, there’s really no reason too – MVVM will save you enormous amounts of time and code, and give a better user experience. See the Patterns and Practices MVVM Quickstart.

Incidentally, this does also align with the teachings of Uncle Bob Martin (www.cleancoders.com) – in that this encourages “the application” to be written in code. What I mean is, most applications seem to start from the UI and then couple with the database – or start from a database and then couple a UI. Instead, Uncle Bob teaches us that application should exist in code – and the UI, database, unit tests, etc – should all just plug into “the application”. MVVM really helps realize this approach.

Using a Dark or Light Theme:
If you create a new Win8 project in Visual Studio 2012, from the templates, it creates a dark-themed app (white text on a dark gray background). This very quickly became annoying to me because it is a little too dark – it’s like light grey text/objects on a dark grey background. How do you change this? Open your App.xaml add a RequestedTheme=”Light” right at the top

Setting up Right-Click “App Bar” functionality:
In a Windows 8 app, many screens supports a right-click (or swipe down) to bring up sort of a context menu. This is handled in the built-in class LayoutAwarePage (if you start from a template, this file is in Common) via the BottomAppBar and TopAppBar. You can ether add the XAML by hand – or just simply open the “Document Outline” window, choose pageRoot, then hit F4 to view the properties.

Under the Common category, you can click the “New” button next to BottomAppBar or TopAppBar.

You might ask “Where is that AddAppBarButtonStyle defined?”. By default, it’s commented – but in the Common folder look at StandardStyles.xml – it has definitions for every kind of app bar button you could imagine.

Persisting Data:
There are two categories of data that you might want to store A) volatile session data and B) actual application data. I haven’t gotten most of this working, but I’ve gleaned some clues so I’ll share what I think is correct. For session-type data, it looks like you can use ApplicationData.Current.RoamingSettings – although I believe there are limits on this. Here is a pretty good page that goes into more detail about this.

As for application data – you have a few options. You can store data locally, you can use SQL Lite or the new Azure Mobile offering – or in my case, I specifically want to give the option of storing an XML file on the end-users SkyDrive. After all, it’s their data. Not only that, if I have a Windows 8 and ultimately a Windows Phone 8 app – they can all read/write from the same source. How do you do this stuff?

Well, writing data locally is kind of… weird. The WinRT libraries didn’t borrow much from the .NET Framework for some reason. “Streams” don’t inherit from System.IO.Stream, they aren’t readable with a StreamReader, etc, etc.. I/O is just weird – I don’t know why they chose to “start fresh” with these API’s. Anyhow, to actually read and write from a file is again, weird, and took me some time to find. So, here is some sample code:

Reading:

ApplicationData applicationData = ApplicationData.Current;

StorageFolder appFolder =   await applicationData.RoamingFolder.CreateFolderAsync(FolderPath, CreationCollisionOption.OpenIfExists);
StorageFile file = 
    await appFolder.CreateFileAsync(FileName, CreationCollisionOption.OpenIfExists);

String fileContents = 
    await FileIO.ReadTextAsync(file, Windows.Storage.Streams.UnicodeEncoding.Utf8);

 

Writing:

ApplicationData applicationData = ApplicationData.Current;

StorageFolder appFolder =   await applicationData.RoamingFolder.CreateFolderAsync(FolderPath, CreationCollisionOption.OpenIfExists);
StorageFile file = 
    await appFolder.CreateFileAsync(FileName, CreationCollisionOption.OpenIfExists);

String contents = this.Serialize(PersistedItem);

 

(the this.Serialize(..) is mine) – Note though, I’m still not at the point where I can try this – so this is untested code, but I believe this should pretty much work or at least get me in the ballbark?

One last note about persistence – I’m grateful for the things I’ve learned from Uncle Bob Martin (www.cleancoders.com) as I made a design decision that has come in handy. I realized that I (or an end-user) might want to store this application data via different methods. So, I created an IPersistable interface:

/// <summary>
/// Interface that represents items that are capable of being persisted.
/// </summary>
public interface IPersistable
{
    /// <summary>
    /// Gets or sets the item that is persisted.
    /// </summary>   Object PersistedItem { get; set; }

    /// <summary>
    /// Loads the <see cref="PersistedItem"/> from the underlying store.
    /// </summary>
    /// <exception cref="PersistenceException">If an error occurs while trying to load
    /// the item from the underlying store.</exception>
    void Load();

    /// <summary>
    /// Saves the <see cref="PersistedItem"/> to the underlying store.
    /// </summary>
    /// <exception cref="PersistenceException">If an error occurs while trying to save
    /// the item to the underlying store.</exception>
    void Save();
}

/// <summary>
/// Interface that represents items that are capable of being persisted.
/// </summary>
/// <typeparam name="TItem">The type of the item to be persisted.
public interface IPersistable : IPersistable where TItem : class, new()
{
    /// <summary>
    /// Gets or sets the item that is persisted.
    /// </summary>
    new TItem PersistedItem { get; set; }
}

 

and made a few implementations: InMemoryPersistence, IsolatedStoragePersistence, SkyDrivePersistence – and presumably I could later implement SqlLitePersistence and AzureMobilePersistence too. Anyhow – this was a real-world case where using the “strategy pattern” and injecting the particular implementation really gives me a lot of flexibility. I use the InMemoryPersistence for my unit tests and IsolatedStoragePersistence (at the moment) for actual app testing, and I hope to get the SkyDrive stuff working later.

How do you read/write from the current users’ SkyDrive? Binoj wrote a blog post about that here, over at CodeRewind.com. I haven’t tried this yet – but he’s actively using this in the BiblePronto app in the Windows 8 App Store.

Other Getting Started Help:
I found this page on MSDN: Creating your first Metro style app using C# or Visual Basic – it has a lot of good little tidbits in there. I think I found that link from this page: Getting starts with Metro style apps – which also has lots of great info.

Bottom Line / Next Steps:
For me personally, I don’t know that I will finish this app – it’s been very, very frustrating for me. I would take one step forward – then do 20 minutes of research to get the answer. I’d start working on the next thing, then it’s another 20 minutes of research. I think I’m also confirming that I’m not really a UI person – I find the user experience stuff to be very tedious. I definitely prefer to write code rather than defining user interfaces.

So for me, I have most of my pages designed, I think I have a workable set of models – and a way to persist them. I think I have a few of the major UI things done too – like an AppBar, page navigation, etc. What’s left? Well, actually getting my model to persist and load, implementing search, getting the SkyDrive stuff to work – and then actually making sure that this working correctly on different resolutions – and with “snapping”, which I think is taken care of by the template. I’m going to keep plugging away. I will likely do another blog post if I can get this finished, with the new things I will likely learn.

Tagged with: ,
Posted in New Technology, Uncategorized, WPF and MVVM

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 2 other followers

%d bloggers like this: