Introduction
Windows Store now has more than 50,000+ apps and growing as we speak at the same time cloud storage for these apps becomes a basic requirement to allow data roaming across multiple devices. In this article, we will talk about accessing SkyDrive cloud storage from Windows Store App.
I'm going to walk you through 5 basic operations:
- Create a Store App
- Login to Sky Drive using the App
- Create Folder on SkyDrive
- Upload File to SkyDrive
- Download File from SkyDrive
Create a SkyDrive Windows Store App
- Get a Windows Store developer account from here
- Install Visual Studio 2013 on a Windows 8.1 PC
- Install Live Connect SDK from here
- Create a new Windows Store C# project using Visual Studio 2013
- Add reference to Live Connect API
- Associate the app to the Store
- Include the live connect SDK in MainPage.xaml.cs:
using Microsoft.Live;
Now your app is ready to use SkyDrive Live Connect SDK.
- Add buttons to MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox Name="infoTextBlock" HorizontalAlignment="Left" Height="29"
Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="1346"/>
<Button Content="Sign In" HorizontalAlignment="Left" Margin="7,58,0,0"
VerticalAlignment="Top" Width="138" Height="50" Click="Button_SignIn_Click"/>
<Button Content="Create Folder" HorizontalAlignment="Left" Margin="7,126,0,0"
VerticalAlignment="Top" Height="50" Width="138" Click="Button_CreateFolder_Click"/>
<Button Content="Upload File" HorizontalAlignment="Left" Margin="7,197,0,0"
VerticalAlignment="Top" Height="50" Width="138" Click="Button_UploadFile_Click"/>
<Button Content="Upload Cancel" HorizontalAlignment="Left" Margin="170,197,0,0"
VerticalAlignment="Top" Height="50" Width="165" Click="Button_UploadFileCancel_Click"/>
<Button Content="Download File" HorizontalAlignment="Left" Margin="7,264,0,0"
VerticalAlignment="Top" Height="50" Width="138" Click="Button_DownloadFile_Click"/>
<Button Content="Download Cancel" HorizontalAlignment="Left" Margin="170,264,0,0"
VerticalAlignment="Top" Height="50" Width="165" Click="Button_DownloadFileCancel_Click"/>
</Grid>
Sign in to SkyDrive using the Demo App
To sign in using the demo application, click "Sign in" button.
In Windows 8.0/8.1, there is a concept called "Connected Accounts", if the user has already signed in using the Connected Account, then this App will use the current Microsoft Account to login to SkyDrive. When the App is run for the first time, the user will get a consent screen to give access to the SkyDrive resources.
In this example, we have the following access request "wl.signin
", "wl.basic
", "wl.skydrive
", "wl.skydrive_update
".
private LiveConnectClient liveClient;
The first action in this app should be clicking the "Sign in" button to create a LiveConnectClient object, this object created inside Button_SignIn_Click
method will be used by other file/folder access methods.
private async void Button_SignIn_Click(object sender, RoutedEventArgs e)
{
try
{
LiveAuthClient auth = new LiveAuthClient();
loginResult = await auth.LoginAsync(new string[]
{ "wl.signin", "wl.basic", "wl.skydrive", "wl.skydrive_update"});
liveClient = new LiveConnectClient(loginResult.Session);
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
this.infoTextBlock.Text = "Signed in.";
}
}
catch (LiveAuthException exception)
{
this.infoTextBlock.Text = "Error signing in: "
+ exception.Message;
}
}
If you notice, we do not have any user interface to receive the username and password, thanks to Windows Connected Account :) for managing the integrated authentication UI.
Working with SkyDrive Folders
In general, we write SkyDrive based Windows Store App to store user files/data in the cloud, so we may save the user data in cloud and can be accessed from any device. Here is the code snippet to create folder on SkyDrive. LiveConnectClient::PostAsync
method is used to create a new folder.
private async void Button_CreateFolder_Click(object sender, RoutedEventArgs e)
{
try
{
var folderData = new Dictionary<string, object>();
folderData.Add("name", "testfolderLevel1");
LiveOperationResult operationResult =
await liveClient.PostAsync("me/skydrive", folderData);
dynamic result = operationResult.Result;
this.infoTextBlock.Text = string.Join(" ",
"Created folder: ", result.name, "ID: ", result.id);
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = "Error creating folder: " + exception.Message;
}
}
Few lines of code to create a folder. Pretty simple! Thanks to Live Connect SDK. :)
When you click "Sign in" button and then "Create Folder", you will see the folder id as marked in the below picture.
As shown above, when the folder is created, the folder is given a unique id like "folder.8b922582dc2j7b71.8B922451DC2F7B71!811". Since files and folders are accessed using the ID and not using the full path, I have written a helper function below to create folders and subfolders using the full path.
Create_Folder()
method algorithm:
- Split the path using '/' delimiter into an array
- Check the folder existence using
getAsync
method - Get the folder ID using "/files" in the
getAsync
method - Repeat step 2 and 3 until all folder names are processed from the array.
- Create folder using
postAsync
method after the full path is processed
private async Task<string> Create_Folder(string sNewFoldername, string sRoot)
{
try
{
string sCurrentRootID = "me/skydrive";
bool bFolderFound = true;
if (sRoot != "")
{
string[] Folderhierarchy = sRoot.Split('/');
LiveOperationResult result;
foreach (string sFolder in Folderhierarchy)
{
bFolderFound = false;
result = await liveClient.GetAsync(sCurrentRootID +"/files");
dynamic files = result.Result;
List<object> data = (List<object>)files.data;
bFolderFound = false;
if (data == null)
break;
foreach (dynamic item in data)
{
if (item.name == sFolder)
{
sCurrentRootID = (string)item.id;
bFolderFound = true;
break;
}
}
if (bFolderFound != true )
{
this.infoTextBlock.Text = "Invalid path";
break;
}
}
}
if(bFolderFound == true)
{
var folderData = new Dictionary<string, object>();
folderData.Add("name", sNewFoldername);
LiveOperationResult operationResult = await liveClient.PostAsync(sCurrentRootID, folderData);
dynamic DynResult = operationResult.Result;
this.infoTextBlock.Text = string.Join
("Created folder: ", DynResult.name, "ID: ", DynResult.id);
return (string)DynResult.id;
}
return null;
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = "Error creating folder: " + exception.Message;
return null;
}
}
You can call the above function as follows:
Create_Folder("TestFolderLevel1", "");
Create_Folder("TestFolderLevel2", "TestFolderLevel1");
Create_Folder("TestFolderLevel3", "TestFolderLevel1/TestFolderLevel2");
I hope the above helper will make the folder access easier like you do with the local drive folder access.
Upload a File to SkyDrive
Now that the demo application is signed in and we are able to create folders, the next task is to upload the files into this newly created folder. I'm providing a code snippet to upload the file to root of the SkyDrive but you can write your own function to upload to a specific folder.
private async void Button_UploadFile_Click(object sender, RoutedEventArgs e)
{
try
{
var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add("*");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
this.ctsUpload = new System.Threading.CancellationTokenSource();
await liveClient.BackgroundUploadAsync("me/skydrive",
"TestUploadedPicture.jpg", file,
OverwriteOption.Overwrite, this.ctsUpload.Token, null);
this.infoTextBlock.Text = "Upload completed.";
}
}
catch (System.Threading.Tasks.TaskCanceledException)
{
this.infoTextBlock.Text = "Upload cancelled.";
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = "Error uploading file: " + exception.Message;
}
}
The above function may contain many lines but most of the code is about selecting a file to upload. Upload is initiated using BackgroundUploadAsync
method from LiveConnectClient object.
private void Button_UploadFileCancel_Click(object sender, RoutedEventArgs e)
{
if (this.ctsUpload != null)
{
this.ctsUpload.Cancel();
}
}
Since larger file upload may take a longer to complete, this is done asynchronously and can be cancelled using the cancel upload button.
Download a File from SkyDrive
All it requires to download a file is to create a LiveConnectClient
object and call BackgroundDownloadAsync
it's that simple when you use Live Connect SDK.
private System.Threading.CancellationTokenSource ctsDownload;
private async void Button_DownloadFile_Click(object sender, RoutedEventArgs e)
{
try
{
var picker = new Windows.Storage.Pickers.FileSavePicker();
picker.SuggestedFileName = "TestDownloadedPicutre.jpg";
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Downloads;
picker.FileTypeChoices.Add("Picture", new List<string>(new string[] { ".jpg" }));
StorageFile file = await picker.PickSaveFileAsync();
if (file != null)
{
this.ctsDownload = new System.Threading.CancellationTokenSource();
await liveClient.BackgroundDownloadAsync("<file id to download>", file,
this.ctsDownload.Token, null);
this.infoTextBlock.Text = "Download completed.";
}
}
catch (System.Threading.Tasks.TaskCanceledException)
{
this.infoTextBlock.Text = "Download cancelled.";
}
catch (LiveConnectException exception)
{
this.infoTextBlock.Text = "Error getting file contents: " + exception.Message;
}
}
As same as upload depending on the network speed download process may take some time and the app needs to respond to the user actions so we call BackgroundDownloadAsync
method and provide a download cancel handler as below.
private void Button_DownloadFileCancel_Click(object sender, RoutedEventArgs e)
{
if (this.ctsDownload != null)
{
this.ctsDownload.Cancel();
}
}
Note: To download the file content fully use "/content" at the end.
BackgroundDownloadAsync("file.8c8ce076ca27823f.8C8CE076CA27823F!129/content", <br />file,ctsDownload.Token, null);
Without the "/content", the image files may download thumbnails only.
Summary
I have attached the MainPage.xaml.cs and MainPage.xaml with this article. You can create your own project and then replace the above files to get a fully working sample of Windows 8.1 Store App. Using the Live Connect SDK was simple to use but there are other ways to access SkyDrive files as explained here. Thank you for your time and your feedback is much appreciated.
History
- 19th January, 2014: Initial post