This is Day # 8 in the Windows 8 development article series on common tips & tricks towards real-world Windows 8 Store apps. With our App nearing function-complete, time to provide the personal touch in user experience through the use of Live Services. Over the last several weeks, you saw 8 articles talk about some must-do things for Windows 8 app developers. Simple & to the point, with some code examples on XAML/C# stack. Here’s the indexed list for the series:
Day 1: Know the ecosystem; Start
Day 2: Layout, Navigation & Visual States
Day 3: Semantic Zoom
Day 4: Controls & Styling
Day 5: Search, Share & Settings Contracts
Day 6: Data Persistence & Application Life-Cycle Management
Day 7: Use of OData or Web Services
Day 8: Live Services integration
Day 8: Live Services Integration
Live Services is a suite of services comprising of Microsoft’s SkyDrive, Hotmail/Live/Outlook email & Windows Live Messenger, often clubbed together as Software-As-Service. The user base count of Live Services is well over 500 million & integration with such services in our Windows 8 Apps provides new ways to engage the user with what he already considers personal, thus leading to a more intimate UX and increased usage. Live Connect is a collection of APIs with RESTful endpoints on top of Live Services, which helps us integrate the user’s “personal cloud” in our applications; while .NET wrappers make the developers life simple while performing asynchronous network calls. Let’s look at our options on C#/XAML stack.
Single Sign-On
People hate signing in, period. With myriads of websites/applications requiring form-based User ID/Password authentication, no wonder users are at a loss remembering credentials. Also, authenticating users is serious business and needs appropriate safety in system architecture, before applications can be developed. So, it makes sense for developers to get away from user authentication when possible, and trusting established identity providers for user tokens. With Windows 8 allowing Microsoft Accounts to sign users in, Live Services offer a unique way to facilitate single sign-on across Apps & websites. Not only can our Apps let MSFT sign users in; but in the same breath, we also can request access to the signed-on user’s information to provide a personalized UX.
Here are the steps needed to allow Live Service single sign-on:
- Get the Live Connect SDK from http://msdn.microsoft.com/en-US/live/ff621310.
- Start the Windows 8 Store App project & Add a Service Reference to the Live Connect DLL.
- Figure out what Scopes your App might need. Details @ http://msdn.microsoft.com/en-us/library/live/hh243646.aspx.
- It is not a good idea to ask for everything all at once, since it may make the user suspicious of your goals. We can always go back & ask for more permissions as needed.
- Use the built-in Sign-In XAML control to allow the user to sign-in with their MSFT Account credentials, passing along the Scopes needed. This takes care of all the heavy-lifting of making the appropriate HTTP calls on our behalf.
- Add appropriate branding to Sign-in button as suited for App.
Here’s some code, to add the Sign-In button and handle changes with respect to the user providing credentials through MSFT Account & us having access to the user’s Session object:
1: // XAML Button on screen.
2: <live:SignInButton x:Name="btnLogin" Scopes="wl.signin wl.basic" TextType="Custom" SignInText="Come join the wonderland ..." SignOutText="Adios .."
3: Branding="Messenger" Theme="Dark" SessionChanged="btnLogin_SessionChanged" />
4:
5: // Code-behind.
6: using Microsoft.Live.Controls;
7:
8: private LiveConnectClient client;
9: private async void btnLogin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
10: {
11: if (e.Status == LiveConnectSessionStatus.Connected)
12: {
13: client = new LiveConnectClient(e.Session);
14: LiveOperationResult operationResult = await client.GetAsync("me");
15:
16: try
17: {
18: dynamic meResult = operationResult.Result;
19: if (meResult.first_name != null && meResult.last_name != null)
20: {
21: infoTextBlock.Text = "Hello " + meResult.first_name + " " + meResult.last_name + "!";
22: }
23: else
24: {
25: infoTextBlock.Text = "Hello, signed-in user!";
26: }
27:
28: contactHeader.Visibility = Windows.UI.Xaml.Visibility.Visible;
29: FetchContacts();
30: }
31: catch (LiveConnectException exception)
32: {
33: this.infoTextBlock.Text = "Error calling API: " + exception.Message;
34: }
35: }
36: else
37: {
38: infoTextBlock.Text = "Not signed in.";
39: }
40:
41: infoTextBlock.Visibility = Windows.UI.Xaml.Visibility.Visible;
42: }
Even though a user is signed on to their Windows 8 PC using a MSFT Account, user information is not automatically available for Apps to tap into, since that would be an invasion to privacy. So, the user has to explicitly provide consent to your App towards using his/her information, based on the Scopes/Permissions that your App asked for. First time users will be greeted with an approval UI, like below, automatically displayed by the Live Connect Sign-In button plumbing:
Upon user consent, we can sign in the user & use his/her profile information to greet, as seen in the event handler in the code above. Once the user starts using your App upon signing-in & allowing permissions, he/she can see your App in their MSFT Account profile, as shown below, including the ability to revoke rights with granularity:
User Data
Once declared Scopes are permitted through user permission, the Live Connect APIs can be used to create/read a user's Contacts, and can create/read/update/delete the user's Calendars. But with power comes responsibility and restraint & justification should be in place for such use in our Windows 8 Store Apps.
Armed with the wl.basic Scope, here’s a way to retrieve the user’s Contacts list and display them in a GridView:
1: private async void FetchContacts()
2: {
3: try
4: {
5: LiveConnectClient liveClient = new LiveConnectClient(client.Session);
6: LiveOperationResult operationResult = await liveClient.GetAsync("me/contacts");
7:
8: dynamic contactsResult = operationResult.Result;
9: List<dynamic> contactsList = contactsResult.data;
10:
11: this.itemGridView.ItemsSource = contactsList;
12: }
13: catch (LiveConnectException exception)
14: {
15: this.contactsError.Text = "Error getting contact info: " + exception.Message;
16: this.contactsError.Visibility = Windows.UI.Xaml.Visibility.Visible;
17: }
18: }
Did you notice the use of the shortcut “me”? It’s a quick HTTP endpoint to refer to the signed-in user. And here’s how we could bind it to our GridView UI; you have complete flexibility to parse & bind data to UI as needed:
1: <GridView
2: x:Name="itemGridView"
3: AutomationProperties.AutomationId="ItemGridView"
4: AutomationProperties.Name="Grouped Items"
5: Margin="0,30,40,46"
6: ItemTemplate="{StaticResource Contacts250x100Template}">
7:
8: <GridView.ItemsPanel>
9: <ItemsPanelTemplate>
10: <VariableSizedWrapGrid Orientation="Horizontal" Margin="0,0,100,0" FlowDirection="LeftToRight" Height="700" Width="1400" />
11: </ItemsPanelTemplate>
12: </GridView.ItemsPanel>
13: </GridView>
14:
15: <!-- Template to display Contacts -->
16: <DataTemplate x:Key="Contacts250x100Template">
17: <Grid HorizontalAlignment="Left" Width="250" Height="100">
18: <Border Background="#99FFDD" Opacity="1">
19: <StackPanel Orientation="Vertical">
20: <TextBlock Text="{Binding id}" Foreground="#6655FF" Margin="5,5,15,2" VerticalAlignment="Top" TextWrapping="Wrap" FontSize="10"/>
21: </StackPanel>
22: </Border>
23: <StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}" Height="30" Orientation="Horizontal">
24: <TextBlock Text="{Binding name}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Margin="5,0,15,0"/>
25: </StackPanel>
26: </Grid>
27: </DataTemplate>
28:
SkyDrive
SkyDrive is the MSFT Account holder’s personal space in the cloud & heavily used as a feature, specially in the Windows 8/Windows Phone ecosystem. So, while a convenient storage option, we developers need to be careful to not undermine the faith users have in SkyDrive. Need to store data outside of the user’s device and thinking of hosting a cloud data storage yourself - Why not just leverage the user’s SkyDrive? Not only is the user accustomed to SkyDrive, but his/her settings/data also roam across devices, leading to convenience.
The wl.skydrive Scope gives us the permission to traverse up & down the user’s SkyDrive directory and inspect files/folders. Armed with the wl.skydrive_update Scope, we have complete access to read/write files & folders, move/delete/copy files from any location. Here’s the quick & easy way to upload a photo from a Windows 8 App onto the the base directory of user’s SkyDrive. Note the use of FileOpenPicker to select a photo from user’s photo library, before we upload the file asynchronously to SkyDrive root directory:
1: private async void UploadPicture()
2: {
3: try
4: {
5: var picker = new Windows.Storage.Pickers.FileOpenPicker();
6: picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
7: picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
8: picker.FileTypeFilter.Add("*");
9: Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
10:
11: if (file != null)
12: {
13: LiveConnectClient liveClient = new LiveConnectClient(client.Session);
14: await liveClient.BackgroundUploadAsync("me/skydrive", "MyUploadedPicture.jpg", file, OverwriteOption.Overwrite);
15: }
16: }
17: catch (LiveConnectException exception)
18: {
19: this.infoTextBlock.Text = "Error uploading file: " + exception.Message;
20: }
21: }
Conclusion
That’s it for today. The crux of this article was to talk about Live Service integration from Windows 8 Store Apps to provide the personal user experience users deserve. For more information on the various options of using Live Connect APIs to tap into the user’s already existing cloud presence through MSFT Account, start @ http://msdn.microsoft.com/en-us/library/live/hh243641.
This concludes our little 8-part Windows 8 App development article series. Hopefully, the tips & tricks I have learnt along the way saves you some time. Please offer feedback & thanks for reading. Happy coding!
About Author
Samidip Basu (@samidip) is a technologist, gadget-lover and MSFT Mobility Solutions Lead for Sogeti USA working out of Columbus OH. With a strong developer background in Microsoft technology stack, he now spends much of his time evangelizing Windows Phone/Windows 8 platforms & cloud-supported mobile solutions in general. He passionately helps run The Windows Developer User Group (http://thewindowsdeveloperusergroup.com/), labors in M3 Conf (http://m3conf.com/) organization and can be found with at-least a couple of hobbyist projects at any time. His spare times call for travel and culinary adventures with the wife. Find out more at http://samidipbasu.com.