Friday, 18 February 2011

Passed 70-583

I just discovered that I've passed yet another beta exam!

  • 70-583 - PRO: Designing and Developing Windows Azure Applications

So when I get around to taking the 70-513 exam, I would have then fulfilled the requirements for the certification:

Time to brush up on my WCF!

Tuesday, 15 February 2011

Aussie Toilets WP7 App

Icon for Aussie Toilets appMy second app 'Aussie Toilets' has now been published on the Windows Phone 7 marketplace. It's an app for locating the nearest public toilet, and it's free!

It uses data provided by the Australian Government's National Toilet Map website. It's a useful app to have on your phone, especially if you're out and about and need to find the nearest 'public conveniences'.


'Aussie Toilets' map screenThe app displays a map of your current location (or defaults to Australia if it isn't sure, or you've declined permission for the app to access your phone's GPS).

Once you've zoomed in to a particular location, it will begin loading the database. This may take a few seconds, as the database is quite large.

It then displays up to 5 nearest public toilets.

You can pan around the map, and use the standard 'pinch to zoom' to zoom in closer or further out.

Screengrab-hoursScreengrab-facilitiesScreengrab-addressTapping on a name will take you to a new page with more details about that facility. The data is displaying using the 'pivot' control, so you can swipe left or right to pan to each section.

Specific facilities include male/female toilets, baby change and showers. Other facilities will be added in future versions (e.g. accessible toilets etc).

The opening hours are also displayed. Some locations might be open 24 hours, others (eg. in a shopping centre) only during certain times.

These details vary for each facility and are only as accurate as the data supplied to the database by the organisations responsible for each toilet (e.g. Councils, State government agencies, transport providers, shopping centres, service stations and food outlets). The app's database in the initial release is current as of January 2011.

To install Aussie Toilets on your Windows Phone 7 device, go to http://social.zune.net/redirect?type=phoneApp&id=dcf35aa5-3829-e011-854c-00237de2db9e (Opens in Zune)

Future plans

  • Detect and allow database updates to be downloaded as they become available from the government site
  • Nice icons for facility details
  • Display more of the facility details as included in the database
  • Improve performance of database access
  • Investigate ways to provide feedback and improve data quality

Footnote

I took quite a while to settle on the name 'Aussie Toilets'. I'd had a few other good suggestions – things like 'Dunny Directions', 'Loo Locator' or 'Aussie Loos'. In the end I decided I'd stick with a nice obvious self-explanatory (if slightly more pedestrian) name.

Thursday, 10 February 2011

Sharing code between two WP7 projects

So you want to publish a free (aka 'lite') as well as paid versions of your Windows Phone 7 app? Ideally you can do this with a minimum of duplication between the two projects. This is how I've approached the problem.

Create second project

Assuming you've got a solution with a working WP7 project (I'll refer to this as 'primary'). Add a new WP7 project to your existing solution (referred to as 'secondary'). In the new secondary project, add a reference to the primary project.

Move resources into resource dictionary

If you have any resources defined in your App.xaml file, you should move them to a separate xaml file and use a ResourceDictionary to reference them.
Here's a cutdown version of my Styles.xaml. This lives in the primary project and has a build action of 'Page'.
<?xml version="1.0" encoding="utf-8" ?>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:unsupported="clr-namespace:Microsoft.Phone.Controls.Unsupported">
    <Style x:Key="PerformanceProgressBar" TargetType="ProgressBar">
       ...
    </Style>
</ResourceDictionary>
App.xaml for primary
I've been using Caliburn Micro framework so the bootstrapper property has to be moved inside the nested ResourceDictionary.
<Application x:Class="Primary.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:Primary">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:AppBootstrapper x:Key="bootstrapper" />
                </ResourceDictionary>
                <ResourceDictionary Source="Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

    </Application.Resources>
</Application>
App.xaml for secondary
In this file, we need to fully specify the path to Styles.xaml
<Application x:Class="Secondary.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Secondary">
    <Application.Resources>
        <ResourceDictionary >
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary>
                    <local:AppBootstrapper x:Key="bootstrapper" />
                </ResourceDictionary>
                <ResourceDictionary Source="/Primary;component/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
In my case, the secondary project has it's own AppBootstrapper class that inherits from the primary project's similarly named AppBootstrapper.
There's more info on using ResourceDictionaries with WP7 in this StackOverflow question.

Make page navigation Uris fully qualified

