Wednesday, 1 April 2015

Exceptions

When it comes to exception handling, the standard practices apply,
  • In methods and functions throw exceptions, don't try and return -1's or nulls or empty strings, something went wrong let your system know through an exception.
  • Don't bury exceptions, when an exception occurs it contains a lot of good information so when you catch one re throw it using just throw; otherwise you'll strip the stack trace and it'll be harder to figure out where's the source of your error.
  • clean up your data, if an exception occurs clean the mess up.
Now lets take a look at a quick example.

and the xaml

<Page
    x:Class="pc.exceptions.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.exceptions"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="1" Text="Exception Example"
                   Style="{ThemeResource HeaderTextBlockStyle}"
                   VerticalAlignment="Center"/>
        <StackPanel Grid.Column="1" Grid.Row="1">
            <TextBox x:Name="Denominator_TXT" Text="0" Width="100"
                     HorizontalAlignment="Left"/>
            <Button x:Name="DivideByZero_BTN" Content="1/0 Exception" />
        </StackPanel>
    </Grid>
</Page>

and lets look at the code behind

using System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace pc.exceptions
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.DivideByZero_BTN.Click += DivideByZero_BTN_Click;
        }

        //thrid exception thrown
        void DivideByZero_BTN_Click(object sender, RoutedEventArgs e)
        {
            var d = Convert.ToInt32(Denominator_TXT.Text);

            try
            {
                var x = CalculateTwo(CalculateOne, 9, d);
            }
            catch (Exception ex)
            {
                //this is bad, don't do this
                throw ex;
            }
        }

        //second function to throw exception
        double CalculateTwo(Func<int, int, double> CalculationFunc, int A, int B)
        {
            try
            {
                return CalculationFunc.Invoke(A, B);
            }
            catch (DivideByZeroException ex)
            {
                throw;
            }
        }

        //First Function to throw Exception
        double CalculateOne(int a, int b)
        {
            try
            {
                return a / b;
            }
            catch (DivideByZeroException ex)
            {
                throw;
            }
        }
    }
}

What we have is pretty straight forward, basically we create a divide by zero exception on purpose to trace the errors now when we run our app and cause our exception. lets inspect our exception stack trace at each level

CalculateOne

   at pc.exceptions.MainPage.CalculateOne(Int32 a, Int32 b)

We see the original source of our exception

CalculateTwo

   at pc.exceptions.MainPage.CalculateOne(Int32 a, Int32 b)
   at pc.exceptions.MainPage.CalculateTwo(Func`3 CalculationFunc, Int32 A, Int32 B)

Now we can trace the original source of our exception

DivideByZero_BTN_Click

  at pc.exceptions.MainPage.DivideByZero_BTN_Click(Object sender, RoutedEventArgs e)

we've lost our stack trace history, so by inspecting it at or after this level we can't really tell where the error originated from. however if we change

//thrid exception thrown
void DivideByZero_BTN_Click(object sender, RoutedEventArgs e)
{
    var d = Convert.ToInt32(Denominator_TXT.Text);

    try
    {
        var x = CalculateTwo(CalculateOne, 9, d);
    }
    catch (Exception ex)
    {
        //this is bad, don't do this
        throw ex;
    }

}

to

//thrid exception thrown
void DivideByZero_BTN_Click(object sender, RoutedEventArgs e)
{
    var d = Convert.ToInt32(Denominator_TXT.Text);

    try
    {
        var x = CalculateTwo(CalculateOne, 9, d);
    }
    catch (Exception ex)
    {
        //Much better
        throw;
    }

}

then inspect the stack trace of the exception once it's thrown we see

   at pc.exceptions.MainPage.CalculateOne(Int32 a, Int32 b)
   at pc.exceptions.MainPage.CalculateTwo(Func`3 CalculationFunc, Int32 A, Int32 B)
   at pc.exceptions.MainPage.DivideByZero_BTN_Click(Object sender, RoutedEventArgs e)

much better, this again allows us to trace our tack to see where the error actually originated from.

now you may have noticed that once our application runs out of opportunities to handle our exception our application catches it for the final time in debugger via the unhandled excption event



#pragma checksum "c:\users\administrator\documents\visual studio 2013\Projects\pc.exceptions\pc.exceptions\App.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "3D2BE5729E141535E26842E969B8DF4A"
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------


