Friday, May 2, 2014

My future is Xamarin

I have been creating software for handheld devices for over a decade now. I’ve seen interesting things come and go and also witnessed a couple of failures. A great part of my mobile development career involved consulting and I had loads of fun working with some very smart people doing all sorts of interesting stuff. But for the past year or so I felt like I fell into a deep whole. Normally I would provide consulting services for up to 6 months then move on to something else, but my last project was not the case. It was retailer solution and was not really interesting, not at all challenging, and was mostly tedious, and to make it worse I was targeting a 10 year old platform and needed to support an even older one. I first went along with this because the company was going through a hard time and could really use some revenue, at that time we had just let go of 1/3 of our staff and I felt lucky that I got to keep my job. I did my job the best I could even and delivered what needed to be shipped. As the project progressed and the requirement changes got out of hand I found myself in an endless loop of fixing then breaking then fixing stuff. Sometimes in life you just have to suck it up and do your job since after all it pays the bills, keeps a roof over our heads, and puts food on the table. This project has taken all of my time and energy. It was the main reason I have not posted a single article for an entire year!

During this time I paid a lot of attention (more than usual) to what was going on in the mobile space and I have grown an interest in Xamarin. I’ve seen more and more people adapt Xamarin and after trying it in a few small projects I could really see why. This means a lot coming from me since I am a huge fan of native platform development. I’ve done Android projects before where I used Java + Eclipse and iOS projects where I used Objective-C + XCode. But after seeing and trying out Xamarin, thanks to my experience with Android and iOS, I found myself immediately being productive. I love the fact that I can just use the official Android or iOS documentation pages and be able to implement it directly using Xamarin.

So after months of considerations I have decided to take a break from consulting and take on a full time position for a company called 24/7 Entertainment where I will be doing Xamarin development. I have worked with the company in the past where I helped them with some Windows Phone and Store music apps. I know the team from past work experiences and I know that they are loads of fun to work with and are very passionate about what they do. They believe in their products and all share common goals. They follow modern software development practices and use the latest and the greatest development tools and hardware. This job is going be fun, challenging, and simply great! I hope to learn, contribute, and have a blast!

Sunday, May 5, 2013

Integrating with the Windows Phone 8 Lock Screen

A nice new feature in Windows Phone 8 is integration with the lock screen. As a developer, you can now display notification icons the same way the Outlook app displays New Mail notifications. You can also change the background image of the lock screen from your app. The information used for displaying notification is the exact same information that an app uses to display notifications on the app’s primary tile regardless if the app is pinned to the start screen or not

Notification Icon

To display an icon on the lock screen you must follow a small set of strict rules on how your image file should be. The image has to be a 38 x 38 PNG image that contains only white pixels and some levels of transparency. Yes, I know it’s a bit strict but it makes sense as the icon notifications are designed to be very discreet.

App Manifest

You need to define a few extensions to let the operating system allow your app to integrate with the lock screen. So here’s what we need to do, open the WMAppManifest.xml file using an XML editor, to do this right click on the WMAppManifest.xml file and select Open With, and use the XML (Text) Editor. First, we need to define the <DeviceLockImageURI> element in the primary token. The DeviceLockImageURI describes which image file to display in the lock screen as an icon. To define DeviceLockImageURI, insert the following element in the <PrimaryToken>
<DeviceLockImageURI IsRelative="true"
                    IsResource="false">Assets\YourLockImage.png</DeviceLockImageURI>
Then, insert the following lines after the between the <Tokens> and <ScreenResolutions> definitions
<Extensions>
  <Extension ExtensionName="LockScreen_Notification_IconCount"
             ConsumerID="{111DFF24-AA15-4A96-8006-2BFF8122084F}"
             TaskID="_default" />
  <Extension ExtensionName="LockScreen_Notification_TextField"
             ConsumerID="{111DFF24-AA15-4A96-8006-2BFF8122084F}"
             TaskID="_default" />
  <Extension ExtensionName="LockScreen_Background"
             ConsumerID="{111DFF24-AA15-4A96-8006-2BFF8122084F}"
             TaskID="_default" />
</Extensions>

Lock screen settings