If you have any NavigationService calls to navigate to other pages in the primary project, they will need to be fully qualified so that they continue to work when called from the secondary project.
_navigationService.Navigate( new Uri( "/Primary;component/SettingsPage.xaml", UriKind.RelativeOrAbsolute ) );

Fully qualify the value of the NavigationPage attribute in the WMAppManifest.xml file

Assuming you want the same page to load at the start in the secondary project, you'll need to change the reference in the NavigationPage attribute in the WMAppManifest.xml file.
<Tasks>
  <DefaultTask Name="_default" NavigationPage="Primary;component/MainPage.xaml" />
</Tasks>
Bear in mind that if you edit the application properties through the Visual Studio project properties interface, this will revert the NavigationPage value back to just "MainPage.xaml", so you'll need to update it again.

Add links to existing files for all 'Content' files and application bar images

imageAny files in your primary project that have a build action of 'Content' will need to be added to the secondary project. Add them as existing items and choose the 'Add as link' option so you just reference the existing file. Update the build action of all of these files to be 'Content'. Common examples of these files would include ApplicationIcon.png and Background.png.
Likewise, if you have any application bar icons, you'll probably need to do the same.

Conclusion

Following these steps produces a nice lean secondary project like this:
image
It's hard to see from the icons (as Mercurial has overlaid green ticks on top), but the only unique files to the project are App.xaml, AppBootstrapper.cs and the contents of the Properties folder. All the others are linked to ones in the Primary project.

Thursday, 3 February 2011

IsolatedStorageSettings extension method

I noticed that my Windows Phone 7 applications started to have lots of these kinds of statements in the OnLaunch and OnActivate event handlers:

IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
bool allowLocationService;
AllowLocationServiceProperty = settings.TryGetValue( "AllowLocationService", out allowLocationService ) ? allowLocationService : false;

I came up with simple this extension method to reduce the repetition:

/// <summary>
/// Gets a value for the specified key
/// </summary>
/// <typeparam name="T">The System.Type of the value parameter.</typeparam>
/// <param name="settings"></param>
/// <param name="key">The key of the value to get.</param>
/// <param name="default">A value to return if the key is not found.</param>
/// <returns>When this method returns, the value associated with the specified key if the key is found; 
/// otherwise, the value of <paramref name="default"/>. </returns>
public static T TryGetValue<T>(this IsolatedStorageSettings settings, string key, T @default)
{
    T value;
    return settings.TryGetValue( key, out value ) ? value : @default;
}

Which means I can now do:

IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

AllowLocationServiceProperty = settings.TryGetValue( "AllowLocationService", false );

That's a bit better!

There's a few other examples in this thread in the Windows Phone 7 forums.

Wednesday, 2 February 2011

Comparison of public weather forecasts for Adelaide

If I want what I consider the most accurate forecast for Adelaide, I'm going to refer to the Bureau of Meteorology forecast. There are a number of other weather sites on the Internet, so let's see how close their forecasts are to what I'll call the "official" one.

Note, temperature is measured in Celsius in Australia, so those are the units I'm displaying. Out of interest, 42°C is equivalent to 107.6°F which is equivalent to hot!

BoM Forecast

PRECIS FORECAST FOR ADELAIDE
Issued at 5:00 am on Monday, 31 January 2011

Monday               Max 42   Dry. Sunny.

Tuesday     Min 24   Max 33   Fine. Mostly sunny.
Wednesday   Min 20   Max 34   Fine. Mostly sunny.
Thursday    Min 22   Max 34   Fine. Mostly sunny.

wunderground.com

http://www.wunderground.com/global/stations/94672.html

Predicting 37°C

image

weather.com

http://uk.weather.com/weather/today-Adelaide-ASXX0001?fromSearch=true

I went to the UK version of weather.com as that seemed to be the easiest way to get the temperatures in Celsius.

Forecast: 40°C

image

accuweather.com

http://www.accuweather.com/en-us/au/south-australia/adelaide/quick-look.aspx

Forecast: 42°C

image

theweathernetwork.com

http://www.theweathernetwork.com/weather/ausa0001

Forecast: 32°C

image

image

weatherbug.com

http://weather.weatherbug.com/Australia/Adelaide-weather.html?zcode=z6286&lang_id=en-au

Forecast: 33°C

Looking at the screengrab, I can see why they're called weatherbug.

image

So as you can see, most of these have absolutely no idea.. I can only presume they are throwing darts at a dart board with the numbers they come up with. Accuweather seemed to be the closest to the Bureau's figures.

And as it turned out, Monday did get to 42°C, so the BoM was on the money.