namespace pc.exceptions
{
#if !DISABLE_XAML_GENERATED_MAIN
    public static class Program
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        static void Main(string[] args)
        {
            global::Windows.UI.Xaml.Application.Start((p) => new App());
        }
    }
#endif

    partial class App : global::Windows.UI.Xaml.Application
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
        private bool _contentLoaded;

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent()
        {
            if (_contentLoaded)
                return;

            _contentLoaded = true;
#if DEBUG && !DISABLE_XAML_GENERATED_BINDING_DEBUG_OUTPUT
            DebugSettings.BindingFailed += (sender, args) =>
            {
                global::System.Diagnostics.Debug.WriteLine(args.Message);
            };
#endif
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
            UnhandledException += (sender, e) =>
            {
                if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
            };
#endif
        }
    }
}

this code will cause our application to break and since the exception is unhanded it will then crash, if you would like to prevent that in you app.xaml.cs you can handle the event.

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;
    this.UnhandledException += App_UnhandledException;
}

private void App_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    //handle excption
    e.Handled = true;
}


now this will keep your application form terminating... some of the times... this isn't exactly recommended actually it's discouraged, however this would be an excellent place to save data to storage or log exceptions, maybe post the exception to a web-service so that you can debug it at a later date.

There are exceptions that will terminate your application regardless if they're handled and of coarse when there's an exception you can no longer guarantee the state of your application and thus the best course of action may very well be to just shut it down.

Monday, 30 March 2015

Licensing your application

Are you willing to pay for an application before you try it? probably not, so what are your try before you buy options:

Timed Trial: start with all the features in the application and after a certain amount of time will expire and stop working, or work partially, or suddenly be riddled with ads until your user breaks down and pays or deletes it.

one thing to note is that Timed trial is not compatible with in-app purchases, that means if you have a timed trail you can't have consumable or durable products inside you application.

Feature Based Trial: start with a subset of features and require your user to pay to unlock advanced features.

In-app purchase: allow your users to make consumable purchases inside your apps; for example in games you can buy things like coins or powerups

In production we would use the CurrentApp class to handle all of our licensing information and interactivity, but for testing we use CurrentAppSimulator. Our Licencing Information is stored in an xml file at the following location:

C:\Users\Administrator\AppData\Local\Packages\49a7a3ba-c5b6-495d-be63-c1b0560ce3e7_75cr2b68sm664\LocalState\Microsoft\Windows Store\ApiData\WindowsStoreProxy.xml

now I'm using my administrator account for development, so your path will be different, now let's look inside of this xml file, but before we do it may be worth to mention that the WindowsStoreProxy.xml file is created the first time your app accesses the LicenseInformation property of the CurrentAppSimulator class.

<?xml version="1.0" encoding="utf-16" ?>
<CurrentApp>
  <ListingInformation>
    <App>
      <AppId>00000000-0000-0000-0000-000000000000</AppId>
      <LinkUri>http://apps.microsoft.com/webpdp/app/00000000-0000-0000-0000-000000000000</LinkUri>
      <CurrentMarket>en-US</CurrentMarket>
      <AgeRating>3</AgeRating>
      <MarketData xml:lang="en-us">
        <Name>AppName</Name>
        <Description>AppDescription</Description>
        <Price>1.00</Price>
        <CurrencySymbol>$</CurrencySymbol>
        <CurrencyCode>USD</CurrencyCode>
      </MarketData>
    </App>
    <Product ProductId="1" LicenseDuration="0" ProductType="Durable">
      <MarketData xml:lang="en-us">
        <Name>Product1Name</Name>
        <Price>1.00</Price>
        <CurrencySymbol>$</CurrencySymbol>
        <CurrencyCode>USD</CurrencyCode>
      </MarketData>
    </Product>
    <Product ProductId="2" LicenseDuration="0" ProductType="Consumable">
      <MarketData xml:lang="en-us">
        <Name>Product2Name</Name>
        <Price>1.00</Price>
        <CurrencySymbol>$</CurrencySymbol>
        <CurrencyCode>USD</CurrencyCode>
      </MarketData>
    </Product>
  </ListingInformation>
  <LicenseInformation>
    <App>
      <IsActive>true</IsActive>
      <IsTrial>true</IsTrial>
      <ExpirationDate>2014-06-19T09:00:00.00Z</ExpirationDate>
    </App>
    <Product ProductId="1">
      <IsActive>true</IsActive>
    </Product>
  </LicenseInformation>
  <ConsumableInformation>
    <Product ProductId="2" TransactionId="00000000-0000-0000-0000-000000000000" Status="Active" />
  </ConsumableInformation>
