Andrej Tozon's blog

In the Attic

NAVIGATION - SEARCH

Windows 8 Metro-style application manifest

When you create a new Windows Metro style application, Visual Studio will automatically create the application manifest for you. The file will be called Package.appxmanifest and will be included in the root of the project. Looking at it closer reveals that it’s a plain XML file that can be generated manually or with the help of some other tool as well.

Visual Studio, however, offers a nice GUI editor for editing the application manifest file. This is a quick walk through its tab pages. To invoke the editor, simply double-click on the manifest file or choose Store | Edit App Manifest from the menu.

Application UI

image

The tab for application menu hosts the basic info about your application.

Display Name is the title of your application. It will appear on the start screen, search page, etc., wherever the user can see. It can be localized.

Entry Point should point to the application’s activatable class id. It should be set to project’s App class, but in current build of Visual Studio, changing it to invalid value doesn’t currently seem to affect anything.

Description contains a longer description of your application, but it shouldn’t exceed 2048 characters. It can be localized as well.

Tiles (Logo, Wide Logo and Small Logo) represent the graphics you want to present your application with. The logo is also used as the main tile and the Small Logo is used for lists, etc. The Wide Logo is used when the app requires the wide format tile. Valid format for all graphics are .png and .jpg.

Further down, there are even more options…

image

Show Name and Short Name work in together with the above Display Name. Setting Show Name to Yes and leaving Short Name empty, the Display Name will be displayed on the application tile as an overlay. Set Short name to a custom name and Short Name will be displayed as the overlay.

Foreground Text sets the color of the text displayed on the application tile. In can be set to Light or Dark, for  best fit with the tile graphics.

Background Color specifies the tile’s background color. Can be either named or the ‘#’ color.

Notifications control how the notifications look and work.

Badge Logo points to the graphics that will be displayed on the lock screen as a notification from your application.

Lock Screen Notifications specify what kind of notifications your application will support when the system is locked. Can be set to Tile Text, Badge or both.

Toast Capable should be set to true when you want to send alerts from your application.

Splash Screen options (Splash Screen and Background Color) control the appearance of the splash screen. Splash Screen should point to the splash screen graphics and Background Color specifies the background color for that screen (transparency effects).

