Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Develop for Windows Phone and Windows using Portable Class Library

In the past I wasn’t a big fan of the Portable Class Library as I felt it imposed more restrictions than necessary and would constrain/frustrate developers more than it would actually solve a problem. However, in recent times a couple of things have happened that have made this whole experience a lot better.

Firstly, we no longer need to drag out VS2010 to do Windows Phone 7 development. The new Windows Phone 8 SDK plugs into VS2012 and allows for both WP7 and WP8 app development. This means that if you’re going to be targeting multiple versions of WP you can do so in the same solution.

Next, the release of Microsoft.Bcl.Async on nuget – ok, you’re probably thinking what’s that? Well a while ago Microsoft published the Async programming CTP. Whilst it had a go-live license and could be used in your Windows Phone 7 project it was a hassle to install in VS2010 (due to a weird set of dependencies which were broken with subsequent updates to VS) and didn’t support VS2012 at all. The Microsoft.Bcl.Async package is the replacement for the Async CTP, allowing you to do asynchronous programming in WP7 apps. Of course, both Win8 and WP8 support async programming out of the box.

Ok, on to using a Portable Class Library. The concept here is that you want to build a single, managed, library that can be referenced by applications targeting different platforms. Let’s walk through a simple example.

We’re going to start by creating three different applications within the sample solution: SimplePCLTestApp.WP7, SimplePCLTestApp.WP8 and SimplePCLTestApp.Win8. As the project names suggest the projects should be targetting WP7, WP8 and Win8 respectively. We’re then going to also create a Portable Class Library called SimplePCL. Note, when you go to create the PCL you’ll see a prompt similar to the following image. This allows you to specify which frameworks your going to be targeting. In this case we’ll take the default options as we’re not going to be building for XBox.

image

The next thing to do is to add the Microsoft.Bcl.Async nuget package into the WP7 and PCL projects. The following image illustrates the package that you’re after.

image

Unfortunately at the moment when you attempt to add this package it won’t give you the option to add it to the PCL. It appears there is some incompatibilities with the current version of the nuget package for Microsoft.Bcl.Async and the PCL. Luckily it’s relatively easy to fix manually:

> Unload the PCL project
> Right-click on the PCL project and select Edit SimplePCL.csproj
> Now, replace the following element

<ItemGroup>
  <!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>

With

<ItemGroup>
<Reference Include="Microsoft.Threading.Tasks">
    <HintPath>..\packages\Microsoft.Bcl.Async.1.0.12-beta\lib\sl4-windowsphone71\Microsoft.Threading.Tasks.dll</HintPath>
  </Reference>
  <Reference Include="Microsoft.Threading.Tasks.Extensions">
    <HintPath>..\packages\Microsoft.Bcl.Async.1.0.12-beta\lib\sl4-windowsphone71\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
  </Reference>
  <Reference Include="Microsoft.Threading.Tasks.Extensions.Phone">
    <HintPath>..\packages\Microsoft.Bcl.Async.1.0.12-beta\lib\sl4-windowsphone71\Microsoft.Threading.Tasks.Extensions.Phone.dll</HintPath>
  </Reference>
  <Reference Include="System.Runtime">
    <HintPath>..\packages\Microsoft.Bcl.1.0.11-beta\lib\sl4-windowsphone71\System.Runtime.dll</HintPath>
  </Reference>
  <Reference Include="System.Threading.Tasks">
    <HintPath>..\packages\Microsoft.Bcl.1.0.11-beta\lib\sl4-windowsphone71\System.Threading.Tasks.dll</HintPath>
  </Reference>
</ItemGroup>

> Save, and reload the PCL project

The last preparatory step is to add a reference to the PCL project to each of our applications. This is done as per normal by right-clicking the project, selecting Add Reference, and then selecting the PCL project from the solution node.

We’re now ready to start writing some code. We’ll rename Class1 to ExampleClass and add the following code:

public class ExampleClass:INotifyPropertyChanged {
    private string name;
    public string Name {
        get { return name; }
        set {
            if (Name == value) return;
            name = value;
            OnPropertyChanged();
        }
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
   [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    private readonly ManualResetEvent sleepEvent = new ManualResetEvent(false);
    public async Task UpdateName(string newName)  {
        await Task.Factory.StartNew(() =>
                                        {
                                            // This will sleep waiting for a signal that will never happen!
                                            sleepEvent.WaitOne(1000);

                                       });
    Name = newName;
   }
}

This simple class illustrates a couple of different things:

- The use of INotifyPropertyChanged – almost essential for view models, which you will probably want to share across projects if you’re using MVVM. Note the OnPropertyChanged method uses the CallerMemberName attribute, rather than the property name having to be specified when the method is called.

- The UpdateName method is an asynchronous method which launches a background task using Task.StartNew. This is to simulate some long running task (eg service call, or disk I/O). There is no support for Thread.Sleep in the PCL so we’ve used a workaround which involves waiting for a reset event that will never happen.

- The Name property is updated after the background task has completed. If this method was invoked on the UI thread then it’s safe to update the Name property, since the PropertyChanged event also needs to be invoked on the UI thread to prevent a cross threading violation.

We can then add the following code to the main page of each of our applications:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);


    var example = new ExampleClass();
    example.PropertyChanged+=ExamplePropertyChanged;
    example.Name = "Initial Name";
    Debug.WriteLine("-------------------------");
    await example.UpdateName("Updated Name");
    Debug.WriteLine("-------------------------");
}

private void ExamplePropertyChanged(object sender, PropertyChangedEventArgs e)
{
    var ex = sender as ExampleClass;
    Debug.WriteLine(ex.Name);
}

Running this, in all cases, should yield the following Debug output (you may see some additional assembly/type loading information as well):

Initial Name
-------------------------
Updated Name
-------------------------

And there you have it. An example of how you can use a Portable Class Library to abstract our your platform independent code.

Windows Phone 8 SDK: Accessing Content from an SD Card

Before you get all excited and worked up about the fact that you can use an SD card with the new Windows Phone SDK there are a couple of limitations that you need to be aware of. Keep in mind that one of the primary scenarios that was being solved was the distribution of apps (errr, did I mention apps…. this is limited to Enterprise apps) and content, rather than being an extension to the device storage.

- You can only access file types that you’ve registered for (this excludes the standard file format – which is a bit nasty if you want your app to say process images or documents supplied on an SD card).