</CurrentApp>

lets look at the ListingInformation Node, in here it contains three children App, and two product nodes, the thing to notice is that they have two different ProductType attributes:
  • Durable: buy once keep forever
  • Consumable: buy but use up
now let's take a look at the LicensingInfromation and ConsumableInformation Nodes, these nodes contain corresponding details about the apps and purchasable products.

App: is a the node referring to our application, here it can be in trail mode that expires and can be purchased.

  • Product with type Durable: this is a product that can be purchased indefinitely an added feature.
  • Product with type consumable: a product that can be used up. 

Timed Trial

alright, lets' get started with a Timed trial app, that's an application that you download and you can use for a number of predefined days only to stop entirely or start display adds once the trial expires or perhaps only let's you utilize a subset of Features.

Let's take a look at our UI

now the xaml

<Page
    x:Class="pc.licenseExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.licenseExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock  Grid.Column="1" Text="License Exmaple"
                    Style="{ThemeResource HeaderTextBlockStyle}"
                    VerticalAlignment="Center" />
        <StackPanel Grid.Column="1" Grid.Row="1">
            <TextBox x:Name="AppData_TXT" Header="App Data:"/>

            <TextBox x:Name="ListingInfo_TXT" Header="Listing Info:"
                     Height="200" TextWrapping="Wrap"/>

            <TextBox x:Name="LicenceInfo_TXT" Header="Licence Info:"
                     Height="100" TextWrapping="Wrap"/>

            <StackPanel Orientation="Horizontal">
                <Button x:Name="GetLicenseInfo_BTN" Content="Get Info" />
                <Button x:Name="BuyLicense_BTN" Content="Buy" />
            </StackPanel>
        </StackPanel>
    </Grid>
</Page>


let's take a look at the code behind

using System;
using System.Windows.Input;
using Windows.ApplicationModel.Store;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace pc.licenseExample
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.GetLicenseInfo_BTN.Click += GetLicenseInfo_BTN_Click;
        }

        async void GetLicenseInfo_BTN_Click(object sender, RoutedEventArgs e)
        {
            AppData_TXT.Text = Windows.Storage.ApplicationData.Current.LocalFolder.Path;

            var listingInfo = await CurrentAppSimulator.LoadListingInformationAsync();
            var listingStr = "Age Rating: {0}\r\nCurrentMarket:{1}\r\nDescription:{2}\r\nFormattedPrice:{3}\r\nName:{4}";
            ListingInfo_TXT.Text = string.Format(listingStr,
                listingInfo.AgeRating,
                listingInfo.CurrentMarket,
                listingInfo.Description,
                listingInfo.FormattedPrice,
                listingInfo.Name);
           

            var licenseInfo = CurrentAppSimulator.LicenseInformation;
            var str = "ExpirationDate: {0}\r\nIs Trial:{1}\r\nIs Active:{2}";

            LicenceInfo_TXT.Text = String.Format(str,
                licenseInfo.ExpirationDate.ToString(),
                licenseInfo.IsTrial,
                licenseInfo.IsActive);
        }
    }
}

now what we have so far will list all of our application info when we hit the "Get Info" button and by default we can see the following


the App Data Text box gives us a link to our application in our roaming folder so that we can get to our xml file faster, I've already modified mine to have an expiry date in the past, which is why our IsActive property if false and our is Trial is true, so this tells us that the trial period is expired but the user hasn't activated the application.

so now let's write the code for buying our application, to the code behind,

public MainPage()
{
    this.InitializeComponent();
    this.GetLicenseInfo_BTN.Click += GetLicenseInfo_BTN_Click;
    this.BuyLicense_BTN.Click += BuyLicense_BTN_Click;           
}

async void BuyLicense_BTN_Click(object sender, RoutedEventArgs e)
{
    try
    {      
        await CurrentAppSimulator.RequestAppPurchaseAsync(false);
    }
    catch (Exception ex)
    {
        //handle excption
    }

}