Initial Rotation specifies the initial rotation when the application starts. Can be set to all four possible rotations (Portrait, Landscape, Portrait and Flipped, Landscape and Flipped.

Capabilities

The next tab in application manifest editor allows you to set the protected resources you want to allow your application to access. Your application will not have the access to those capabilities if you don’t explicitly set them here, nor they won’t be accessible in cases when hardware does not support it, are blocked through other security policies, or when explicitly denied access by the user herself. Note that the user is prompted about those capability requirements when she is installing your application and can deny those requests. Even later…

Here’s the current list of those capabilities:

image

Declarations

Declarations are your application’s extensibility points, for better integration with the system and/or other installed applications. Some of those extensibility points include:

  • Contact Picker (your application serves as a contact picker for other applications),
  • File Type Associations (registers your app as a (default) handler for a specific file type),
  • File Picker (your app serves as a content picker for other apps; think choosers in Windows Phone),
  • Protocol (your app registers as a URL Protocol handler),
  • Search (provides searching functionality),
  • ShareTarget (for your next social networking application Smile),

… and a few more. All declarations have their own options and settings.

image

Packaging

The Packaging tab holds the info, relevant to deploying and publishing your application.

image

Package Name uniquely identifies the package and therefore your application too. It’s a GUID.

Package Display Name is a localizable package title that is displayed to the users.

Logo points to the application store logo.

Publisher describes the application publisher and matches the publisher subject information from the certificate that is used for signing the application manifest. The value is set automatically when choosing an existing certificate or create a new test certificate.

Publisher Display Name and Package Family Name are also derived from the chosen certificate. Publisher Display Name can be changed and even localized.



Windows 8 applications and JSON data

For anyone that wants to call various JSON data service endpoints in a Windows 8 (Metro style?) application, there’s a couple of changes in “.NET APIs for Metro style apps” (using MSDN terminology here) that needs to be looked into. For this blog post I’m using flickr API as an example of how to fetch and parse JSON data.

Where’s my WebClient?

No, there is no WebClient class in the new API. But…

There’s a HttpClient class that works similar, or even better, by providing an asynchronous method to fetch data. If you’ve looked into the Async CTP bits, the new method should look very familiar.

The new HttpClient class itself resides into the System.Net.Http namespace. Jumping right into the code:

public async Task<string> GetPhotosStream()
{
    HttpClient client = new HttpClient();
    string url = "http://www.flickr.com/services/rest/?method=flickr.photos.search&format=json&nojsoncallback=1&api_key=<yourkey>&text=buildwindows";
    HttpResponseMessage response = await client.GetAsync(url);
    return response.Content.ReadAsString();
}

Shall anyone need it, there is also a synchronous method called Get() that will block until full response message is returned and read on the client.

Other than Get(Async), there are three method pairs more – Get(Async), together with Put(Async), Post(Async) and Delete(Async) forms the full set of verbs supported by REST (Representational state transfer) to manipulate data.

GetAsync() will return a HttpResponseMessage, which contains the returned status code, response headers and returned content, which can be read in a variety of ways.

Parsing JSON

I have rarely used native framework JSON classes (I prefer using JSON.Net), but looking at the new API it looks like there’s quite a few changes here as well.

A returned string can be fed to the JsonObject in its constructor or using Parse() method on its instance. Either way will result in an exception if the JSON string is invalid and couldn’t be parsed.

Once parsed, you’ve got full access to it’s structure. Before I show the code to access it, let’s look at snippet of the returned JSON string:

{
  "photos":
  {
    "page":1, 
    "pages":1, 
    "perpage":100, 
    "total":"13", 
    "photo":
    [
      {"id":"6146549133", ..., "title":"20 Microsoft interns (three from Olin) at this week's BUILD conference", ...},
      {"id":"6146244616", ..., "title":"Internet Explorer", ...},
      ...
      ...
    ]
  },
  "stat":"ok"
}

And this is how you would read the titles of returned photos:

private static List<string> titles = new List<string>();

public static async void ExaminePhotos()
{
    string responseText = await GetPhotosStream();
    JsonObject root = new JsonObject(responseText);
    bool isSuccess = root.GetNamedString("stat") == "ok";
    JsonObject info = root.GetNamedObject("photos");
    int page = (int)info.GetNamedNumber("page");
    int totalPages = (int)info.GetNamedNumber("pages");
    JsonArray photos = info.GetNamedArray("photo");
    for (uint i = 0; i < photos.Count; i++)
    {
        string title = photos.GetObjectAt(i).GetNamedString("title");
        titles.Add(title);
    }
}

While the “Named*" methods return typed values (GetNamedString() returns a string, GetNamedNumber() a double, etc.), it’s also possible to get the JSON value by string indexer and later call to its typed value, e.g. json[“stat”].GetString(), which gets useful if you want to check for its type first.

The second part deals with a JsonArray named photo, which gets enumerated and read in a similar manner.

Wait, isn’t this supposed to be simpler?

Of course, the DataContractJsonSerializer is still here. In fact, it appears to be the same class, just moved into a separate assembly.

To use it, create appropriate classes from the JSON structure (one of utilities that can help) and deserialize JSON string with the help of DataContractJsonSerializer:

string responseText = await GetPhotosStream();

DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(RootObject));
RootObject root;
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(responseText)))
{
    root = serializer.ReadObject(stream) as RootObject;
}

The result is a full object tree that was deserialized from the flickr API JSON string.



First look at Windows 8 application as a developer

It’s been a couple of days since I installed the //build/ preview version of Windows 8 and in this short time I’ve grown to quite like it. It’s an interesting mix of the new Metro style and the “old” Windows 7-like style.

There were two things I’ve just had to install though, to make my life easier while working with Windows 8. The first thing was Total Commander, a file navigation alternative to Windows Explorer, and shortly after that, I installed “Mouse without borders”, the software KVM-like solution that lets you control multiple computers with a single set of keyboard and mouse, share clipboard etc. (for that I had to manually install .NET Framework 2.0 first, though).

The most confusing part about Windows 8 was the mixture of touch and mouse input. I installed Windows 8 on a touch-enabled notebook and was surprised that I could pan, zoom and drag things around, but couldn’t select apps. Tiles responded to tap, but apps just didn’t start and I had to use the mouse to click on them. I’m blaming the missing/incomplete drivers for that and expect it to be fixed by the time Windows 8 gets released. Once I got comfortable working around those issues, I started exploring the new Metro UI, mostly exploring my options for creating my own Metro application.

