Showing posts with label Windows8. Show all posts
Showing posts with label Windows8. Show all posts

Friday, 17 January 2014

Learning Windows Azure Mobile Services for Windows 8 and Windows Phone 8

I've spent the last few months writing a book for Packt Publishing titled Learning Windows Azure Mobile Services for Windows 8 and Windows Phone 8. The book has been published today and is available as an eBook or paper-back.

The book covers the following with examples and full solutions for Windows 8 and Windows Phone 8:

Chapter 1: Preparing the Windows Azure Mobile Services Portal

  • Choosing a subscription
  • Pay-as-you-go subscription
  • Basic and Standard subscriptions
  • Free trial
  • Creating a Windows Azure account
  • Creating a mobile service
  • Mobile Services features
  • Managing keys
  • Mobile service dashboard
  • Configure
  • Scale
  • Logs
  • Summary

Chapter 2: Start Developing with Windows Azure Mobile Services

  • Preparing our development environment
  • Hardware requirements
  • Setting up the software
  • Requirement for store accounts
  • Creating apps from the portal
  • Connecting existing apps to Windows Azure Mobile Services
  • Adding a Connected Service in Visual Studio 2013
  • Manually installing the SDK in Visual Studio 2012 Express for Windows Phone
  • Creating a table
  • Writing a model of the table
  • Interacting with the table
  • Summary

Chapter 3: Securing Data and Protecting the User

  • Configuring permissions
  • Rules for choosing permissions
  • Authentication providers
  • Authentication
  • Registering for Windows Live Connect Single Sign-on
  • Authentication in the app
  • Logging in
  • Storing credentials
  • Logging out
  • The DataServiceBase class
  • REST API and the master key
  • Summary

Chapter 4: Service Customization with Scripts

  • Understanding table scripts
  • Level-insert table script example
  • Score-insert script example
  • Score-read script example
  • API scripts
  • Creating an API script
  • High-score API script
  • Script debugging and logs
  • Scheduling
  • Working locally with Git
  • Pulling the repository
  • Updating our repository
  • Adding scripts manually
  • Pushing back changes
  • Implementing NPM modules
  • Summary

Chapter 5: Implementing Push Notifications

  • Understanding Push Notification Service flow
  • Setting up Windows Store apps
  • Setting up tiles
  • Setting up badges
  • Setting up Windows Phone 8 apps
  • Service scripts
  • WNS scripts for Store apps
  • Sending toast notifications
  • Sending tile notifications
  • Sending multiple tiles
  • Sending badge notifications
  • MPNS scripts for Windows Phone apps
  • Sending toast notifications
  • Sending tile notifications
  • Summary

Chapter 6: Scaling Up with the Notifications Hub

  • Configuring the Hub
  • Setting up Windows Store and Windows Phone 8 apps
  • Calling the hub from scripts
  • Creating WNS scripts (for Store apps)
  • Sending toast notifications
  • Sending tile notifications
  • Sending badge notifications
  • Creating MPNS scripts (for Windows Phone 8 apps)
  • Sending toast notifications
  • Sending tile notifications
  • Backend services
  • Targeting audience using tags
  • Summary

Chapter 7: Best Practices for Web-connected Apps

  • App certification requirements for the Windows Store
  • UX guidelines
  • Implementing a privacy policy
  • Checking the network connection
  • Managing notifications settings
  • Implementing settings pages
  • Summary

The content is based around a case study of a simple XAML based game to help provide real-world examples and implement as much Windows Azure Mobile Services functionality as possible with a tangible context. There is a full table of content on the book's web page.

Writing this book was an enjoyable, but difficult challenge. The main challenge was covering a large subject matter within a strict and short page limit; I chose to use a case study to help me think up realistic examples, but also provide fully working Windows 8 and Windows Phone 8 solutions to enhance the book.