now if we hit the buy button our isActive flag will become true, but as always we have to write the logic to deal with our licence change, luckily the LicenceInformation property has an event LicenceChanged. Let's implement that.

public MainPage()
{
    this.InitializeComponent();
    this.GetLicenseInfo_BTN.Click += GetLicenseInfo_BTN_Click;
    this.BuyLicense_BTN.Click += BuyLicense_BTN_Click;
    CurrentAppSimulator.LicenseInformation.LicenseChanged += LicenseInformation_LicenseChanged;

}

void LicenseInformation_LicenseChanged()
{
    var licenseInfo = CurrentAppSimulator.LicenseInformation;
    var str = "ExpirationDate: {0}\r\nIs Trial:{1}\r\nIs Active:{2}";

    LicenceInfo_TXT.Text = String.Format(str,
        licenseInfo.ExpirationDate.ToString(),
        licenseInfo.IsTrial,
        licenseInfo.IsActive);

}

and now our licence info will update once we simulate purchasing our application.

Durable 

Keep in mind that in-app purchases do not work with a timed-trial, so for these to work you have to open your "WindowsStoreProxy.xml" ile and change the app node to

<App>
    <IsActive>true</IsActive>
    <IsTrial>false</IsTrial>
</App>

Basically remove the expiration date node and set the istrial to false.

Now let's look at purchasing a durable, first we're going to list the durable Items so add the following datatemplate to your page's resources in the xaml

<Page.Resources>
    <DataTemplate x:Name="DurableTemplate">
        <StackPanel>
            <TextBox Header="Product Id:" Text="{Binding ProductId}"/>
            <TextBox Header="IsActive:" Text="{Binding IsActive}"/>
            <TextBox Header="Expiration Date:" Text="{Binding ExpirationDate}"/>
        </StackPanel>
    </DataTemplate>

</Page.Resources>

this will later let us view the items via ListView. Next go down to your main stack panel the one that has all our text boxes and buttons and add the following xaml

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

    <ListView x:Name="Durable_LV" Header="Durable"
            ItemTemplate="{StaticResource DurableTemplate}"/>

</Grid>

We're adding a grid with a listview is because we'll ad a second list view later for consumables, now let's add the following line to the Get Licence Info method

Durable_LV.ItemsSource = licenseInfo.ProductLicenses.Values;

Now when we run our application and get the info for our durable products.

notice we also added a buy button to the durable DataTemplate, all we did was add the following

<Button Content="Buy" Command="{Binding ElementName=MainContainer, Path=BuyDurableCommand }" CommandParameter="{Binding ProductId}" />

however this does require that we give our root page element the name "MainContainer" and that we set the pages datacontext to it's codebhind, you can see that in the following

<Page
    x:Name="MainContainer"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    x:Class="pc.licenseExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:pc.licenseExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    mc:Ignorable="d">

now in the code behind we have to create an ICommand Property we can bind to, so lets add that to our class.
public sealed partial class MainPage : Page
{
    //Command to expose to UI
    public ICommand BuyDurableCommand { get; set; }

    //stuff in code behind

 }

ok, now we need to actually create a new class that implements ICommnad

public class BuyCommand : ICommand {

    Action<object> _buyCommand;

    //consturctor that takes in action to perform
    public BuyCommand(Action<object> Execute)
    {
        _buyCommand = Execute;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _buyCommand.Invoke(parameter);
    }

}

now finally we need to tie our BuyDurableCommand property to the BuyCommand class we created and we'll do that in our constructor like so.

public MainPage()
{
    this.InitializeComponent();
    this.GetLicenseInfo_BTN.Click += GetLicenseInfo_BTN_Click;
    this.BuyLicense_BTN.Click += BuyLicense_BTN_Click;
    CurrentAppSimulator.LicenseInformation.LicenseChanged += LicenseInformation_LicenseChanged;

    this.BuyDurableCommand = new BuyCommand(async id =>
    {
        try
        {
            var pr = await CurrentAppSimulator.RequestProductPurchaseAsync(id.ToString());
        }
        catch (Exception ex)
        {

        }
    });

}

now with that complete, when we run our application and purchase our durable product.