Wednesday, June 26, 2013

Two cool things in Windows 8.1 I'd like to see come to Windows Phone

With the first real Windows 8.1 details being announced today a few new features have jumped out at me as being cool to see in Windows Phone in the future.

There will no doubt be other features that get announced and/or I may learn about that would be great to see included in Windows Phone V next, but as Microsoft have said that there are plans to bring greater parity between the two platforms this may be possible.

Multiple images on the lockscreen (that alter like a slideshow) 

Having a dynamic lockscreen is brilliant but often you want more than one app to be providing the informaiton. This coudl be a solution.

Automatically updating apps without requiring user intervention 

Because people are very bad about updating when left to do it themselves.

There are, of course, new APIs and apps that it wolud be nice to see come to Windows Phone but I thought these 2 features were worth special note.

What is there on "Big Windows" that you'd like to see come to Windows Phone?


To be clear, I have no knowledge of what will be in any future version of Windows Phone or when that may be. This is just me thinking out loud about what I'd liek to see.




Links to all the Windows Phone related sessions at BUILD 2013

Wednesday, June 19, 2013

What is required when implementing Fast App Resume?

Windows Phone 8 introduces the concept of Fast App Resume.

Unfortunately this is a much confused and misunderstood feature.

Fas App Resume (FAR) is a purely technical setting that controls what the OS should do with existing instances of the application when the user does something which would, traditionally, try and launch a new instance.

Enabling FAR tells the OS that it should load any exiting application instance before starting a new one.

FAR does not define what should happen with the existing instance is NOT universally defined. Each app should do what is best/most appropriate for that app if begin launched via FAR.

When implementing Fast Resume, you must decide what is the best user experience for you app when launched from the different launch points that are available on the phone.

Enabling FAR does not mean that every app should always maintain an existing back stack when an existing instance is resumed due to FAR.

Windows 8 has a recommendation that apps should hide whether they are being launched afresh or an existing instance is reloaded. Apps, when launched, should always display themselves as they were when last viewed, regardless of how long ago that was or if the devices has been turned off (or rebooted) in the meantime.

This recommendation does not exist historically in Windows Phone and has not been made now.

In Windows Phone (7.x) there was a recommendation that apps should be predictable and always do the same thing when launched.

I see no reason why that recommendation does not still stand. Windows Phone apps should provide a consistent, predictable experience when launched.

But what about the built in apps?
Looking at the built in applications is always a great guide for what your apps should do. There's a problem here though. The built in applications can have multiple instances in the back stack.
The built in apps will launch a new instance in the same predictable way. The back stack maintains multiple instances in their different states.
There are also built in apps which remember where you were previously whenever the app is launched, regardless of other instances in the back stack.

It would be great if Microsoft had provided some information about why this feature (FAR) was added. I'd hope it's driven from research about how users are trying to use apps on the phone. To see the data behind such research would be awesome.

I suspect this may have been added to try and drive Win8 parity...

So what about some guidelines*:
  • Enable Fast App Resume so that load time will be faster if an instance of the app already exists in the back stack.
  • Launching from the main tile or app list always opens the app on the main page.
  • Launching from a deep link (secondary tile) or otherwise) should launch direct to the
  • Adding a home button should always be very carefully considered and you need a very strong case for adding one.
  • Regardless of whether an existing instance of an app was loaded or not, any back stack should be cleared when starting the app again.
  • If your app will show the last page shown when previously opened, this behaviour should be implemented regardless of how the app was started.
An exception:
  • If the user was performing a complicated or long process when they left the app and it would be frustrating to lose that context, data or state then it may be appropriate resume where the user left off. It may also be useful to provide a way to allow the user to return to the main page though.
*entirely my opinion and I reserve the right to change this opinion either wholesale or on a case by case basis ;)

If you do implement FAR and you have page navigation animations that animates the PhoenApplicationFrame you may need to consider how you avoid spurious animations when FAR occurs. I've handled this by hiding the frame while navigation and back stack manipulation is performed as part of the resume process.