I took the default Weather application as the example. Funny thing is that at first I couldn’t find a way to change the temperature display to show Celsius instead of Fahrenheit. I started the app and started clicking all over it and eventually found out that right clicking anywhere on the screen (a Metro application takes up the whole screen unless it shares that space with other apps) brings up the Application bar (in touch world, the app bar is displayed by swiping up your finger from the bottom of screen).

image

Application bar

Similar to Windows Phone, Application bar is reserved for command and status buttons. One difference is that buttons are aligned to left and right edges instead of centered horizontally. This makes them easier to reach by your thumb fingers when holding a tablet.

Application bar hosts your command buttons that may change depending on the context - the state your application is in. You can also choose to include more system level commands such as the option to pin the application to the Start screen. Buttons you shouldn’t include in the Application bar are the ones for displaying application's settings and / or search pages. More on that later.

While application bar revealed some helpful options, there was no settings button to be found. Running around with the mouse I found a hot-spot on the bottom-left of the screen (where you’d expect the Start button to be on older Windows). Dragging my mouse to that corner revealed a Start-like menu with the “charm” options: Settings, Devices, Share, Search and Start (in touch world, charms are displayed when you swipe from the right edge towards center).

image   image

Great! Settings!

Settings and preferences

Turned out that settings charm took me to the settings pane that appeared on the right-hand side of the screen, offering me the following options:

  • Rate and Review the application (doesn’t currently work because Windows Store is not available yet),
  • Control system access for Weather (allows user to enable or disable the capabilities required by your application),
  • Weather preferences. That last one was key and the most difficult to find because it looked like some kind of group header. When I discovered that it was selectable, I got into the preferences page that allowed me to change application’s preferences.

image image

Preferences is also one of the custom Settings pages you can implement in your own application. There are a few settings commands you can add to the Settings pane that you map to specific pages, some of those being the About page, Preferences, Help and Privacy statement. From what I found out, only for Settings commands can be displayed in the Settings pane at once, but I’m not sure if that can change depending on your display resolution.

image

You don't need to worry when and how the Settings pane will be displayed, that all is handled by the OS, which means some less work for the developer and, perhaps more importantly, a unified experience across all Metro applications. You only need to implement the way Setting commands display application-specific pages (Preferences, About, etc.)

Search and Share


Search and Sharing contracts are implemented similar to Settings, but go additional step forward. If your application is going to support searching, you can hook up a Search pane, implement required event handlers and provide a custom results page. For Sharing, that would mean to implement the sharing logic. It looks like all application can share their screenshot by default (even if you don’t implement the sharing contract).

image    image

One bonus that Search and Sharing contract provide over Settings is that other applications can use your application as a search or share target. That means that from whichever other application user is currently using, she can search your application (or share her content through it) just by choosing it as a target from her current Search (or Share) pane.

There seems to be quite a few system hooks in Windows 8 that your Metro apps can connect to. Those mentioned above only happen to be the most exposed and accessible in the short run. Clearly it will take some time to get fully familiar with the new Runtime and OS integration and let’s not forget, we’re playing with the preview bits – anything can change in future versions.



Windows 8 geolocation API: First run

Microsoft Windows 8 OS was finally revealed this week at Microsoft’s //build/ conference. It looks like a promising OS, with Metro style theme showing all over it.

image

If you want to install it, look it up on the MSDN subscriptions site or head over here (limited set of SKUs). If you’re a developer, pick the one that includes the Visual Studio 11 Developer preview (or install tools – available also as a separate download – later).

A lot is about to be said of WinRT, the new Windows Runtime and how it relates to .NET and how developing Windows applications will going to be (dis)similar to developing WPF or Silverlight applications. Skipping that discussion for later, I jumped right into developing tools to see how familiar the new API would look to me and whether my past experience with developing XAML based applications in the past few years would help or not.

Starting with the geolocation API

Having developed a couple of Windows Phone application that used my location as a crucial piece of information, I was curious how the same would be done in a Windows 8 application. I’m posting this as a walkthrough (assuming you installed the Visual Studio 11 Express for Windows Developer Preview):