- You can only read from SD card.

Ok, with these limitations in mind, let’s take a shot at reading from an SD card.

First up, we need to get an SD card (oh and a real Windows Phone 8 device to work with) and put some content on it. In this scenario we’re going to use a sqlite database called mydata.sqlite. I simply inserted the Micro SD card, using an SD card adapter, into my laptop and copied across the existing sqlite file. I then inserted the card into my Windows Phone 8 device.

Next, I opened my Windows Phone 8 project and added a couple of nuget packages. These are only required if you’re using sqlite, if you’re using some other file type, you don’t need to worry about these packages.

wp7sqlite – This is a managed implementation of sqlite
sqlite-net – This is a super-easy wrapper that you can use in order to access the content.

image

Unfortunately, whilst these two packages were designed to work together, for some reason the versions that are in nuget are incompatible, requiring some minor modifications to get them to work. Luckily this is mostly a matter of replacing “out” with “ref” in a couple of methods.

The next thing to do is to declare our intent to a) read from the SD card and b) what file types we want to be able to access. Double-click the WMAppManifest.xml to open the designer, switch to the Capabilities tab and check the ID_CAP_REMOVABLE_STORAGE capability.

image

Close the manifest designer, right-click on the WMAppManifest.xml file and select Open With. Select XML (Text) Editor and hit Ok. You need to add a FileTypeAssociation element into the Extensions element. If Extensions doesn’t exist, you may need to create that too – it needs to sit after the Tokens element but before the ScreenResolutions element.

</Tokens>
   <Extensions>
     <FileTypeAssociation Name="sqlite" TaskID="_default" NavUriFragment="fileToken=%s">
       <SupportedFileTypes>
         <FileType ContentType="application/sqlite">.sqlite</FileType>
       </SupportedFileTypes>
     </FileTypeAssociation>
   </Extensions>
   <ScreenResolutions>

Now all that’s left is to write some code in order to access the content from the sd card. If you’re simply going to read from the files you can do so in situ. However, in this case we’re eventually going to want to write to the file, so we’re going to copy it to Isolated Storage first.

// Connect to the current SD card.
var sdCard = (await ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault();

var routeFiles = await sdCard.GetFileAsync("mydata.sqlite");
using (var source = await routeFiles.OpenForReadAsync())
using (
    var target = IsolatedStorageFile.GetUserStoreForApplication()
                                    .OpenFile("writeablecopy.sqlite", FileMode.Create, FileAccess.Write))
{
    await source.CopyToAsync(target);
}

var db = new SQLiteAsyncConnection("writeablecopy.sqlite");
var existing = await db.QueryAsync<MyDataObject>("select * from data");
var data = existing.ToArray();

Don’t forget you’ll want to add appropriate error detection and check that an SD card even exists before you attempt to read from it. For those following the sqlite portion, the MyDataObject class is a relatively simply class, the sqlite-net wrapper handles the conversion between the sqlite data and the .net types:

public class MyDataObject
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string Name { get; set; }
}

Cancel My Newspaper Subscription: Would a Real Journalist Please Stand Up!