If you want an easy way to enable support in your project without having to manually edit the WMAppManifest.xml file, there's a nuget package to help.


Tuesday, June 18, 2013

Comparing 3rd party Windows Phone control sets

The Windows Phone SDK only includes a relatively small number of controls. For all but the simplest of apps you'll likely need more. In this situation you can look to build them yourself or use controls created by others. There are many available and they vary in cost, size and what they include.

Below is a comparison of the controls available in the largest and most popular sets.

These collections are:


(Click for larger version)

There are also many other smaller collections and individual controls included in the Geek Champ Component Marketplace.

Obviously the above chart will no longer be correct when the control sets are updated but I believe it to be correct at the moment. ;)


Making modifying WMAppManifest.xml easier

When it comes to some of the more advanced features of Windows Phone 8 development you may need to make changes to the manifest file (WMAppManifest.xml) which the SDK doesn't provide a nice visual way to do.
In this scenario it means opening the xml file in a text editor and, probably, copying and pasting the required pieces for the appropriate page on MSDN-after you've searched for and found it.

Obviously this isn't an ideal way of working and recently I felt something needed to be done.

After exploring a few possibilities, I've created nine new NuGet packages which will allow you to modify the WMAppManifest.xml file to indicate supporting:

  • New tile formats, via reflection, when a 7.X app is run on a 7.8 or 8.0 device.
  • Background location tracking
  • Fast-App-Resume
  • Lock Screen background images
  • Lock Screen notification text
  • Lock Screen notification counts
  • All Lock Screen items (rather than adding them individually)
  • Lauching via a custom schema
  • Custom file formats/extensions

You can find the packages by searching for "WMAppManifest"
Or, if like me, you're super lazy (efficient), you can search for "WMAM" (the acronym) and you'll find them that way too.

The package will make appropriate modifications to the WMAppManifesst.xml file and add a readme file to the project.
When you uninstall the package the readme file is removed but the modifications to the XML file remain.
This is deliberate. The NuGet package is just a means to an end. There is no expectation that you'll need to update the package in the future so you can uninstall it immediately after it's been installed. This will mean you have no unnecessary dependencies in your project.

If you are adding support for file extensions or a custom schema you'll still need to modify the file manually to set the schema name and file extension. Everything else is set up though. You just need to alter the "ChangeMe" or "SetMe" values. This is documented in the readme file for each package so you may want to read that before removing the readme file and/or uninstalling the package.

You can find all the packages at nuget.org if you want to explore them in a bit more detail.

If you think these could be useful, you use them, find an issue or have any other feedback I'd love to hear it. Please do share your thoughts and experiences with this. It's my attempt to help make Windows Phone development that little bit easier for everyone.




Tap, Click, Command or Select - How to trigger navigation.

Here's a scenario: You have a number of items on a page and you want the person using the app to be able to touch one of those items and have the app navigate to another page.

It's a simple and common scenario. It's also one where there are lots of ways of implementing the
behaviour. But which one should be used?

The navigation part is pretty straight forward but how to detect the "touch" and intent.

There are four options available:
  1. Contain each item in a Button and use the `Click` event to detect the users action.
  2. Use the `Tap` event on the containing UIElement to detect the users action.
  3. Contain each item in a Button and bind to the `Command` to detect the users action.
  4. If the items are in a  ListBox (or similar) use the SelectionChanged event to determine the users action.
Some may think there is no difference or they're interchangeable but there are some important differences.

A Click event occurs when contact is made with the sceen and the same control is still under the touch point when contact is lost. This is regardless of how long the touch was made for or what happened in the mean time. This means you can move around the screen, move off of the control and back onto it, move the control within a scrollable area, and as long as there is no other control which will capture the gesture, swipe across the control and still trigger the click event. This may be more than you want or a user will expect to trigger the action/navigation.