There is a sample chapter available to download here (I'm fairly sure this should have been the 3rd chapter on security, but it looks to be the first one) and an article on Push Notifications here.

Anyway, if it looks of interest, please get yourself a copy!

Thursday, 28 November 2013

Creating Azure Notifications Hub Push Notifications using Node Script

Windows Azure Mobile Services has great built-in support for making Push Notifications; however there’s a better more scalable option using the Notifications Hub which is part of the Service Bus group of services.
We can call the hub from external backend services using the Windows Azure Service Bus SDK (NuGet PM> Install-Package WindowsAzure.ServiceBus) and this is fairly well documented; however if you want to do a direct replacement for the build-in Push Notifications using Notifications Hub, it’s not so well documented. I did some digging in the source to work out how to use it: https://github.com/WindowsAzure/azure-sdk-for-node
In our Mobile Services scripts we can make use of NPM packages which we install ourselves and pre-installed packages like the Windows Azure SDK for Node which we will use for calling the Hub.

Accessing the Notifications Hub

We need two things to allow us to connect to the hub and those are the DefaultFullSharedAccessSignature which you can get from the Notifications Hub Dashboard and the Hub name. We can declare these as variables like this:

var CONNECTION_STRING = "Endpoint=sb://myapp.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=XXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=";
var HUB_NAME = "MyHubName";

Now to interact with the Notifications hub, we get a reference to the Azure package like this:

var azure = require("azure");

Then create a NotificationHubService like this:

var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);

All the native PNS send methods have prototypes similar to this:

MpnsService.prototype.send = function (tags, payload, targetName, notificationClass, optionsOrCallback, callback)

The Notifications class is the batching interval (how quick it’s sent).

Windows Phone MPNS Notofications

Following are examples of sending toast and tiles to Windows Phone apps using the MPNS provider:   

function sendToastHubMpns(text1, text2, tagExpression)
{
    var azure = require("azure");
    var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
   
    var toast = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
    "<wp:Notification xmlns:wp=\"WPNotification\">" +
        "<wp:Toast>" +
            "<wp:Text1>" + text1 + "</wp:Text1>" +
            "<wp:Text2>" + text2 + "</wp:Text2>" +
        "</wp:Toast> " +
    "</wp:Notification>";
   
    notificationHubService.mpns.send(tagExpression, toast, "toast", 2, function(error) {
    if (error) {
        console.error(error);
    }});
}

function sendTileHubMpns(backTitle, backContent, tagExpression)
{
  var azure = require("azure");
  var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
   
  var tile = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
      "<wp:Notification xmlns:wp=\"WPNotification\" Version=\"2.0\">" +
         "<wp:Tile Template=\"FlipTile\">" +
              "<wp:BackTitle>" + backTitle + "</wp:BackTitle>" +
              "<wp:BackContent>" + backContent + "</wp:BackContent>" +
              "<wp:WideBackContent>" + backContent + "</wp:WideBackContent>" +
         "</wp:Tile> " +
      "</wp:Notification>";
 
    notificationHubService.mpns.send(tagExpression, tile, "token", 1, function(error) {
    if (error) {
        console.error(error);
    }});
}

Windows 8 WNS Notifications

Following are examples of sending toast, tile and badge notifications to Windows 8 apps using the WNS provider:   

function sendToastHubWns(text1, text2, text3, tagExpression)
{
  var azure = require("azure");
  var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
 
  var toast = "<toast>" +
    "<visual>" +
      "<binding template=\"ToastText04\">" +
        "<text id=\"1\">" + text1 + "</text>" +
        "<text id=\"2\">" + text2 + "</text>" +
        "<text id=\"3\">" + text3 + "</text>" +
        "</binding>" +
      "</visual>" +
    "</toast>";

    notificationHubService.wns.send(tagExpression, toast, "wns/toast", 2, function(error) {
    if (error) {
        console.error(error);
    }});
}

function sendTileHubWns(text1, text2, text3, tagExpression)
{
    var azure = require("azure");
    var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
   
    var tile = "<tile>" +
    "<visual>" +
      "<binding template=\"TileSquareText01\">" +
        "<text id=\"1\">" + text1 + "</text>" +
        "<text id=\"2\">" + text2 + "</text>" +
        "<text id=\"3\">" + text3 + "</text>" +
      "</binding>" +
    "</visual>" +
    "</tile>";
 
    notificationHubService.wns.send(tagExpression, tile, "wns/tile", 2, function(error) {
    if (error) {
        console.error(error);
    }});
}

