SkyDrive backup of your mobile app – Let’s get some common ground

By | July 11, 2012

I’ve seen a lot of Windows Phone mobile apps implementing a “backup” feature to SkyDrive thanks to the new Live Connect SDK that Microsoft kicked out.

This is an excellent idea.

However, do you really want your SkyDrive to start looking like this?

[SkyDrive root]
  ‘- [Program 1]
  ‘- Photos
  ‘- [Program 2]
  ‘- [Program 3]
  ‘- Videos
  ‘- [Program 4]
  ‘- My Documents
  ‘- [Program 5]

Oh hell no. I’m way too OCD to have a file system even come CLOSE to looking like that.

So here’s my thought: Microsoft has already put in place a good paradigm for this. Remember c:\Program Files? How about c:\ProgramData? Let’s agree to keep this the same.

[SkyDrive root]
  ‘- ProgramData
    ‘- Windows Phone
      ‘- [Publisher Name]
        ‘- [Program Name]

The only level I’ve added here is the OS. That’s because I can see this also being used in Windows 8, hell even Xbox moving forward. An alternative here would be to put the OS flavor under your Program Name, then data in there. I could go either way.

Here’s the difference in my own personal SkyDrive, which I like quite a bit.

image

PackageTracker is one app I have that does backup to SkyDrive. It puts it in my root folder. However Cloud Transfer backs up to ProgramData. If you had 50 programs that backed up to SkyDrive, which structure would you prefer?

So personally, I’ve started doing this w/ all my Windows Phone apps. If you agree with this approach, retweet, re-blog, link, and implement this in your own mobile apps using backup.

If you haven’t thought about using backup, seriously look at it. The Live Connect SDK is crazy easy to use, and think about what you would do if you bought a new phone, or your phone broke, and now you had to re-configure all your apps w/ the settings you had previously. Wouldn’t it be great if the app had a “restore” feature? Hell yes it would.

UPDATE:
There’ve been a few requests for example code to create this. Below is just that. Requirements are the Async CTP and JSON.Net.

async private Task<string> GetSkyDriveBackupFolderId(LiveConnectClient client)
{
	var rootFolders = JObject.Parse((await client.GetAsyncTask("/me/skydrive/files?filter=folders,albums")).RawResult);
	var progDataFolder = rootFolders["data"].FirstOrDefault(f => f.Value<string>("name").Equals("programdata", StringComparison.OrdinalIgnoreCase));
	string progDataFolderId;
	if (progDataFolder == null)
	{
		var result = await client.PostAsyncTask("me/skydrive/",
			new Dictionary<string, object>() { { "name", "ProgramData" } });

		progDataFolderId = JObject.Parse(result.RawResult).Value<string>("folder_id");
	}
	else
	{
		progDataFolderId = progDataFolder.Value<string>("id");
	}

	var windowsPhoneFolder = JObject.Parse((await client.GetAsyncTask(string.Concat("/", progDataFolderId, "/files?filter=folders,albums"))).RawResult)["data"]
		.FirstOrDefault(f => f.Value<string>("name").Equals("windows phone", StringComparison.OrdinalIgnoreCase));
	string windowsPhoneFolderId;
	if (windowsPhoneFolder == null)
	{
		var result = await client.PostAsyncTask(string.Concat("/", progDataFolderId),
			new Dictionary<string, object>() { { "name", "Windows Phone" } });

		windowsPhoneFolderId = JObject.Parse(result.RawResult).Value<string>("id");
	}
	else
	{
		windowsPhoneFolderId = windowsPhoneFolder.Value<string>("id");
	}

	var bc3TechnologiesFolder = JObject.Parse((await client.GetAsyncTask(string.Concat("/", windowsPhoneFolderId, "/files?filter=folders,albums"))).RawResult)["data"]
		.FirstOrDefault(f => f.Value<string>("name").Equals("bc3 technologies", StringComparison.OrdinalIgnoreCase));
	string bc3TechnologiesFolderId;
	if (bc3TechnologiesFolder == null)
	{
		var result = await client.PostAsyncTask(string.Concat("/", windowsPhoneFolderId),
			new Dictionary<string, object>() { { "name", "BC3 Technologies" } });

		bc3TechnologiesFolderId = JObject.Parse(result.RawResult).Value<string>("id");
	}
	else
	{
		bc3TechnologiesFolderId = bc3TechnologiesFolder.Value<string>("id");
	}

	var cloudTransferFolder = JObject.Parse((await client.GetAsyncTask(string.Concat("/", bc3TechnologiesFolderId, "/files?filter=folders,albums"))).RawResult)["data"]
		.FirstOrDefault(f => f.Value<string>("name").Equals("cloud transfer", StringComparison.OrdinalIgnoreCase));
	string cloudTransferFolderId;
	if (cloudTransferFolder == null)
	{
		var result = await client.PostAsyncTask(string.Concat("/", bc3TechnologiesFolderId),
			new Dictionary<string, object>() { { "name", "Cloud Transfer" } });

		cloudTransferFolderId = JObject.Parse(result.RawResult).Value<string>("id");
	}
	else
	{
		cloudTransferFolderId = cloudTransferFolder.Value<string>("id");
	}

	return cloudTransferFolderId;
}

You use it simply by calling:

var id = await GetSkyDriveBackupFolderId(client);

Where client is a LiveConnectClient object. The goal is that the folder is eventually either found or created in the process and the folder Id is returned at the end of the day.

This is the best/only way I could figure to accomplish this since you can’t just throw a normal “x/y/z” path in to the Live Connect SDK and have it do the corresponding navigation. If you have seen a better way to do this, by all means let me know!