A Tap event is intended to be used when you want to capture the users intention to interact with a screen element by tapping it. To trigger the tap event of a control contact must be made and released within a short period of time (about 300ms) and without the touchpoint moving more than a small amount.  This avoids the event being triggered by pressing on something for a long period of time or when moving a control on the screen. This is what you should be using instead of a `Click` event as it is designed and created to be used for finger based interaction while the click event was created for use with a mouse.

Using the SelectionChanged event for items in a ListBox (or similar) is a popular technique as it is used by the DataBound project template. There are a couple of issues with this though. The first is that you must clear the selection after it's made to allow the selection of the same item again. The second, and bigger issue in my opinion, is that this is a misuse of what the ability to select an item is for. The ability to select an item (or items) is to enable it to be distinguished from the other items in the group. That's why there's a selected state. It allows you to see which items have been selected, so you can act on them. Thirdly, triggering a change in the selected item can also happen accidentally when scrolling a list.
If you have multiple items in a list and want to be able to perform an action when one of them is tuched, it would be better to use a Tap event on the individual item, rather than an event attacehd to the outer collection.
Like this:

    <ListBox ItemsSource="{Binding ListOptions}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Tap="ItemTapped">
                    <TextBlock Text="{Binding}" />
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>


But, I hear you say, what about MVVM? I don't want to use coded behind, I want to bind the action to an ICommand on the ViewModel.

Yes, the ICommand is the solution here and the ButtonBase control has a Command property that you can bind your ICOmmand implementation to. But how is it triggered?
Disappointingly, from my perspective, it is triggered by either a Click or Tap event. This means that it can still be triggered in the same unexpected and undesired ways as a Click event.

Fortunately it's easy to create a user control that has the ability to call an ICommand implementation when it is Tapped and not Clicked.

Here's the incredibly simple XAML you need:

<UserControl
    x:Class="TapClickCommand.TapCommandControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Tap="ControlTapped" />

Yes, it's just an empty control with a Tap event handler wired up.

Then we just need the code to make it work:
namespace TapClickCommand
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
 
    public partial class TapCommandControl : UserControl
    {
        public readonly DependencyProperty TapCommandProperty =
            DependencyProperty.Register(
                "TapCommand",
                typeof(ICommand),
                typeof(TapCommandControl),
                new PropertyMetadata(null));
 
        public readonly DependencyProperty TapCommandParameterProperty =
            DependencyProperty.Register(
                "TapCommandParameter",
                typeof(object),
                typeof(TapCommandControl),
                new PropertyMetadata(null));
 
        public TapCommandControl()
        {
            InitializeComponent();
        }
 
        public ICommand TapCommand
        {
            get { return (ICommand)GetValue(TapCommandProperty); }
            set { this.SetValue(TapCommandProperty, value); }
        }
 
        public object TapCommandParameter
        {
            get { return GetValue(TapCommandParameterProperty); }
            set { this.SetValue(TapCommandParameterProperty, value); }
        }
 
        public void ControlTapped(object sender, GestureEventArgs e)
        {
            if (this.TapCommand != null)
            {
                this.TapCommand.Execute(this.TapCommandParameter);
            }
        }
    }
}


You use it just like the Command property in ButtonBase.
e.g.

    <local:TapCommandControl TapCommand="{Binding TheTapCommand}"
                             TapCommandParameter="{Binding Id}">
        <TextBlock Style="{StaticResource PhoneTextLargeStyle}"
                    Text="{Binding Name}" />
    </local:TapCommandControl>

Voila!


So, to summarize:
Use a Tap event, rather than Click or SelectionChanged if using code behind.
Bind commands to be triggered by a Tap event rather than a Click event if using commanding.




Saturday, June 15, 2013

Renewing a Windows Phone developer subscription with an MSDN token

For the last 3 years I've paid (yes, with real money) for my Windows Phone developer subscription. As I've just come up for renewal again I wanted to use the token I get as part of my MSDN subscription (that I also pay for).