Before our app can display notifications we need to configure our Lock Screen settings to allow the type of notification that we are interested in displaying. Currently an app can display 3 types of notifications: background image; detailed status; and quick status. Detailed status is similar to the textual calendar notifications that are displayed using the Outlook Calendar app. Quick status is similar to the way the Outlook Mail app displays notifications, an icon and a count indicator.

To configure the device to display notifications from your app, go to the settings app and select Lock screen

settings

In the lock screen settings, choose the notification type that will display notifications from our app

image

For this example we’ll show a quick status notification

quick status on

Code

To update the background image of the lock screen we need use the LockScreen class of the UserProfile API. First we check if the user configured the app to be able to set the background of the lock screen, we can do this through LockScreenManager class. If the app isn’t allowed to change the lock screen background then we can open the lock screen settings page.

Lock screen background (C#)

if (await LockScreenManager.RequestAccessAsync() == LockScreenRequestResult.Granted)
{
    var uri = new Uri("ms-appx:///Assets/LockScreenImage.png", UriKind.Absolute);
    LockScreen.SetImageUri(uri);
}
else
{
    // Open the Settings -> Lock Screen settings
    await Launcher.LaunchUriAsync(new Uri("ms-settings-lock:"));
}


To display an icon notification just update the primary application tile with a notification. We can do this by using the ShellTile API

Display notification (C#)

var tile = ShellTile.ActiveTiles.First();
var data = new FlipTileData
                {
                    Count = 1,
                    Title = "Lock Screen Demo"
                };
tile.Update(data);


To clear the notification just update the primary application tile to its original state

Clear notification (C#)

var tile = ShellTile.ActiveTiles.First();
var data = new FlipTileData
                {
                    Count = 0,
                    Title = "Lock Screen Demo"
                };
tile.Update(data);


Pretty simple isn’t it?

Testing on the Emulator

To test on the Windows Phone emulator you can use the Simulation Dashboard which integrates directly into Visual Studio. To launch this, go to Tools –> Simulation Dashboard. You can use this tool to Lock and Unlock the emulator to test your apps lock screen integration

image

I hope you found this interesting. You can grab the source code here

Monday, April 15, 2013

Using the Windows Phone Custom Contact Store

In previous versions of Windows Phone, you could always query the contact store to retrieve contact or calendar items. During that time I always wondered why I couldn’t just create my own contacts that can be shared with other applications and accessed through the People Hub. I guess more people had this problem and in Windows Phone 8 this has been addressed. Windows Phone 8 introduced the custom contact store in which apps can create contacts that are accessible from the People Hub and from other apps. Items in the custom contact store may only be modified by app that created them

How to create contacts in Windows Phone 8

In this section I would like to demonstrate how to use the custom contact store API. In order to do so we’ll create a UI that accepts the display name, email address, and mobile phone number. To make it a bit more fancy, we’ll add a feature that accepts a photo which can be loaded either from the camera or the media library

So here’s the code…

XAML
<phone:PhoneApplicationPage x:Class="CustomContactStore.MainPage"
                           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                           xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
                           xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
                           xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                           mc:Ignorable="d"
                           FontFamily="{StaticResource PhoneFontFamilyNormal}"
                           FontSize="{StaticResource PhoneFontSizeNormal}"
                           Foreground="{StaticResource PhoneForegroundBrush}"
                           SupportedOrientations="Portrait"
                           Orientation="Portrait"
                           shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock Text="CUSTOM CONTACT STORE" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0" />
            <TextBlock Text="Sample" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" />
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <TextBlock Text="Display Name" VerticalAlignment="Center" />
                    <TextBox Grid.Column="1" Name="displayName" />
                    <TextBlock Grid.Row="1" Text="Email" VerticalAlignment="Center" />
                    <TextBox Grid.Row="1" Grid.Column="1" Name="email" />
                    <TextBlock Grid.Row="2" VerticalAlignment="Center" Text="Mobile" />
                    <TextBox Grid.Row="2" Grid.Column="1" Name="mobile" />
                </Grid>
                <Button Content="Attach New Photo" Click="AttachNewPhotoClicked" />
                <Button Content="Attach Existing Photo" Click="AttachExistingPhotoClicked" />
                <Button Content="Save Contact" Click="AddClicked" />
            </StackPanel>
        </Grid>
    </Grid>

</phone:PhoneApplicationPage>

Code Behind (C#)
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Phone.Tasks;
using Windows.Phone.PersonalInformation;

namespace CustomContactStore
{
    public partial class MainPage
    {
        private Stream photo;

        public MainPage()
        {
            InitializeComponent();
        }

        private async void AddClicked(object sender, RoutedEventArgs e)
        {
            var store = await ContactStore.CreateOrOpenAsync();
            var contact = new StoredContact(store)
                              {
                                  DisplayName = displayName.Text
                              };

            var props = await contact.GetPropertiesAsync();
            props.Add(KnownContactProperties.Email, email.Text);
            props.Add(KnownContactProperties.MobileTelephone, mobile.Text);

            if (photo != null)
                await contact.SetDisplayPictureAsync(photo.AsInputStream());

            await contact.SaveAsync();

            if (photo != null)
                photo.Dispose();
        }

        private void AttachNewPhotoClicked(object sender, RoutedEventArgs e)
        {
            var task = new CameraCaptureTask();
            task.Completed += OnTaskOnCompleted;
            task.Show();
        }

        private void OnTaskOnCompleted(object o, PhotoResult result)
        {
            photo = result.ChosenPhoto;
        }

        private void AttachExistingPhotoClicked(object sender, RoutedEventArgs e)
        {
            var task = new PhotoChooserTask();
            task.Completed += OnTaskOnCompleted;
            task.Show();
        }
    }
}

To create a custom contact we need to use the ContactStore API, we create an instance of this using the helper method CreateOrOpenAsync(). Now that we have an instance of the contact store, we create an instance of a StoredContact and set the DisplayName property to the value of the display name entered in the UI. The StoredContact object is very limited but we can add KnownContactProperties such as Email and MobileTelephone. This is done by using the GetPropertiesAsync() method of the StoredContact instance. The photos can be attached using the CameraCaptureTask or the PhotoChooserTask. We attach the photos by calling the SetDisplayPictureAsync() method of the StoredContact instance. The API’s for the custom contact store are pretty straight forward and easy to use.

Manifest

The custom contact store requires the ID_CAP_CONTACTS capability, we should enable that in the WMAppManifest.xml file. In order to that, in the Visual Studio Solution Explorer, expand the project properties folder and double click the WMAppManifest.xml file. This will open the new UI editor for the manifest file. Go to the Capabilities tab and enable the ID_CAP_CONTACTS

id_cap_contacts

Once the manifest file has been updated the app should be able to launch.

The user interface looks like this:

Custom Contact Store

Once the contact is created it will be available in the People Hub

People Hub

When the contact is viewed from the People Hub the owner of the contact will be displayed on top

Custom Contact

I hope you found this useful. You can check out the source code using the link below

Friday, January 18, 2013

The missing ResWFileCodeGenerator custom tool for Visual Studio 2012

I've been doing quite a lot of Windows Store Apps on Windows 8 lately. Ever since I started I always seemed to miss the ResXFileCodeGenerator custom tool. This is because in WinRT when you want to load a localized string in code then you will have to do something like this:

var resources = new ResourceLoader();
var localizedString = resources.GetString("SomeResourceName");

This of course can easily lead to a lot of errors. In my case I got a little to eager while refactoring and forgot to notice that I was also changing hard coded strings. This broke the code quite a lot. Because of this frustration I decided to implement my own custom tool since Microsoft didn't provide one

The project is open source and is available at CodePlex. Here's a preview of the description which I took directly from my CodePlex project site.

Project Description
A Visual Studio 2012 Custom Tool for generating a strongly typed helper class for accessing localized resources from a .ResW file.

Features
- C# code generator
- VB.NET code generator


Visual Studio 2012 Custom Tool (C#)


Visual Studio 2012 Custom Tool (VB)


Resource File Contents


C# Usage
private string test1, test2, test3;

private void LoadLocalizedStrings()
{
    test1 = App1.LocalizedResources.Resources.Test1;
    test2 = App1.LocalizedResources.Resources.Test2;
    test3 = App1.LocalizedResources.Resources.Test3;
}

Visual Basic Usage
Dim test1, test2, test3

Private Sub LoadLocalizedStrings()
    test1 = AppVb.LocalizedStrings.Resources.Test1
    test2 = AppVb.LocalizedStrings.Resources.Test2
    test3 = AppVb.LocalizedStrings.Resources.Test3
End Sub

Generated C# Code
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18010
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------------------
// <auto-generatedInfo>
//  This code was generated by ResW File Code Generator (http://reswcodegen.codeplex.com)
//  ResW File Code Generator was written by Christian Resma Helle
//  and is under GNU General Public License version 2 (GPLv2)
// 
//  This code contains a helper class exposing property representations
//  of the string resources defined in the specified .ResW file
// 
//  Generated: 11/08/2012 22:41:22
// </auto-generatedInfo>
// --------------------------------------------------------------------------------------------------
namespace App1.LocalizedResources
{
    using Windows.ApplicationModel.Resources;
    
    
    public partial class Resources
    {
        
        private static ResourceLoader resourceLoader = new ResourceLoader();
        
        /// <summary>
        /// Localized resource similar to "Test 1 value"
        /// </summary>
        public static string Test1
        {
            get
            {
                return resourceLoader.GetString("Test1");
            }
        }
        
        /// <summary>
        /// Localized resource similar to "Test 2 value"
        /// </summary>
        public static string Test2
        {
            get
            {
                return resourceLoader.GetString("Test2");
            }
        }
        
        /// <summary>
        /// Localized resource similar to "Test 3 value"
        /// </summary>
        public static string Test3
        {
            get
            {
                return resourceLoader.GetString("Test3");
            }
        }
    }
}

Generated Visual Basic Code
'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated by a tool.
'     Runtime Version:4.0.30319.18010
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On

Imports Windows.ApplicationModel.Resources

'--------------------------------------------------------------------------------------------------
'<auto-generatedInfo>
' This code was generated by ResW File Code Generator (http://reswcodegen.codeplex.com)
' ResW File Code Generator was written by Christian Resma Helle
' and is under GNU General Public License version 2 (GPLv2)
'
' This code contains a helper class exposing property representations
' of the string resources defined in the specified .ResW file
'
' Generated: 11/12/2012 21:30:52
'</auto-generatedInfo>
'--------------------------------------------------------------------------------------------------
Namespace AppVb.LocalizedStrings
    
    Partial Public Class Resources
        
        Private Shared resourceLoader As ResourceLoader = New ResourceLoader()
        
        '''<summary>
        '''Localized resource similar to "Test 1 value"
        '''</summary>
        Public Shared ReadOnly Property Test1() As String
            Get
                Return resourceLoader.GetString("Test1")
            End Get
        End Property
        
        '''<summary>
        '''Localized resource similar to "Test 2 value"
        '''</summary>
        Public Shared ReadOnly Property Test2() As String
            Get
                Return resourceLoader.GetString("Test2")
            End Get
        End Property
        
        '''<summary>
        '''Localized resource similar to "Test 3 value"
        '''</summary>
        Public Shared ReadOnly Property Test3() As String
            Get
                Return resourceLoader.GetString("Test3")
            End Get
        End Property
    End Class
End Namespace

Thursday, January 17, 2013

Parenthood

Once again I have taken a break from blogging. Parenting and my new family has been my absolute top priority and I've been having a hard time finding the time to write articles. I really enjoy spending time with my son and wife and I take advantage of every possible moment to do so.

I ended up at a schedule that starts around 5:30 AM in which my son wakes up, and wakes me up. I go and start preparing some breakfast for him. We then have a cozy morning playing around the house. I drop him off at day care as late possible (in my case 9:00 AM) and then drive to the office, or to a customer, or back home if I'm working from home. I pick my son up at between 3:00-4:00 PM and spend time with him and my wife until around 6:30 PM (this is his bed time and I'm very lucky that he has no trouble sleeping). From around 6:30 to 8:00-9:00 PM I spend some time with my wife discussing how our days went and do some planning for the following days. My wife goes to bed a bit early, and when that happens I go back to work. Since I drastically shortened by day, I need to do quite a bit of catching up at night. I usually work an extra 2-3 hours more at night, then I have an hour or 2 to give my mind a rest or work on a hobby project. My day usually ends between 12:30 AM and 2:00 AM. I need at least 4 hours of sleep to recharge for the next day, otherwise I won't be able to last a full week on my schedule.

Hence the break from blogging :)