function sendBadgeHubWns(value, tagExpression)
{
    var azure = require("azure");
    var notificationHubService = azure.createNotificationHubService(HUB_NAME, CONNECTION_STRING);
   
    var badge = "<badge value=\"" + value + "\" />";
 
    notificationHubService.wns.send(tagExpression, badge, "wns/badge", 2, function(error) {
    if (error) {
        console.error(error);
    }});
}

These functions can be called like this:

function sendAllHubNotifications(message)
{
  sendToastHubMpns("My Application", message, null);
  sendTileHubMpns("My Application ", message, null);

  sendToastHubWns("My Application ", "Here’s a notification", message, null);
  sendTileHubWns("My Application ", " Here’s a notification ", message, null;
  sendBadgeHubWns("alert",  null);
}

Notice there is a tagExpression variable which we have set to null. We can use this to target notifications at user’s interests which are registered in the app:

function sendAllHubNotifications(message)
{
  sendToastHubWns("My Application ", "Here’s a notification", message, "NEWS");
  sendTileHubWns("My Application ", " Here’s a notification ", message, "NEWS");
  sendBadgeHubWns("alert", "NEWS");
}

I managed to get Windows 8 to work with this but not Windows Phone 8

Registering with the Hub from a Windows 8 App

This example shows how to register a Windows 8 Store App with the DefaultListenSharedAccessSignature connection string this time (from the Notifocations Hub Dashboard). This registers two tags, but you can use null to receive everything:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices;
using Newtonsoft.Json.Linq;
using Microsoft.WindowsAzure.Messaging;

namespace MyApp
{
    internal class MyAppPush
    {
        private const string HUB_NAME = "myapp";
        private const string CONNECTION_STRING = "Endpoint=sb://myapp.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=/XXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=";

        public async static void UploadChannel()
        {
            var channel = await Windows.Networking.PushNotifications.PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

            var token = Windows.System.Profile.HardwareIdentification.GetPackageSpecificToken(null);
            string installationId = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(token.Id);

            try
            {
                // Register with hub
                var hub = new NotificationHub(HUB_NAME, CONNECTION_STRING);
                var result = await hub.RegisterNativeAsync(channel.Uri, new string[] { "NEWS", "SUPPORT" });
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        }
    }
}


Windows Phone 8 apps are registered in the same way, but they have a slightly different mechanism as they have an event when the URI changes which needs to be used for registration.

Friday, 18 October 2013

Launching an Email Client from Windows 8 Store Apps – Language Comparison

Unlike in Windows Phone apps, there is not a dedicated task for composing email, instead, a general purpose launcher is used for launching URIs. To launch an email client, a mailto: type URI can be used. The launching itself is pretty much identical in C#, VB.Net, C++ and JavaScript; however the text needs escaping to cope with spaces, carriage returns etc and this is where the languages differ:

C#
In .Net for C# and VB.Net, the Uri class has a static method ‘EscapeUriString’ which takes care of escaping URI strings:

var email = string.Format(“mailto:{0}?subject={1}&body={2}”,
            “email@somedomain.com",
            "A Subject",
            “The email body”);

var cleaned = Uri.EscapeUriString(email);

// Email task
await Launcher.LaunchUriAsync(new Uri(cleaned, UriKind.Absolute));

VB.Net

Dim email = String.Format(SUPPORT_MAIL,
            “email@somedomain.com",
            "A Subject",
            “The email body”)

Dim cleaned = Uri.EscapeUriString(email)

            ' Email task
Await Launcher.LaunchUriAsync(New Uri(cleaned, UriKind.Absolute))

JavaScript
WinRT JavaScript Uri object doesn’t have the ‘EscapeUriString’ method, however it supports the standard JavaScript encodeURI method which does the same thing:

var email = "mailto:";
            email += "email@somedomain.com";
            email += "?subject=";
            email += "A Subject";
            email += "&body=";
            email += "The email body";

var cleaned = encodeURI(email);

// Email task
var uri = new Windows.Foundation.Uri(cleaned);
return Windows.System.Launcher.launchUriAsync(uri);

C++
WinRT JavaScript Uri object doesn’t have the ‘EscapeUriString’ method either and doesn’t have anything build in, so we need to write one ourselves.

String^ email = L"mailto:";
       email += "email@somedomain.com";
       email += L"?subject=";
       email += "A Subject";
       email += L"&body=";
       email += "The email body";

auto cleaned = encodeURI(email);

auto uri = ref new Uri(cleaned);
Launcher::LaunchUriAsync(uri);

I found the main bit of this enclode function on Stack Overflow (can’t find where now) and modified it to work with WinRT:

String^ encodeURI(String^ c)
{
    const std::string unreserved = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~!*()\\,/?:@=+$&";

    std::wstring  escaped=L"";
    for(size_t i=0; i<c->Length(); i++)
    {
       auto data = c->Data();

       if (unreserved.find_first_of(data[i]) != std::string::npos)
       {
           escaped.push_back(data[i]);
       }
       else
       {
           escaped.append(L"%");
           char buf[3];
           sprintf_s(buf, "%.2X", data[i]);

           auto s = std::string(buf);
           auto w = std::wstring(s.begin(), s.end());

           escaped.append(w);
       }
    }

    return ref new Platform::String(escaped.c_str());

}

Wednesday, 10 July 2013

Windows 8 MVVM Drag Drop

Overview

I’ve recently added drag/drop functionality to a Windows 8 app between a GridView and a ListBox using an MVVM pattern. I created two Attached Properties to collect the dragged items and fire a command when they were dropped. Both work on ListViewBase controls.

DragItemStarting Attached Property


This detects the DragItemsStarting event on the source control and pushes the items into a bound IList<T> in the view model:

public class DragItemsStarting
{
    public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.RegisterAttached("Items", typeof(IList<object>), typeof(DragItemsStarting), new PropertyMetadata(null, ItemsPropertyChanged));

    public static void SetItems(DependencyObject attached, IList<object> value)
    {
        attached.SetValue(ItemsProperty, value);
    }

    public static IList<object> GetItems(DependencyObject attached)
    {
        return (IList<object>)attached.GetValue(ItemsProperty);
    }

    private static void ItemsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Attach click handler
        (d as ListViewBase).DragItemsStarting += DragItemstarting_DragItemsStarting;
    }
             
    static void DragItemstarting_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        // Set Items
        SetItems(sender as DependencyObject, e.Items);
    }
}

