We’ll start by creating a new Mobile Service (if you don’t know how, follow this tutorial to the point where they’re creating a new app, we’ll create the app manually).
Once the mobile service is created, navigate to the API tab and add a new API. Gave it a name and leave the permissions default. The end result should look like this.
Click the arrow icon next to the API name to start editing the script. The script looks like this by default.
There are options here both for POST and GET methods, implemented with Hello World stuff. We’ll only be needing the POST part, the GET method we’ll just leave alone.
This is the new POST method:
You’ll notice on line two and three that you’ll need to insert your own client ID and client secret. To get those we’ll need to create a new app on the Windows Store developer site.
Give an app name to the new app, save it and open the Services option.
<p>On the services page, click on “Live Services Site”, on that site select “Authenticating your Service” and take note of the Client ID and Client Secret.</p> <p><a href="http://i41.tinypic.com/vgc2d.jpg" target="_blank"><img src="http://i41.tinypic.com/vgc2d.jpg" width="391" height="259" /></a><a href="http://i41.tinypic.com/vnfa6h.jpg" target="_blank"><img src="http://i41.tinypic.com/vnfa6h.jpg" width="378" height="187" /></a></p> <p>Usually, when using push notifications from a WAMS we can add those two keys into the management portal on Azure. However, when using a Custom API the WNS (Windows Notification Service) doesn’t seem to know that they are there. That’s the reason we’re including them into the script code here on lines two and three.</p> <p>Last step here is to create a new Windows Store application in Visual Studio, Right-click the project, select Store and associate it with the app we’ve just created on the Windows Developer portal.</p> <p><a href="http://i44.tinypic.com/2cymk95.jpg" target="_blank"><img src="http://i44.tinypic.com/2cymk95.jpg" /></a></p> <p>We now have an application hooked up to a registered application on the Windows Developer portal with access to WNS through the client ID and secret.</p> <p>Let’s have a look at the rest of the script.</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d491c982-b5de-4b68-aa28-7fe36881ca3a" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> wns = request.service.push.wns;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> message = request.body.message;</span></li> <li><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> title = request.body.title;</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> launchParam = request.body.launchParam;</span></li> <li><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> channel = request.body.channel;</span></li> </ol> </div> </div> </div> <p>In the build-in API of WAMS we have access to an object called push. Push has a reference to WNS and can call push notifications. In a custom API we can find the Push object in request.service. Message and Title will be the content of the toast, channel is the channel used to send the toast from the server to the client and launchParam is what will determine the page we navigate to when the toast is clicked. All these parameters will be send over the wire from the Windows Phone app.</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1953a182-20a4-42ba-876f-9a3bc14e5128" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#000000">wns.sendToastText02(channel, {</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">text1: title,</span></li> <li> <span style="background:#ffffff;color:#000000">text2: message</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">},</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">launch: launchParam,</span></li> <li> <span style="background:#ffffff;color:#000000">success: </span><span style="background:#ffffff;color:#0000ff">function</span><span style="background:#ffffff;color:#000000"> () {</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">response.send(statusCodes.OK, { isSuccess: </span><span style="background:#ffffff;color:#0000ff">true</span><span style="background:#ffffff;color:#000000">, response: statusCodes.OK });</span></li> <li> <span style="background:#ffffff;color:#000000">},</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">error: </span><span style="background:#ffffff;color:#0000ff">function</span><span style="background:#ffffff;color:#000000"> () {</span></li> <li> <span style="background:#ffffff;color:#000000">response.send(statusCodes.OK, { isSuccess: </span><span style="background:#ffffff;color:#0000ff">false</span><span style="background:#ffffff;color:#000000">, response: statusCodes.NOK });</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">);</span></li> </ol> </div> </div> </div> <p>This piece of the script will do the actual sending of the push notification. We call the sendToastText02 method on the wns object (for an overview of all the possibilities of wns, have a look at <a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj860484.aspx" target="_blank">MSDN</a>). The parameters for the method are simple, first it needs the channel. The channel is a direct link between an installation of your app and the server. It’s unique for every installation of the app. Next parameter is the payload of the toast, the information that will be shown on the toast message itself. Third parameter are the options. This is where we pass the launch parameters for the Windows app and the functions for success and error.</p> <p>That’s all for the script. Pretty easy right?</p> <h2>Windows Phone app</h2> <p>The Windows Phone app is pretty straightforward as well. In this proof of concept it’ll just be an app with a bunch of buttons, when the Windows 8 app starts it will show the button that was clicked on the phone. Create a new Windows Phone 8.0 application and add the following NuGet package to the project.</p> <h3>Install-Package WindowsAzure.MobileServices </h3> <p>This will install the WAMS SDK into the project. We’ll need this SDK to fetch the channel and request the toast message. </p> <p>The Windows Phone app only has one page with a really simple layout</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bb60f571-9d22-48d0-8f97-606c1b19dd76" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#008000"><!-- ContentPanel - place additional content here --></span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">StackPanel</span><span style="background:#ffffff;color:#ff0000"> x</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#ff0000">Name</span><span style="background:#ffffff;color:#0000ff">="ContentPanel"</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#ff0000"> Grid.Row</span><span style="background:#ffffff;color:#0000ff">="1"</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#ff0000"> Margin</span><span style="background:#ffffff;color:#0000ff">="12,0,12,0"></span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">TextBlock</span><span style="background:#ffffff;color:#ff0000"> Text</span><span style="background:#ffffff;color:#0000ff">="Enter ID" /></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">TextBox</span><span style="background:#ffffff;color:#ff0000"> x</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#ff0000">Name</span><span style="background:#ffffff;color:#0000ff">="TextBoxId" /></span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 1" /></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 2" /></span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 3" /></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 4" /></span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 5" /></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 6" /></span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 7" /></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Button</span><span style="background:#ffffff;color:#ff0000"> Click</span><span style="background:#ffffff;color:#0000ff">="Button_Click"</span><span style="background:#ffffff;color:#ff0000"> Content</span><span style="background:#ffffff;color:#0000ff">="Button 8" /></span></li> <li><span style="background:#ffffff;color:#0000ff"></</span><span style="background:#ffffff;color:#a31515">StackPanel</span><span style="background:#ffffff;color:#0000ff">></span></li> </ol> </div> </div> </div> <p>A Textbox that will hold an ID and 8 buttons that use the same click event handler. The Windows 8 app that we’ll build in a minute will request a Channel from WNS, we’ll save that channel into our WAMS database. The ID that we enter here in the textbox is the ID of the record that holds the channel that we want to use. That means that in a real app, you’ll need to find a way to get the ID from the Windows 8 app into the Windows Phone app. Possibilities here are NFC or QR codes, or just plain text. Alternatively, you could use the username from a Microsoft Account to store and retrieve the channel instead of an ID.</p> <p>Next we need to initialize the WAMS SDK in App.xaml.cs</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ebe8eacd-f80a-4a76-af34-fb9d2e798cda" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">partial</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">App</span><span style="background:#ffffff;color:#000000"> : </span><span style="background:#ffffff;color:#2b91af">Application</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000"> {</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MobileServiceClient</span><span style="background:#ffffff;color:#000000"> MobileService = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MobileServiceClient</span><span style="background:#ffffff;color:#000000">(</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#a31515">"https://nicopushdemo.azure-mobile.net/"</span><span style="background:#ffffff;color:#000000">,</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#a31515">"qCWCpYmWlJiOyXFQnKscFYnNixruku41"</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">);</span></li> </ol> </div> </div> </div> <p>You’ll need the values of your own service here of course. It can be found by going to the Azure management portal, selecting your WAMS and opening the “Connecting an existing application” option.</p> <p><a href="http://i43.tinypic.com/sbsp6g.jpg" target="_blank"><img src="http://i43.tinypic.com/sbsp6g.jpg" width="614" height="332" /></a></p> <p>Here’s the button event handler for the eight buttons</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c87c35cc-8a49-4687-8729-91d7387e5788" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> Button_Click(</span><span style="background:#ffffff;color:#0000ff">object</span><span style="background:#ffffff;color:#000000"> sender, </span><span style="background:#ffffff;color:#2b91af">RoutedEventArgs</span><span style="background:#ffffff;color:#000000"> e)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">Notification</span><span style="background:#ffffff;color:#000000"> notification = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Notification</span><span style="background:#ffffff;color:#000000">();</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000">notification.Channel = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> FetchChannel(</span><span style="background:#ffffff;color:#0000ff">int</span><span style="background:#ffffff;color:#000000">.Parse(TextBoxId.Text));</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">notification.Message = </span><span style="background:#ffffff;color:#a31515">"Click to launch the app"</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">notification.Title = </span><span style="background:#ffffff;color:#a31515">"Message from the Phone app!"</span><span style="background:#ffffff;color:#000000">;</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">notification.LaunchParam = ((</span><span style="background:#ffffff;color:#2b91af">Button</span><span style="background:#ffffff;color:#000000">) sender).Content.ToString();</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> response = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">App</span><span style="background:#ffffff;color:#000000">.MobileService.InvokeApiAsync<</span><span style="background:#ffffff;color:#2b91af">Notification</span><span style="background:#ffffff;color:#000000">, </span><span style="background:#ffffff;color:#2b91af">NotificationResult</span><span style="background:#ffffff;color:#000000">>(</span><span style="background:#ffffff;color:#a31515">"notifications"</span><span style="background:#ffffff;color:#000000">, notification);</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (response.IsSuccess)</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#2b91af">MessageBox</span><span style="background:#ffffff;color:#000000">.Show(</span><span style="background:#ffffff;color:#a31515">"Toast succes!"</span><span style="background:#ffffff;color:#000000">);</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> <li> </li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Task</span><span style="background:#ffffff;color:#000000"><</span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">> FetchChannel(</span><span style="background:#ffffff;color:#0000ff">int</span><span style="background:#ffffff;color:#000000"> id)</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> channels = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">App</span><span style="background:#ffffff;color:#000000">.MobileService.GetTable<</span><span style="background:#ffffff;color:#2b91af">Channel</span><span style="background:#ffffff;color:#000000">>().Where(c => c.Id == id).ToListAsync();</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000"> channels[0].ChannelUri;</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>When one of the buttons is clicked an instance of Notification is created, Notification is a class that we build ourselves, looks like this</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:192e2027-cc1a-46e2-af33-bfe224f634a5" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Notification</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#2b91af">{</span></li> <li> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(propertyName: </span><span style="background:#ffffff;color:#a31515">"message"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> Message { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(propertyName: </span><span style="background:#ffffff;color:#a31515">"title"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> Title { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(propertyName: </span><span style="background:#ffffff;color:#a31515">"channel"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> Channel { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(propertyName: </span><span style="background:#ffffff;color:#a31515">"launchParam"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> LaunchParam { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>FetchChannel will use the entered ID to fetch the channel from the WAMS database (saving the channel in the DB will be done from the Windows Store app). The LaunchParam is the content from the button that was clicked.</p> <p>Once the Notification instance is filled up, we call the custom API by calling InvokeAPIAsync, the generic types passed in are the type of the parameter and the type of the expected result. The expected result is NotificationResult</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2c954b56-4f8a-4783-bfde-c193a09c6d51" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">NotificationResult</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#2b91af">{</span></li> <li> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(PropertyName = </span><span style="background:#ffffff;color:#a31515">"isSuccess"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">bool</span><span style="background:#ffffff;color:#000000"> IsSuccess { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">[</span><span style="background:#ffffff;color:#2b91af">JsonProperty</span><span style="background:#ffffff;color:#000000">(PropertyName = </span><span style="background:#ffffff;color:#a31515">"response"</span><span style="background:#ffffff;color:#000000">)]</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> Response { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>The parameters for InvokeApiAsync are the name of the custom API, the object of the same type that was specified. The WAMS SDK will take care of deserializing that object into a JSON format using Json.NET before sending it over the wire to our API.</p> <h2>Windows 8 app</h2> <p>The final piece of the puzzle is the Windows 8 app. This is a very basic app consisting of two pages. An empty MainPage and a SecondPage. This to prove that you can navigate to any page when launched from a toast.</p> <p>Create an empty Windows 8 app and once again add the WAMS SDK through NuGet.</p> <h3>Install-Package WindowsAzure.MobileServices </h3> <p>We’ll start by initializing the WAMS SDK in App.xaml.cs</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c9772229-4533-4130-a7d8-deece192f095" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 500px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2.5em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">sealed</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">partial</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">class</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">App</span><span style="background:#ffffff;color:#000000"> : </span><span style="background:#ffffff;color:#2b91af">Application</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000"> {</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">PushNotificationChannel</span><span style="background:#ffffff;color:#000000"> CurrentChannel { </span><span style="background:#ffffff;color:#0000ff">get</span><span style="background:#ffffff;color:#000000">; </span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">set</span><span style="background:#ffffff;color:#000000">; }</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">public</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">static</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MobileServiceClient</span><span style="background:#ffffff;color:#000000"> MobileService = </span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">MobileServiceClient</span><span style="background:#ffffff;color:#000000">(</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#a31515">"https://nicopushdemo.azure-mobile.net/"</span><span style="background:#ffffff;color:#000000">,</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#a31515">"qCWCpYmWlJiOyXFQnKscFYnNixruku41"</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">);</span></li> <li> </li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">private</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">async</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> AcquirePushChannel()</span></li> <li> <span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">CurrentChannel = </span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">PushNotificationChannelManager</span><span style="background:#ffffff;color:#000000">.CreatePushNotificationChannelForApplicationAsync();</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">var</span><span style="background:#ffffff;color:#000000"> settings = Windows.Storage.</span><span style="background:#ffffff;color:#2b91af">ApplicationData</span><span style="background:#ffffff;color:#000000">.Current.LocalSettings;</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000">(settings.Values.ContainsKey(</span><span style="background:#ffffff;color:#a31515">"channel"</span><span style="background:#ffffff;color:#000000">))</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> previousChannel = settings.Values[</span><span style="background:#ffffff;color:#a31515">"channel"</span><span style="background:#ffffff;color:#000000">].ToString();</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000">(previousChannel == CurrentChannel.Uri)</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">return</span><span style="background:#ffffff;color:#000000">;</span></li> <li> <span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000">settings.Values[</span><span style="background:#ffffff;color:#a31515">"channel"</span><span style="background:#ffffff;color:#000000">] = CurrentChannel.Uri;</span></li> <li style="background: #f3f3f3"> </li> <li> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">await</span><span style="background:#ffffff;color:#000000"> MobileService.GetTable<</span><span style="background:#ffffff;color:#2b91af">Channel</span><span style="background:#ffffff;color:#000000">>().InsertAsync(</span><span style="background:#ffffff;color:#0000ff">new</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#2b91af">Channel{</span><span style="background:#ffffff;color:#000000">ChannelUri = CurrentChannel.Uri});</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>A bit more initial work needed here. First the same codeblock as the one in the WP8 app. Next is the AcquirePushChannel method. This one will ask WNS for a push channel, save it to the WAMS DB and into the Application’s settings. This is because a channel has a lifetime, during this time the application will be able to reuse that same channel. On every app start we’ll check if the channel we receive from WNS is the same one that is stored in the WAMS DB, if it isn’t we store it again.</p> <p>Now, the magic also happens here in App.xaml.cs, at the end of the OnLaunched method.</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:20e6bcdd-b495-4a5f-bb10-180cd80900e6" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000"> launchArgs = e.Arguments.Trim().ToString();</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#0000ff">if</span><span style="background:#ffffff;color:#000000"> (launchArgs != </span><span style="background:#ffffff;color:#0000ff">string</span><span style="background:#ffffff;color:#000000">.Empty)</span></li> <li><span style="background:#ffffff;color:#000000">{</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000">rootFrame.Navigate(</span><span style="background:#ffffff;color:#0000ff">typeof</span><span style="background:#ffffff;color:#000000">(</span><span style="background:#ffffff;color:#2b91af">SecondPage</span><span style="background:#ffffff;color:#000000">), launchArgs);</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> <li style="background: #f3f3f3"> </li> <li><span style="background:#ffffff;color:#008000">// Ensure the current window is active</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#2b91af">Window</span><span style="background:#ffffff;color:#000000">.Current.Activate();</span></li> </ol> </div> </div> </div> <p>We’ll check to see if the LaunchActivedArgs have some arguments. If they don’t, nothing special happens and MainPage is loaded. If they do, the argument will be the LaunchParams we’ve passed from the WP8 app, to the custom API. That value has now finally reached our Windows 8 app via the toast. We navigate to SecondPage and pass in the launchArgs as parameter.</p> <p>SecondPage.xaml looks like this</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:39e90d6e-e0dc-4da7-922f-6c6fa7d41e66" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">Grid</span><span style="background:#ffffff;color:#ff0000"> Background</span><span style="background:#ffffff;color:#0000ff">="{</span><span style="background:#ffffff;color:#a31515">ThemeResource</span><span style="background:#ffffff;color:#ff0000"> ApplicationPageBackgroundThemeBrush}</span><span style="background:#ffffff;color:#0000ff">"></span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff"><</span><span style="background:#ffffff;color:#a31515">TextBlock</span><span style="background:#ffffff;color:#ff0000"> x</span><span style="background:#ffffff;color:#0000ff">:</span><span style="background:#ffffff;color:#ff0000">Name</span><span style="background:#ffffff;color:#0000ff">="SelectedItem"</span><span style="background:#ffffff;color:#ff0000"> Style</span><span style="background:#ffffff;color:#0000ff">="{</span><span style="background:#ffffff;color:#a31515">StaticResource</span><span style="background:#ffffff;color:#ff0000"> HeaderTextBlockStyle}</span><span style="background:#ffffff;color:#0000ff">" /></span></li> <li><span style="background:#ffffff;color:#0000ff"></</span><span style="background:#ffffff;color:#a31515">Grid</span><span style="background:#ffffff;color:#0000ff">></span></li> </ol> </div> </div> </div> <p>In the code behind of SecondPage we’ll need to override OnNavigatedTo</p> <div id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:689d5ef3-a39c-4217-8b37-2a28985cd6f6" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background: #000080; color: #fff; font-family: Verdana, Tahoma, Arial, sans-serif; font-weight: bold; padding: 2px 5px">Code Snippet</div> <div style="background: #ddd; max-height: 300px; overflow: auto"> <ol start="1" style="background: #ffffff; margin: 0 0 0 2em; padding: 0 0 0 5px;"> <li><span style="background:#ffffff;color:#0000ff">protected</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">override</span><span style="background:#ffffff;color:#000000"> </span><span style="background:#ffffff;color:#0000ff">void</span><span style="background:#ffffff;color:#000000"> OnNavigatedTo(</span><span style="background:#ffffff;color:#2b91af">NavigationEventArgs</span><span style="background:#ffffff;color:#000000"> e)</span></li> <li style="background: #f3f3f3"><span style="background:#ffffff;color:#000000">{</span></li> <li> <span style="background:#ffffff;color:#000000">SelectedItem.Text = </span><span style="background:#ffffff;color:#a31515">"Navigated to this page by clicking in the phone app on "</span><span style="background:#ffffff;color:#000000"> + e.Parameter;</span></li> <li style="background: #f3f3f3"> <span style="background:#ffffff;color:#000000"></span><span style="background:#ffffff;color:#0000ff">base</span><span style="background:#ffffff;color:#000000">.OnNavigatedTo(e);</span></li> <li><span style="background:#ffffff;color:#000000">}</span></li> </ol> </div> </div> </div> <p>And that’s basically it. </p> <h2>Making it happen</h2> <p>Run the Windows 8 app once, so that it’s installed on your system and a channel is registered and saved into the WAMS DB. Feel free to close the app afterwards.</p> <p>Launch the Windows Phone app, insert the correct ID into the textbox and hit any of the buttons.</p> <p><a href="http://i42.tinypic.com/11rygsx.jpg" target="_blank"><img src="http://i42.tinypic.com/11rygsx.jpg" width="246" height="410" /></a></p> <p>Click the toast when it pops up and be amazed by the result <img class="wlEmoticon wlEmoticon-smile" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="Glimlach" src="http://www.spikie.be/blog/images/wlEmoticon-smile_27.png" /></p> <p><img src="http://i42.tinypic.com/1z3p5di.jpg" /></p> <p><img src="http://i42.tinypic.com/2q9b9dv.jpg" width="762" height="43" /></p> <h2>Conclusion</h2> <p>In this post I’ve talked about a way to share data between apps through the use of push notifications. When you have the same app on both Windows Phone and Windows 8 this provides a cool way for your user to switch platforms while remaining on the same part of the app.</p> <p>Download the projects from my SkyDrive:</p> <ul> <li><a href="http://sdrv.ms/1987H82" target="_blank">Windows 8</a></li> <li><a href="http://sdrv.ms/1987WQr" target="_blank">Windows Phone</a></li> </ul>
This is an imported post. It was imported from my old blog using an automated tool and may contain formatting errors and/or broken images.
Leave a Comment