Over the last 48 hours Microsoft has launched Windows Phone 8 (press kit here) and the developer tools, the Windows Phone 8 SDK. Unfortunately there seems to be a spate of bad journalist here in Australia. Rather than actually spending time the platform they insist on quoting other, somewhat biased, journalist. Specifically this piece by Ben Grubb at SMH (http://www.smh.com.au/digital-life/mobiles/windows-phone-8-cant-catch-big-two-20121030-28hed.html). Let’s drill in and see what Ben said quoted:

- First, he states that Microsoft is so far behind Android and iOS that it sees RIM as it’s main rival. This comment is completely out of context and he provides no actual basis. It’s a reality that RIM is the closest in market share, so of course they are the next target in terms of just acquiring market share. This in itself doesn’t mean that Microsoft isn’t looking to capture a much larger market share. If you look at device features, variety, developer platform/tools etc, Microsoft isn’t lagging. In terms of apps, there is a way to go before we get to where Android or iOS is but that’s a result of how long the platform has been around more than anything.

- Next, he says that analysts are saying Microsoft is wrong and has no hope…. Really, again who said this. If this is what you believe, then how about putting your name to this comment.

- It’s great that the only quotes from Microsoft is about how hard it is to compete in a market that’s heavily saturated by the incumbent platforms. Well duh! this isn’t news. How about giving us a run down on all the new features of Windows Phone 8, instead of boring us with the obvious.

- I’m not going to bore you with any more of the quotes, rather than any useful commentary that Ben could have offered if he’d actually bothered to use a Windows Phone 8 device. However I’ll leave you with one last example. Ben quotes Joseph Sweeney of IBRS who has made the comment that he didn’t “really see much new”. Hmmm, and adding a fifth row of icons on the iphone 5 was a ground breaking UI change was it. Here’s a list of some of the changes that are in Windows Phone 8 (I’ll leave it to you to work out whether you think they’re new or not):

* Live Tiles – this in itself is not new. However, apps can now take advantage of three different sizes, the ability to flip and cycle content through the tiles.

* Kid’s corner – an isolated area of the phone where kids can play without parents worrying about their data or wallet being compromised.

* Lock screen – an app can surface content and information directly to the lock screen

* VOIP – the integration of Skype (and other third party VOIP apps) is at a low level, making it ultra efficient (ie won’t drain your battery) and always on (so you can always receive chat and calls)

* Rooms – an area where you can share content with a group of people

* Wallet - I originally had this in here but the other smartphone platforms are all doing their own interpretation of this so it's not really new.

And this is just to cover some of the consumer features that I believe add to an already awesome phone platform. If you want to see an example of a journalist who has actually taken the time with a phone then read the following http://www.informationweek.com/byte/personal-tech/slick-windows-phone-8-an-acquired-taste/240012565

Windows Phone 8 SDK: Enterprise Applications (part 2)

In the previous post we used the XapSignTool directly in order to sign the enterprise application. One of the changes introduced to Windows Phone is the ability for the Windows Phone store to distribute precompiled applications, making them run that much quicker. In order to take advantage of this for your enterprise applications you need to run the MDILXAPCompile tool which ships with the SDK. Luckily, the team have also provided a powershell command making it dead easy to precompile and sign your application in one easy step.

Firstly, you’ll need to run powershell. Depending on how your system is setup you’ll probably want to run it as administrator as you may need to change the execution policy. If you’re familiar with powershell you can probably skip these steps.

Go to C:\Windows\System32\WindowsPowerShell\v1.0, right click on Powershell.exe and select Run as Administrator

If you run into errors running the powershell script, with an error referring to execution policy, you can adjust the policy as follows (warning this will allow any script to run):

Set-ExecutionPolicy -ExecutionPolicy Unrestricted

Change directories to the MDILXAPCompile tools folder within the SDK:

cd ‘C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\MDILXAPCompile\’

Run BuildMDILXap.ps1

.\BuildMDILXap.ps1 –xapfilename 'c:\temp\Provisioning\SimpleCompanyApp.xap' –pfxfilename 'c:\temp\companyappcert.p12' –password mypassword

The output should look like the following

image

Windows Phone 8 SDK: Enterprise Application Deployment

This is a step by step guide to preparing your organisation so that you can sign and deploy enterprise applications.

Certificate Acquisition

Get your Publisher ID/Symantec Id and Approver Email Address

First up you’re going to need your Publisher ID (also referred to as Symantec Id) and Approver Email Address.

These can both be retrieved from your Dev Center account (Must be Company account type)

image

- Type (Blue box): This has to be Company

- Symantec Id (Green box): This is your publisher Id or Symantec Id (as distinct from your Publisher GUID)

- Email (Purple box): This is not necessarily your approver email address

Click Edit (under Contact info) and scroll to bottom of page

clip_image002

- Email address (Blue box): This is the approver email address

Request Certificate

Navigate to https://products.websecurity.symantec.com/orders/enrollment/microsoftCert.do

Enter Publisher ID and Approver Email Address

clip_image004

Complete Billing information

clip_image005

clip_image007

Agree to terms

clip_image009

Confirmation of order completion

clip_image011

Approve your Certificate Request

You’ll need to monitor the approver email address for “Enterprise Code Signing Certificate Order Approval”. If this is someone else in the organisation you must warn them – if they receive this and accidentally click the “I Do Not Approve” option it will result in significant delays.

Click appropriate link to website to review and approve/reject order

clip_image013

Click “I Approve” button

clip_image014

Confirmation of approval

clip_image015

Retrieve your Certificate

You should receive confirmation email that the order has been approved.

clip_image016

Follow the link to retrieve the certificate. This should be done on the same computer and in same browser that the initial request was made.

clip_image018

clip_image020
Click Continue to retrieve the certifcate

Review certificates for the browser. Eg Firefox it’s in Options > Advanced > View Certificates

clip_image022

Click Backup and save the certificate (eg companyappcert.p12 or companyappcert.pfx) complete with private key (you need to set a password)

Open Certificate Manager management console (Start > Run > Certmgr.msc) and confirm that certificate exists and that the full Certification Path exists. This is a common error – only the leaf node is exported. Make sure you have the full path as illustrated in the screenshot below.

clip_image024

Signing and Deploying Applications

Create Application

Create your application as normal. When you want to deploy your application, take a copy of the XAP file that can be located in the \Bin\Release folder of your application.

Sign Application

Open “Developer Command Prompt for VS2012”.

Warning: Make sure you open the correct command prompt as not all of them have the same environment parameters set. This may prevent some of the tools running correctly.

Run the XapSignTool supplying the name of the XAP file as a parameter:

"C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\XapSignTool\XapSignTool.exe" sign /v c:\temp\Provisioning\SimpleCompanyApp.xap

Note:

/v Indicates verbose output – this will be necessary if you have multiple certificates that could be used for signing (which is more than likely)

The next step can be skipped if signing completed correctly. If there are multiple certificates found you’ll need to identify which one you want to use (hence the /v option so that it lists them)

clip_image025

Locate the Symantec Enterprise Mobile CA for Microsoft and copy the SHA1 Hash value (right-click command window and select Mark, select SHA1 value and press Enter to copy value).

Now run XapSignTool again with SHA1 hash value specified

"C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\XapSignTool\XapSignTool.exe" sign /v /sha1 XXXX……hash value….......XXXX c:\temp\Provisioning\SimpleCompanyApp.xap

clip_image027

If successfully run then the original XAP will be replaced by the signed XAP. This file can be hosted on a server for downloading directly to device. Should be protected by credentials and available only over SSL. Whilst it is signed it is not encrypted so can be decompiled.

Warning: The permissions on the file may be changed as part of this process. You may need to reset permissions on the file in order for it to be able to be downloaded to the device.

Generate Application Enrolment Token

From command prompt run AetGenerator (first parameter is the backed up certificate; second parameter is corresponding password).

"c:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Tools\AETGenerator\AetGenerator.exe" companyappcert.p12 mypassword

clip_image028

Deployment of Application Enrolment Token

This can be emailed to the device as an attachment

clip_image030

Click on attachment to download. Once downloaded, click on attachment again to open.

clip_image031

Deployment of Signed Application

Open url of hosted XAP file in Internet Explorer

clip_image033

When prompted confirm installation by clicking Install. Application will then install silently (unlike Store that takes the user to where the application is installed in applications list).

clip_image034clip_image036

Windows Phone 8 SDK: Debugging your Application

Depending on whether your application targets WP7 or WP8 you’ll see different options in the devices dropdown. Since it is possible to run WP7 devices on both WP7 and WP8 devices you’ll see additional options for WP7 targeted applications (right image).

image_thumbimage_thumb1

In the same way that you should always test your application on both the emulator and a real device, for a WP7 application you should test on both the wp7 and wp8 emulators, and ideally both wp7 and wp8 devices. In fact with the new SDK the test matrix just got significantly larger as you need to also test the 720p emulator (I’m less worried about the WXGA emulator since in theory it should just scale up from WVGA – the only thing to watch is that images don’t pixelate).

If you didn’t already realise, the new emulator images are actual hyper-v virtual machines. This means that they will appear in Hyper-V Manager. Although, I wouldn’t recommend attempting to tweak the images via the manager!

image_thumb3

The Additional Tools window includes a Network tab, although in my case it’s a little confusing because there are four adapters. Whilst I haven’t been able to get Fiddler to work with the new emulators it does appear that lower level tools such as Wireshark can be used to monitor traffic – it’s useful to see what the IP address of the emulator is via the Network pane so that you can filter the traffic.

image_thumb5

In the Windows Phone 8 SDK there is another tool that can really assist with debugging applications and their behaviour when interrupted. The Tools menu contains a link to the Simulation Dashboard.

image_thumb8

The Simulation Dashboard (adjusts the currently selected emulator in the device dropdown) allows you to monitor the network speed and signal strength. It also lets you trigger the lock screen and a reminder.

image_thumb10

Being able to trigger a reminder will aid in debugging your application, or game, when it is partially obscured, rather than simply when the user navigates away from your application.

image_thumb7

Windows Phone 8: New Project Structure

In the previous post you would have seen that you can now select with a WP7 or WP8 target when creating a new project with the Windows Phone 8 SDK. With earlier SDK versions the choice of target platform made very little difference to the project structure. Now, there are some substantial differences that you should take note of. The following images illustrate the project structure for Windows Phone 7.1 (left) and Windows Phone 8 (right) projects.

imageimage

Here’s some of my observations:

- There is no splash screen image in the template. Actually WP8 does use the same splashscreen mechanism, requiring the file SplashScreenImage.jpg. You can also provide high resolution versions of the splash screen image which need to be named appropriately (see documentation for details). My guess is that because WP8 application start up so quickly (through a combination of improved runtime and precompilation of assemblies etc), the thinking is that the splash screen is not necessary any more.

- ApplicationIcon has been moved into the Assets folder, recognising that most developers like to organise images etc into a sub folder to make it easier to manage files within a project

- Background image has been replaced by a series of tile images (in the Assets\Tiles folder). WP8 supports small, regular and large tiles, as well as flip and cyclic templates. The series of tiles gives you a starting point to working with the different tile formats.

- AlignmentGrid (located in the Assets folder) is an overlay that you can display on any page to see if your controls/text align correctly. Alignment is an important aspect of fit and finish of an application, and is all too often neglected. The result is an application looks unfinished or off balance. You’ll see in MainPage.xaml that there is a element which you can uncomment in order to display this image. Note: IsHitTestVisible is set to False to ensure it doesn’t affect the way that your application operates. You should also take note of the comment in the XAML which indicates you may need to adjust the Margin depending on whether you have the SystemTray visible or not.

        <!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />—>

- AppResources/LocalizedStrings. With the new support for right-to-left text it’s become important for developers to know how to globalize/localize their applications. One step in Globalizing your application is moving string literals out into a resource file (ie AppResources.resx). These strings can be referenced via the wrapper class, LocalizedStrings, which is created as a static resource in App.xaml

<Application.Resources>
    <local:LocalizedStrings xmlns:local="clr-namespace:PhoneApp16" x:Key="LocalizedStrings"/>
</Application.Resources>

These strings can then be localized by creating appropriate resource files for each different language you want to support within your application. Depending on the language specified on the user’s Windows Phone, the most appropriate language will be used within the application.

One last observation is that the list of References has changed. Microsoft has recognised that developers shouldn’t have to add/remove assemblies that are part of the .NET Framework. As such, instead of seeing individual assemblies, developers now see just the frameworks that are references (see below image).

image

Windows Phone 8 SDK: Creating a New Application

It goes without saying that the starting point for any project is going to be the new project dialog. We are of course talking about Visual Studio 2012, where you’ll find all the Windows Phone 8 SDK goodness. What some people don’t realise is that you can do the same thing (ie create projects) in Blend. However, I find Blend to be obnoxious when it comes to file management and dealing with project structure. This is the one reason why I always start in Visual Studio – get your project/solution structure right, and then invite the designers into the room.

image_thumb1

New Project Dialog

The project templates in New Project Dialog, as you can see, haven’t changed much with the exception that in addition to a XAML/XNA template, there is also a XAML/Direct3D. With Windows Phone 8 we can now write native code to be part, or all, of our application or game.

image_thumb4

Native Code Project Templates

There are also a number of native project templates which you can use to create all or part of your project.

image_thumb6

Choosing the Target Platform

Most of the managed project templates you’ll be prompted to choose which platform you wish to target. Clearly if you’re making use of native code, you’ll only be able to target Windows Phone 8. One thing to note is that if you target Windows Phone 7.1 your application will run on both WP7 and WP8 devices but of course, you won’t be able to access any of the new functionality.

Why the iPhone 5 is a Fail

When the iPhone 5 came out I thought it about time that I experience how the other side lives; you know the side that seem to drool at any thing white and shiny (also known as ilunatics for participating in iqueues).  Most people who know me know how Microsoft-centric my world is but from time to time I do step out and try to familiarise myself with other platforms. With this in mind when I renewed my phone contract I signed up for an iphone 5, which of course came with a replacement nano-sim.

Ok, so here are just a few of my observations:

- Why a nano-sim? I don’t believe the space saving warrants being different from every other phone on the market. I had to spend two extra agonising days with the iphone, just because I couldn’t find a converter to go back up to a micro-sim.

- Why the new socket? Ok, not being in the land of white and shiny, I don’t really care that it’s changed. What I care about is the Apple have again defied the industry and gone with their own proprietary connector. Instead of using one of hundreds of micro-usb cables I have floating around, I have to use the white cable that came with the device, and I have to keep it in a locked box for fear on our cats chewing on them (they seem to hate Apple products and will chew on them at any opportunity).

- The apps rock! The one thing I have to say about the iphone is that the quality and depth of apps available is second to none. Whilst some haven’t been adapted to the new height of the iphone 5 they’re still of exceptional quality.

- The core platform does NOT rock When the iphone first came out the interface was revolutionary in the way that users interacted with the device. My comment, even back when the iphone 3 came out is that Apple had failed to innovate with the iphone; evolve, absolutely, innovate, not so. With iphone 4 and now 5 there is nothing that I’ve seen in the core platform that says to me “I’ve got to have that” If you compare the numerous Android devices on the market, the iphone 5 really just doesn’t lead the pack, in fact from a UX perspective it trails a poor third to both Android and Windows Phone.

- The Ads, Really??? I don’t know whether you’ve seen the new TV ads that talk about how they’ve optimised the height of the new iphone 5. I must admit I had to double-take as I thought it was a spoof initially, now I just feel embarrassed for Apple. They must really be scared if they’ve stooped so low. Don’t get me started on the ear buds (as if no other headphone manufacture has shaped their earbuds before, in fact shame on Apple for not having done this sooner) or the dancing ipods.

Lastly, before I sign off I want to make an interesting observation about the timing of the ipad mini v’s Windows 8. As you’re probably aware Apple made their announcement the day prior to Microsoft’s mega Windows 8 launch. It strikes me that Apple might have got this the wrong way round – by putting it the day before, it was almost forgotten the next day when Microsoft went to press. Had they done it the day after, wouldn’t they have taken the focus back from Microsoft back onto Apple. I’m no marketer but would have loved to have heard the logic about the timing of these events.

Don’t forget that next week is BUILD

Windows 8 Launch

For those not living under a rock you’ll have noticed that Windows 8 has been launched. Over the past month or so I’ve been involved in a couple of Windows 8 projects. All three projects made it into the store just in time for the launch events.

image_thumb[1]

With this interlude over, we’ll be back to more frequent Windows Phone updates….

Long time no post

I must apologise for the long absence of posts on this blog. This is due to two factors: the first due to the large workload over the last six months. The second is that I've been posting more frequently over at the Mobile Corner on the Visual Studio Magazine web site. A full list of my posts are linked to from the published link.

If you're in Australia over the coming months, don't forget to come out to TechEd and check out all things Windows Phone and its big brother Windows 8.

Limitations of the WebView in Windows 8 Metro Apps

Having worked quite intimately with the WebBrowser control in Windows Phone I was a little flawed by how immature and annoying the WebView for Windows 8 metro app is. As noted by Brent Schooley in his post on Metro WebView Source and HTML workarounds you can work around some of the limitations such as the missing SaveToString method. One of the features of the WebBrowser control that I quite often use is the series of events that are raised around navigating to pages within the control. Unlike the WebBrowser, the WebView is missing events such as Navigating, Navigated and NavigationFailed, and has only the LoadCompleted event. I figured that I should be able to detect when the current page is changing, and thus raise a Navigating event. Turns out that it is possible with a combination of InvokeScript (to invoke some javascript within the page) and window.external.notify (to raise an event when the page in the browser is changing). The following WebViewWrapper class exposes a Navigating event which you can wire an event handler to in order to detect when the browser is being navigated away from the current page (unfortunately there doesn’t seem to be a way to extract the target url, nor to be able to cancel the navigation, unlike the real Navigating event that the WebBrowser control has). I’ve also included a SaveAsString method which wraps the code Brent had in his post.

public class WebViewWrapper
{
    // Maintain a reference to the WebView control so that
    // we can invoke javascript
    public WebView WebView { get; private set; }

    public WebViewWrapper(WebView webView)
    {
        WebView = webView;
    }

    // The Navigating event is a custom event, allowing us to hook/unhook
    // from the ScriptNotify and LoadCompleted events. To invoke this
    // event, we actually invoke the internalNavigating event.
    private event EventHandler<NavigatingEventArgs> internalNavigating;
    public event EventHandler<NavigatingEventArgs> Navigating
    {
        add
        {
            WebView.ScriptNotify+=NavigatingScriptNotify;
            WebView.LoadCompleted+=WireUpNavigating;
            internalNavigating += value;
        }
        remove
        {
            WebView.ScriptNotify -= NavigatingScriptNotify;
            WebView.LoadCompleted-=WireUpNavigating;
            internalNavigating -= value;
        }
    }

    // When each page loads, run a javascript function which wires up
    // an event handler to the onbeforeunload event on the window.  This
    // event is raised when the window is about to unload the current page
    // In the event handler we call window.external.notify in order to raise
    // the ScriptNotify event on the WebView. The javascript function also
    // returns the current document location. This is used to update the
    // AllowedScriptNotifyUris property on the WebView in order to permit
    // the current document to call window.external.notify (remembering
    // that even though we injected the javascript, it’s being invoked in the
    // context of the current document.
    private void WireUpNavigating(object sender, NavigationEventArgs e)
    {
        var unloadFunc = "(function(){" +
                            " function navigating(){" +
                            "  window.external.notify('%%' + location.href);" +
                            "} " +
                            "window.onbeforeunload=navigating;" +
                            "return location.href;" +
                            "})();";
        var host = WebView.InvokeScript("eval", new[] { unloadFunc });
        WebView.AllowedScriptNotifyUris = new[] { new Uri(host) };
    }

   // Check to see if the ScriptNotify was raised by the javascript we
   // injected (ie does it start with %%), and then raise the Navigating
   // event.
   private void NavigatingScriptNotify(object sender, NotifyEventArgs e)
    {
        if (internalNavigating == null) return;
        if(!string.IsNullOrWhiteSpace(e.Value))
        {
            if(e.Value.StartsWith("%%"))
            {
                internalNavigating(this, new NavigatingEventArgs() {LeavingUri = new Uri(e.Value.Trim('%'))});
            }
        }
    }

    public string SaveToString()
    {
        try
        {
            var retrieveHtml = "document.documentElement.outerHTML;";
            var html = WebView.InvokeScript("eval", new[] { retrieveHtml });
            return html;
        }
        catch
        {
            return null;
        }
    }
}

public class NavigatingEventArgs:EventArgs
{
    public Uri LeavingUri { get; set; }
}

Actually making use of the WebViewWrapper class is as simple as creating an instance and then wiring up an event handler.

public BlankPage()
{
    this.InitializeComponent(); 

    var wrapper = new WebViewWrapper(MyWebView);
    wrapper.Navigating += WrapperNavigating;
}

void WrapperNavigating(object sender, NavigatingEventArgs e)
{
    Debug.WriteLine(e.LeavingUri);
    Debug.WriteLine((sender as WebViewWrapper).SaveToString());
}

Timeout of HttpWebrequest and WCF service calls on Windows Phone

Firstly, I’m ashamed that the Windows Phone team didn’t do a better job of providing an ability to set a Timeout for either HttpWebRequest, WebClient and WCF service requests. You might be thinking…. but it’s Silverlight and everything’s Async all the time. Well you’d be correct in that thought process but just because something is asynchronous, doesn’t mean that the user isn’t sitting there waiting for something to complete.

For example say you have a simple form that the user has to fill in before they can proceed (eg “create user” form). Clearly if they are on a good network then you’d hope that the service request returns almost instantaneously and the user is cleared to proceed within the app. However, if for whatever reason the request takes longer than expected (slow network, busy server etc) you don’t want the user to sit there indefinitely. After about 10-20 seconds they’re going to get frustrated and probably close and then uninstall your application. Simple solution is to put a Timeout on your service calls so that you can notify that there is something wrong and that they should try again later or check their connection.

Simple you say…. not so. There is no Timeout property that you can set on either HttpWebRequest, WebClient or on the WCF proxy classes that are generated by Add Service Reference. Luckily there are a number of good posts already on the web that cover the basics of implementing a timeout for doing HttpWebRequests (for example this post on stackoverflow).

What isn’t as well covered is how to implement a Timeout for WCF service calls. The challenge with implementing a Timeout property is trying to wrap the asynchronous pattern that the WCF proxy generates. For example if you have a service method called “Authenticate” the proxy will have a AuthenticateAsync method and an AuthenticateCompleted event. Attempting to use these to implement a Timeout is going to result in some very messy code. The other thing to consider is that .NET is evolving towards having true asynchronous support in the form of asynchronous method support. This is built in for WinRT and can be incorporated into your Windows Phone applications today using the Async CTP.

In this post we’re going to use the Async CTP to do two things. Firstly, wrap the fictitious Authenticate service call into an asynchronous operation and secondly give it Timeout support, again through the use of an async operation. The code is implemented as a partial class to the proxy class that is generated when you do  “Add Service Reference”. It does required you to implement the first method for each service method that you want to wrap.

namespace PhoneApp30.MyServices
{
    public partial class SimpleServiceClient    {
        public async Task<string> Authenticate(string username, string password, object state = null)
        {
            return await Async( (cb,st)=>
                Channel.BeginAuthenticate(username,password,cb,st),
                Channel.EndAuthenticate, state);
        }
        private async Task<TResult> Async<TResult>(
            Func<AsyncCallback, object, IAsyncResult> beginMethod,
            Func<IAsyncResult, TResult> endMethod,
            object state)
        {
         
            var method = Task<TResult>.Factory.FromAsync(
                beginMethod,
                endMethod, state);
            return await InvokeWithTimeout(method);
        }
        public async Task<TResult> InvokeWithTimeout<TResult>(Task<TResult> method)
        {
            var newTask = Task.Factory.StartNew(() =>
            {
                if (!method.Wait(30*1000))
                {
                    Abort();
                    throw new TimeoutException();
                }
                return method.Result;
            });
            return await newTask;
        }
    }
}

Now we can call the Authenticate method from our code in a relatively synchronous manner. Note the difference is that this won’t block the UI as it is an asynchronous operation.

async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    try{
    var client = new SimpleServiceClient();
    var result = await client.Authenticate();
    Console.WriteLine(result);
    }
    catch(TimeoutException ex){
        // Handle timeout 
    }
}