[A short note before you start: the following is based on the //build/ Developer Preview bits and will most likely change in future versions]

1. Open Visual Studio 11 Express.

2. Create a New Project. A few project templates are available, but let’s start simple and choose a basic C# Application.

image

3. If you’re a XAML developer, you’ll find yourself into a very familiar environment. A big plus on that is that Window designer is loading in the background and not blocking you to fiddle with other things while it loads [yes!]

image

[I’ll look into various settings to control you application’s look and feel in one of my future posts]

4. Similarly to Windows Phone, using a location requires you as a developer, to explicitly declare that your application will require access to the location API. This is set in the application manifest. In a Solution explorer, look for Package.appmanifest item and double click on it to open – the manifest properties window will open.

5. Click on the Capabilities tab. Uncheck the Internet (Client) capability and check Location capability (just under it).

image

You’ve just declared that the application will require the Location capability. Had you not enabled this item, anything access to the location API in the application would have no effect. No errors or exceptions would bi risen, it just wouldn’t work.

6. Go back to the MainPage.Xaml and add a TextBlock named Status into the main Grid (LayoutRoot). This is where you’re going to display the current location.

7. Switch to the code view (quick heads up: the F7 keyboard shortcut is not a default for this one anymore).

8. The core class you’re going to use is called Geolocator. It’s very similar to GeoCoordinateWatcher class from Windows Phone, so working with it should be fairly familiar:

public sealed class Geolocator : IGeolocator
{
  public Geolocator();
  public PositionAccuracy DesiredAccuracy { get; set; }
  public PositionStatus LocationStatus { get; }
  public double MovementThreshold { get; set; }
  public uint ReportInterval { get; set; }

  public event TypedEventHandler<Geolocator, PositionChangedEventArgs> PositionChanged;
  public event TypedEventHandler<Geolocator, StatusChangedEventArgs> StatusChanged;
  public GetGeopositionOperation GetGeopositionAsync();
}

Similar to GeoCoordinateWatcher, it has

  • DesiredAccuracy (Default, High),
  • LocationStatus (Ready, Initializing, NoData, Disabled, NotInitialized, NotAvailable) – with two new values,
  • MovementTreshold,
  • PositionChanged and StatusChanged events,

New in Geolocator are:

  • ReportInterval – the requested minimum time interval between location updates,
  • GetGeopositionAsync() – single call method for asynchronous request for location data.

Noticed the TypedEventHandler event declarations above? What are those? Let’s continue with the example…

9. Set up the Loaded event handler and paste the following code into it:

Geolocator locator = new Geolocator();
locator.PositionChanged +=
new TypedEventHandler<Geolocator, PositionChangedEventArgs>(OnPositionChanged);

OnPositionChanged event handler signature is as follows:

void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
}

To reflect the TypedEventHandler, you can see that sender is no more a plain object, it’s typed! That means no more unnecessary casting and your code is a tad more error-prone.

10. PositionChangedEventArgs holds a reference to a Geoposition, which is declared as:

public sealed class Geoposition : IGeoposition
{
    public CivicAddress CivicAddress { get; }
    public Geocoordinate Coordinate { get; }
}

While Geocoordinate is similar to GeoCoordinate from Windows Phone (Latitude, Longitude, Altitude, Speed, Heading, Accuracy, etc.), the CivicAddress should contain address data, associated with the reported Geocoordinate. I’m saying “should” because from all address properties (City, Country, PostalCode, State) for my current location (Ljubljana, Slovenia), the API only returns my country code (SI). I’m interested to hear how the same API behaves in other locations around the world so if you’re using it, please let me know.

11. If you try setting the Status label text in the OnPositionChanged event handler, you’ll get the invalid cross-thread exception and that’s because the event gets kicked on the background thread. In order to set the text, you have to invoke that on the UI thread, using the dispatcher. This is the part where things seems to differ the most. There’s a new dispatcher called CoreDispatcher. Declare it on the class level and set to page’s Dispatcher property in page’s constructor. That will guarantee you you can use it from the background thread.

So here’s the full MainPage code:

partial class MainPage
{
    CoreDispatcher dispatcher;

    public MainPage()
    {
        InitializeComponent();
        dispatcher = Dispatcher;
        Loaded += new RoutedEventHandler(OnLoaded);
    }