In the phone dev centre there was a nice link prompting me to renew. On that renewal page there was an option to pay for renewal or enter a code. Obviously I wanted the "enter a code" option but where to get that code from? Unfortunately it wasn't as easy to find as I would have liked so I thought I'd share it here.

It's actually quite simple (once you know how)

  • Log into your account on msdn.microsoft.com.
  • Got to https://msdn.microsoft.com/en-us/subscriptions/manage/
  • Under the Subsccription Benefits find "Windows Phone developer account"
  • Click on the "get code" link to reveal your code - it is a GUID
  • Enter that code (GUID) in to the phone dev center renewal page.
  • Done!

Hope this helps.



Wednesday, June 12, 2013

ShellTile.ActiveTiles sometimes forgets about one of the tiles

A couple of times, when working with an app with lots of tiles pinned, I've seen `ShellTile.ActiveTiles` "forget" about one of the tiles.  By that I mean that when updating all the tiles from a background agent one of them isn't updated.

This is with code like:

    foreach (var tile in ShellTile.ActiveTiles)
    {
        // update the tile.
    }


At the moment I only have anecdotal evidence of this behaviour but wondered if anyone else could shed any knowledge or experience of this while I continue to investigate.

Deleting and repinning the tile in question seems to make the problem go away but this isn't a real solution.
Additionally it doesn't seem like it's the first or last created pin but I can't be sure of this.

Has anyone else seen this?



Saturday, June 08, 2013

LongListSelector does not "play nicely" with a static DataContext

Here's a lesson from a day lost to debugging an obscure issue.

Microsoft recommend that you should "use the LongListSelector instead of ListBox for phone apps".

That's great advice, especially if upgrading an existing app where ListBox wass used previously. But there's a gotcha you may need to be aware of.

If a LongListSelector is bound to a static ItemsSource then a reference is held that stops the page being collected. This means that such a page would leak memory!
If it's a large or complex page or one that is opened a lot (so you end up with lots of copies in memory) this could be very bad for your app.

This doesn't happen when bound to a non-static source. It also doesn't happen when using a ListBox bound to either a static or non-static object.

If you're upgrading an app built several years ago when using a static view model seemed like a not unreasonable way to architect an app you may be more likely to hit this. (That's why I discovered the issue-when upgrading an app originally written in 2011.)


Don't believe me or want to see this in action for yourself?
I've put a project at https://github.com/mrlacey/WPMisc/tree/master/LlsStaticTest which demonstrates all the above.
It allows opening of pages which contain:
  • a ListBox bound to a static object; 
  • a ListBox bound to a non-static object; 
  • a LongListSelector bound to a static object; 
  • a LongListSelector bound to a non-static object; 
  • and a way to force garbage collection.
Each page also outputs creation, navigation and destruction information to the debug window.
To see this in action, open each page then tap "FORCE GC" twice and you should see the destructors for all but the static LongListSelector page being called.
You can also see the same by running the app through the memory profiler but I think it's easier and faster to see this problem via the debug output.

There are two ways to address this issue:
  1. Remove the use of a static view model. Depending on your application this may or may not be a viable solution but I would recommend against using a static view model whenever possible.
  2. Remove the binding when backing out of the page. It feels slightly imperfect but works and is easy to do.

To remove the binding when leaving the page, just do something like this.

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);
 
    // The following removes the binding of the LLS to the VM
    // so the page can be collected
    if (e.NavigationMode == NavigationMode.Back)
    {
        this.DataContext = null;
    }
}

Note that this is done in OnNavigatedFrom and not in OnNavigatingFrom as if done before you have navigated away from the page the removal of the binding may cause the UI to update and you may see screen flicker before the page closes.

This discovery was found via a lot of experimentation, insight and a process of elimination.I couldn't find any indication of what was holding a reference via the profiler. If you know where this would be indicated (or even hinted at) I'd love to know.



App store credibility

I'm thinking out loud here. If I wander I'm sorry. If I cause you to jump to conclusions, please don't attribute them to me if they're your conclusions rather than mine.