DragItem Binding XAML


<GridView
    x:Name="pallette"
    cmd:DragItemsStarting.Items="{Binding DragObjects, Mode=TwoWay}"

DragItem Binding View Model

public IList<object> DragObjects
{
    get { return this._dragObjects; }
    set { this._dragObjects= value; }
}

Be careful to implement the getter and not return null as the attached property won’t attach if the value doesn’t change.

DropCommand Attached Property

This detects the drop event and fires the bound command. In my implementation, I wanted the pointer location so I passed that into the command:

public class DropCommand
{
    public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(DropCommand), new PropertyMetadata(null, CommandPropertyChanged));

    public static void SetCommand(DependencyObject attached, ICommand value)
    {
        attached.SetValue(CommandProperty, value);
    }

    public static ICommand GetCommand(DependencyObject attached)
    {
        return (ICommand)attached.GetValue(CommandProperty);
    }

    private static void CommandPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Attach click handler
        (d as FrameworkElement).Drop += DropCommand_Drop;
    }

    private static void DropCommand_Drop(object sender, DragEventArgs e)
    {
        e.Handled = true;

        // Get element
        var fe = (sender as FrameworkElement);

        // Get command
        ICommand command = GetCommand(fe);

        // Get pointer point
        var p = Window.Current.CoreWindow.PointerPosition;

        Debug.WriteLine(string.Format("DROP X: {0}, Y: {1}", p.X, p.Y));

        // Execute command
        command.Execute(p);
    }
}

DropCommand Binding XAML


<ListBox cmd:DropCommand.Command="{Binding DropCommand}"

DropCommand Binding View Model


public ICommand DropCommand
{
    get { return this._dropCommand; }
}

I usually have a method called by the constructor that created the commands:

this._dropCommand = new DelegateCommand(a =>
    {
        if (a is Windows.Foundation.Point)
        {
            this.DoSomething((Windows.Foundation.Point)a);
        }
       
    }, p => this.IsDropExecutable);

You can use any type of command; I've used Delegate command taken from the Prism framework. 

Conclusion

This provides a nice clean way of implementing drag and drop using an MVVM pattern.