TripleDes Encryption with Key and IV for Windows Phone

Given how long TripleDes has been around you would have thought that it would be just part of any decent platform. Not so! Unfortunately Windows Phone support for cryptography in the core apis seems to be quite lacking (although it does now have DPAPI support for protecting local data). There also seems to be a lack of good documentation/examples on how to get existing code bases to work. It turns out that it’s not that hard if you reuse the massive Bouncy Castle cryptography library (http://www.bouncycastle.org/csharp/). Here are the steps to encrypt and decrypt with TripleDes using the Bouncy Castle library for Windows Phone.

The first step is to download the source code from http://www.bouncycastle.org/csharp/. Whilst there are binaries there I didn’t see a set built for Windows Phone.

With the source code downloaded, you’ll need to expand the zip and copy the contents of the \bccrypto-net-1.7-src\csharp\crypto folder into a new Windows Phone Class Library project. You’ll most likely have to exclude the default AssemblyInfo.cs file too in order for it to compile.

Next step is to reference the class library from your application and now you’re good to start using the API.

We’ll start by declaring a very basic UI – in this case made up of an input TextBox for the value to be encrypted, then two output TextBlocks for the encrypted and the subsequent decrypted values. There are two Buttons to instigate the encryption and decryption to make the process easier to follow.

<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <TextBox x:Name="TextToEncrypt"
               Text="Text to encrypt" />
   <Button Content="Encrypt"
            Click="EncryptText" />
   <TextBlock x:Name="TextToDecrypt" />
    <Button Content="Decrypt"
            Click="DecryptText" />
    <TextBlock x:Name="DecryptedText" />
</StackPanel>

To perform the encryption we’re going to need a Key and an Initialization Vector (IV). The following is a randomly created key and doesn’t correlate to any production or test keys that I’m aware of.

private static readonly byte[] Key = new byte[]
                                            {
                                                34, 77, 23, 23, 43, 73, 23, 43,
                                                2, 64, 23, 67, 34, 12, 32, 5,
                                                3, 64, 75, 23, 54, 23, 12, 52
                                            };

private static readonly byte[] IV = new byte[] { 2,45,123,22,66,234,45,34 };

The majority of the work is done in the RunTripleDes method, which takes two parameters: the input value and whether you want it encrypted (true) or decrypted (false). The important thing in this method is to make sure you initiate the Cipher engine with the correct parameters. The following uses the parameters that are consistent with the default TripleDESCryptoServiceProvider that is available to applications written using the full .NET Framework (ie Mode is CBC and Padding is PKCS7). If your encryption needs are different then look through the CipherUtilities class to see what parameters you need to specify in the GetCipher method and then make sure you provide the appropriately structured parameter to the Init method.

public byte[] RunTripleDes(byte[] input, bool encrypt)
{              
        var keyParam = new DesEdeParameters(Key);
        var ivParam = new ParametersWithIV(keyParam, IV);
        var engine = CipherUtilities.GetCipher("DESede/CBC/PKCS7PADDING");
        engine.Init(encrypt, ivParam);
        var output = engine.DoFinal(input);
        return output;
}

To make the code a little easier to follow, we’ll add Encrypt and Decrypt methods to wrap the RunTripleDes method.

public byte[] Encrypt(byte[] input)
{
    return RunTripleDes(input, true);
}
public byte[] Decrypt(byte[] input)
{
    return RunTripleDes(input, false);
}

Lastly, we just need to invoke these methods from the respective button Click event handlers.

private void EncryptText(object sender, RoutedEventArgs e)
{
    var input = Encoding.UTF8.GetBytes(TextToEncrypt.Text);
    var encryptedValue = Encrypt(input);
    TextToDecrypt.Text = Convert.ToBase64String(encryptedValue);
}

private void DecryptText(object sender, RoutedEventArgs e)
{
    var input = Convert.FromBase64String(TextToDecrypt.Text);

    var decryptedValue = Decrypt(input);
    DecryptedText.Text = Encoding.UTF8.GetString(decryptedValue, 0, decryptedValue.Length);
}

You’ll have noticed that we use the UTF8 encoder to convert the input text into a byte array for encryption but that we use the ToBase64String static method on the Convert class to convert the encrypted byte array into text for displaying. We could use the UTF8 encoder to do this but you’d find that when you attempt to convert back to a byte array you may lose bytes. Using ToBase64String and FromBase64String ensures you don’t lose any data in the conversion back and forth from string format – this is particularly important if you’re going to send the encrypted data across the wire (for example a SOAP or REST service)

Ok, let’s give this a whirl – running the application you should be able to enter some text in the TextBox, click the Encrypt button and see the encrypted data, then click the Decrypt button to see the original text appear again (as in the image below).

image

Hope this helps you get started using Bouncy Castle for working with TripleDes in your Windows Phone application.

Missing Background Image on Panorama Control breaks ContextMenu and Causes Performance Issues in Windows Phone Applications

Warning: If you are using a background image for a Panorama control in your application, make sure you get the path correct. Here’s why:

Today I was working on a relatively complex application that uses the Panorama control on the main page of the application. It also has a context menu on items in a couple of the panes with the panorama control. Up until this afternoon everything seemed to work fine. However, as we get close to finishing the project I decided to go through and clean up the images that were included in the project (if you’ve ever worked with a designer or spent a lot of time in Blend you’ll understand why I have to do this step!). Now in most cases your application will continue to work even if the path to your images are wrong – you just won’t see an image where you expect to. This can make it a little hard to ensure you haven’t broken anything as part of the clean up process.

After doing the clean up I did notice that I’d broken a couple of image paths but figured that I’d fixed most of them. I did however also notice that the application was performing really slowly, like it would take a second or so to add a character into a textbox. As I mentioned this is a relatively complex application so I thought that I must have broken some logic in the background causing a perf issue. What I didn’t realise was that the perf issue was related to my image clean up.

Figuring I’d come back to sort out the perf issue later (I’ve been focussed on getting one part of the app finished today so head was in a different place in the app dev cycle) it wasn’t until I noticed another bug that I had to stop what I was doing and address the issue (although at the time I figured it was unrelated). It turned out that none of the the context menus (from the Silverlight toolkit) were working. OMG I thought, what have I done now…. I even thought I’d ping Jeff and see whether he had any gems of wisdom.

One of my golden rules is that I always use source control. Whether it is a simple project I’m working on by myself, or a large project, I always check in my code and frequently. The context menus had been working so I then spent the next hour trawling back through the source control history until I got back to a working version. I then walked forward gradually trying to isolate the issue. Eventually it came down to a missing “/” in the path to the background image for the Panorama control…. really…. yes, really!!! If you get the background image path wrong you will:

- Cause MAJOR performance issues in your application as the panorama control will continually look for the background image (well I’m guessing that’s what it’s doing but either way it’s a major UI performance drain)

- Prevent any ContextMenus from working on that page of your application

- There are probably other controls that may not work well.

Disclaimer: You might be thinking “why didn’t he notice the missing background image”…. in most case you’d be right as the background is usually hard to miss. In this particular instance the background image is very very subtle, just enough to give some visual feedback when the user pans. It looks great but you actually don’t notice it missing unless you’re looking for it.

Bookmark for Mobile App Design Guidelines

Windows Phone

Themes for Windows Phone
http://msdn.microsoft.com/en-us/library/ff769554(v=vs.92).aspx

User Experience Design Guidelines for Windows Phone
http://msdn.microsoft.com/en-us/library/hh202915(v=vs.92).aspx

 

Android

http://developer.android.com/design/index.html

 

iOS

iOS Human Interface Guidelines
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html

Framework Exceptions in Windows Phone

One of the switches that I often enable in Visual Studio is for it to notify my whenever an exception is thrown. This includes exceptions that are thrown internally by the .NET Framework. To enable this option, launch the Exceptions window from the Debug menu.

image

Select the Common Language Runtime Exceptions and check the Thrown checkbox. Click OK to apply this change

image

Now when you run your application you will see any exceptions that are raised, even if they are handles by you or the .NET Framework. Unfortunately sometimes this can be a bit of a drag because the .NET Framework does quite often throw exceptions, sometimes for legitimate reasons, sometimes not so. One such case is for both the CheckBox and RadioButton (actually the ToggleButton which is the base control is the source of this issue). After enabling Exceptions, add the following xaml to a new project.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <CheckBox Content="Checkbox 1" />
</Grid>

Run your application and you will see the following, completely meaningless, exception being raised.

image

If you look at the call stack, apparently something is calling ToString on the ToggleButton control (ie the base control for the CheckBox you just added).

image

If you examine the ToString code, you’ll see something similar to the following, and you can see the reference to Resx.GetString. From the callstack this seems to be the issue.

public override string ToString()
{
    string text = base.ToString();
    string text2 = (base.Content ?? "").ToString();
    bool? isChecked = this.IsChecked;
    return string.Format(CultureInfo.InvariantCulture, Resx.GetString("ToggleButton_ToString_FormatString"), new object[]
    {
        text,
        text2,
        isChecked.HasValue ? isChecked.Value.ToString() : "null"
    });
}

Following this even further you eventually get to the internal Resx constructor where you can see that it attempts to load an assembly (see second line of the above callstack). This is the line that is failing, because the System.Windows.debug.resources assembly doesn’t exist for us developers Sad smile

internal Resx()
{
    Assembly assembly = base.GetType().Assembly;
    this.resources = new ResourceManager("System.Windows", assembly);
    string assemblyString = "System.Windows.debug.resources, Version=2.0.5.0, Culture=en-US, PublicKeyToken=7cec85d7bea7798e";
    try
    {
       Assembly assembly2 = Assembly.Load(assemblyString);
        this.debugResources = new ResourceManager("System.Windows.debug", assembly2);
    }
    catch (FileNotFoundException)
    {
    }
    this.fallbackResources = new ResourceManager("mscorlib", typeof(object).Assembly);
}

 

The work around for this is relatively simple. Create your own Checkbox class that inherits from CheckBox and override the ToString method.

public class MyCheckBox:CheckBox
{
    public override string ToString()
    {
        return string.Empty;
    }
}

Add this to your layout in place of the CheckBox

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <PhoneApp23:MyCheckBox Content="Checkbox 1" />
</Grid>

Run: Look, no Exceptions!

NOTE: Whilst the fact that the exception is thrown in the first place probably isn’t great coding, it has little, if any, effect on your app running in production. I’ve described this work around purely to get around the annoyance of the FileNotFoundException being picked up (the other way would be to specifically exclude this type of exception in the Exceptions dialog). Some ad-hoc testing indicates that this exception has an insignificant effect on performance or rendering times.

SocialViewer gets Windows Phone Mango treatment

As some of you may be aware I was involved in a project last year to enable developers to quickly build reading style applications. This started off as a simple template allowing users to pull in RSS data but exploded to be much more versatile. The template was made available at http://socialviewer.codeplex.com and is freely available for any Windows Phone developer to download and use.

Since the initial version we’ve made a number of enhancements to both functionality and the default look and feel. Over the festive season I started transitioning (and upgrading) the template to take advantage of the new Mango features. The configuration file (where you could previously only configure the feeds and lists for the application) now allows you to control layout, Ads and integration with various social networks.

I’m going to be doing a series of posts over the coming weeks on some of the new features of the Social Viewer template. We’ll start today with a recap of getting started with the template.

Step 1: Download the template

Go to http://socialviewer.codeplex.com and download the latest build from the Source Code tab. IMPORTANT: At this stage the latest version is still an Alpha release, which means that it’s probably not suitable for publishing apps. We’re hoping to get an official release out this month and would love any feedback you have.

Step 2: Unblock the Download

Gotta love Windows security – make sure you right-click the downloaded file, select Properties and then click the Unblock button.

image

Step 3: Extract the Download

Extract all the files from the changeset. There should be two files: a Zip file which is the template (don’t extract this file), and an OUT OF DATE word document that talks about the template (which for the time being you can ignore).

Step 4: Installing the Template

Copy the Zip file that was extracted out of the changeset (should be called BuiltToRoam.SocialViewer.Template.Zip) and place this file into your Visual Studio Templates folder. For example my templates folder is the following. Note that I added the “Silverlight for Windows Phone” sub-folder so that the template appears with all the other Windows Phone project templates.

C:\Users\Nick\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual C#\Silverlight for Windows Phone

Step 5: Run Visual Studio

Visual Studio should automatically pick up the new template even if it is already running. However, if you’re updating from a previous version of the SocialViewer template, you may need to restart Visual Studio for it to pick up the new version.

Step 6: Create a New SocialViewer Project

File –> New –> Project

Select the SocialViewer template and give the project a new name. The is currently a bug that means if you put a space in your project name you’re going to enter a word of pain. DO NOT PUT SPACES IN PROJECT NAME

image

Step 7: Run

That’s it…. out of the box you should literally be able to just run the newly created project. Please do not simply create a new project and publish it via Marketplace. That’s not the intent!

Here are some screen shots of the latest build:

image image image image

Main panorama: What’s new - vertical list of new feed items; Recent – hubtiles with images from Flickr; link list to pivot page, website (ie built to roam) and the about page.

image image image

On demand pivot (sources are only downloaded when the pivot is accessed). Reading page illustrating two different layouts: The default; WebBrowser for RSS feed items

image image

The Settings and About pages. Note the long list of social providers that can be used within your applications (See the configuration file) and the variety of data sources that you can consume (again, see configuration file).

Sydney Hobart Yacht Race and the Lack of Sailing Apps

Recently I enjoyed watching the highlight from the Perth 2011 ISAF Sailing World Championships but was disappointed in the lack of mobile accessibility for results and information about the event. Whilst the website was functional, and actually looked quite good if you were viewing it on a desktop/laptop computer, it left a lot to be desired when accessing it via a mobile device. It seems surprising that given the push by the sailing fraternity to raise the profile of the sport that there was no consideration given to building an application for any of the mobile platforms.

The second failure of the sailing community is this year's Rolex Sydney Hobart Yacht Race. Personally I’m not a big fan of the design of the website but I do like the Yacht Tracker system they’re using. Unfortunately again there are no apps available for any of the mobile platforms as far as I’m aware.

Yesterday after watching the start to the Sydney Hobart on TV (yes, even though I live in Sydney I actually think you get a better view of the start via TV that fighting the crowds at either of the heads) I decided that I would put together a quick Windows Phone application using the data exposed by Twitter, the RSS feed and the data feeds that Yacht Tracker uses. I haven’t bothered to submit the app to Marketplace as the race would be over before it gets approved. Unfortunately this means that only users with an unlocked/developer Windows Phone can use the app.

My apologies if you can’t run the app, send me an email via the website and I’ll see what I can do to get you a trial version. I’ve also included the following screenshots so you can see what you’re missing (remember, this is less than 8 hours of work!)

sh1 s2 s3 s4

 

Updated 28/12/2011 00:20: Now supports background agent support for updating primary live tile with race leaders.

Updated 28/12/2011 11:13: Added multi-tile support, boat details, full page map support and about page.

Nokia Windows Phone Competition

I just realised that I haven’t posted for a while on this blog. I have however been posting across at both Visual Studio Magazine (Mobile Corner) and on BuildMobile (Windows Phone). A full list of postings and books is available here

 

image        image

The core purpose of this post is to let you know, or remind you, that we’re currently running a competition where you can win a Nokia Windows Phone by answering a question and tweeting a link. The full details and conditions for entry are outlined in the post, Win a Nokia Windows Phone. So far we’re posted four questions, with more to come. Don’t worry if you haven’t answered any so far, you can go back and answer the existing questions as entries will stay open until the competition closes.

Question 1: List a navigation API and provide a short example of how you might use it within your application?

Question 2: Other than the controls that ship with the Windows Phone SDK, what controls do you use in your application, and how do they make your application rock?

Question 3: Discuss one feature, or design, of an application you’ve worked on (doesn’t have to be published) that makes it distinctly Windows Phone?

Question 4: List an API (or a set of APIs) that allow developers to build Windows Phone applications that integrate with either device hardware or into the core platform (e.g. integration into one of the hubs)?