Do apps that get featured in the marketplace/app store matter?
It's been well documented that being featured in the store directly leads to an increase in downloads. In that respect, being featured matters to the person who owns/created the app. But I wonder...

Do they have a bigger impact?
Do featured apps impact more than just those who created or downloaded the app?

Does the quality of a featured app impact opinion on other apps?

If it's the featured app I'd expect it to be either highly popular or (and hopefully "and" as well) of a very high quality.

If a featured app isn't very good (however that's defined) isn't it reasonable to assume that, as a consumer of apps, I should not hope for very much from other apps either? Afterall isn't the purpose of a featured app to highlight something I may want to install and use? Why would something that isn't very good be featured?* You want me to install crummy apps that aren't as good as others which do the same thing?


I see many featured apps that aren't very good, do not give me confidence in the general quality of other apps, are buggy or otherwise very poorly designed. :(

And a related question:

Does the credibility of the store affect apps? and the platfom?
Let's take, as an example, a recently featured app.
I'm anonymising the app in case my comments are taken as being focused directly at the app. That's not my aim. I'm trying to look at the wider picture.

It had no description (just the default text of "Check out this Featured App of the Day!") and a single rating.

That's right the app that the store thinks I should know about today, because it's good, relevant to me or in some other way useful has only ever had a single review. That's not encouraging, because we konw that ratings are a two part feedback mechanism. The number of ratings is an indicator of the number of people who have also used that app - there are very, very few apps with large numbers of users and very few ratings. The average (mean) value of the the ratings (subject to skewing from a small sample size) gives an indication of the quality of the app.

So, from that we can infer that the "best" app in the store today has a small user base. But maybe that's because it's new. Nope. It's had 5 updates and the last of which was 8 months ago.

Maybe the featured app is being targetted directly at me based on some heuristics or algorithm based on my other app and device usage? I doubt it and I hope not because if that's the case the algorithms are way off.

And what of that review:


I've anonymized it because the app in question doesn't count and the review included three potentially offensive words which weren't filtered or masked by the store.

I find the ratings count potentially confusing. It says there was one 4 star rating but we can only see one review. There's lots of potential here for confusion. Can't the store count? And if not what confidence should I put in it?
Actually zero star ratings aren't included in the average. If they were there would be 2 ratings with an average of 2 stars. This would bring average ratings down and so, while potentially misleading, ignoring them improves the overall perceived quality of apps. - I'm not sure what I think about this.
This is a consequence of there not being a way to actually give a no star review because the interface for leaving reviews and ratings doesn't have a way to distinguish between a rating not being left and a rating of zero. Ignoring no star ratings may be preferable to including the scores from reviwers who forget to give a rating though. I don't have the figures to say if this is an issue. I bet the people who are genuinely wanting to leave no star reviews (like the one above) are disappointed their rating is ignored though. Do people realise that zero star ratings are ignored and if you want to rate an app badly you must give it a 1 star review?
Anyway, I think I'm getting off topic.

If the store doesn't look great (i.e. doesn't appear to be able to count) then won't your opinion of the apps it sells be tainted? When you buy something from a physical store does that affect your opinion of the products you can buy in that store?

And what about the store as an app. The quality of it, like any app, impacts the perception of the platform. It's easier to say "that phone's rubbish" rather than "app X on phone Y is rubbish" or "it's hard to find good apps on phone Y".


Am I against apps and their developers getting promotion?

No, I want people to create successful apps. But I'd rather they had an awesome app that was successful, offered real value, helped people and showed what was possible with an app.
The quality of apps impacts the whole ecosystem and that in turn affects all of us, both the consumers and creators of apps.

* I'm aware of some of the finer points about what is featured and the business deals and implications that impact marketplace promotion. I've just chosen to ignore them for the sake of this post. They don't impact every featured app and would just serve to complicate the above thoughts. Anyway - my blog, my rules. ;)

Monday, June 03, 2013