    void OnLoaded(object sender, RoutedEventArgs e)
    {
        Geolocator locator = new Geolocator();
        locator.PositionChanged += 
            new TypedEventHandler<Geolocator, PositionChangedEventArgs>(OnPositionChanged);
    }

    void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
    {
        dispatcher.InvokeAsync(CoreDispatcherPriority.Normal, DisplayLocation, this, args);
    }

    void DisplayLocation(object sender, InvokedHandlerArgs e)
    {
        IPositionChangedEventArgs args = e.Context as IPositionChangedEventArgs;
        Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}", 
            args.Position.CivicAddress.Country, args.Position.Coordinate.Latitude, 
            args.Position.Coordinate.Longitude);
    }
}

12. You can simplify the InvokeAsync code by using a lambda expression, though it may be a bit harder to read and/or debug:

void OnPositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
    dispatcher.InvokeAsync(CoreDispatcherPriority.Normal,
        (s, a) =>
        {
            Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}", 
                args.Position.CivicAddress.Country, 
                args.Position.Coordinate.Latitude, 
                args.Position.Coordinate.Longitude);
        }
        , this, args);
}

13. Now try to run the project. This is what you should see:

image

Windows is asking you if this application can use your Location. If user chooses Block, application’s request to access the location is denied. No errors or exceptions would be thrown, it just wouldn’t work. If user allows the access, the app will work as expected.

Note: the user can change this permission any time through the Settings charm: When application is running, move your mouse to the bottom left corner – the menu, similar to start screen should appear.

image

Click Settings and notice the right side bar. Click on the “Control system access for [YourAppName]” – you can change the access settings from there

image         image

If you want to test for access availability status from within the app, check Geolocator’s LocationStatus. In case the location access is disabled, it should be set to NotInitialized (although I expected Disabled).

Another fun fact is that Geolocator is not initialized on it’s instantiation, but only when you actually do something with it. In this case, it initializes when you subscribe to the PositionChanged event. This is also the same code line that will cause application (or Windows RunTime) to pop up that permissions dialog from above. After that line, the LocationStatus should be set to a valid status (Ready if access to location is enabled and NotInitialized if it’s not).

Note: Windows will only ask you for permission the first time it’s required. After that, it’s on user to change this permission. But if you want to test this, go to the Application manifest, Capabilities tab, and re-check the Location capability – that should reset the prompt.

But we’re not done yet.

Subscribing to PositionChanged event will ensure the event handler will be called each time Position is “changed” (that actually depends on your Geolocator’s MovementTreshold and ReportInterval property settings). To stop listening to position changes, you can simply unsubscribe from the PositionChanged event.

But… In a lot of cases, we only want to determine the current location once, instead of continuously tracking it. Fortunately, GetGeopositionAsync method does just that – retrieves the current position and it does it in the asynchronous manner (as suggested by Async method suffix by proposed convention).

And guess what? Async methods are unbelievable easy to handle with the new async / await keyword pair. Let’s give it a try.

14. Change the OnLoaded event handler too look like this:

async void OnLoaded(object sender, RoutedEventArgs e)
{
    Geolocator locator = new Geolocator();
    Geoposition position = await locator.GetGeopositionAsync();
    Status.Text = string.Format("Country:{0} Lat: {1} Lng: {2}",
        position.CivicAddress.Country, 
        position.Coordinate.Latitude, 
        position.Coordinate.Longitude);
}

Geolocator is instantiated as before, but the current position is accessed through the GetGeoPositionAsync() method. And notice how that method is decorated with the await keyword and the whole OnLoaded method with async. The principle will also guarantee you that your code, after that async call, can safely call into the UI thread. No dispatcher needed. And from what I know, there are many async method scattered around the new runtime, it will just make coding so much easier, not to mention the new responsive UI.

Wrapping up

That’s it! My first experience with the new API. So far I love it but porting existing and building new applications will eventually show its real value.

And to just briefly touch on the current hot topic – I really think that desktop application development has just shifted gears, although it’ll take some time to lift off the ground. What we’re looking at is an early preview and it will take some time till release, and event more to a broad Windows 8 adoption.

If you have any comments, questions, suggestions for future posts on the subject, any feedback at all, do not hesitate to contact me.