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!

  • well it sure would be nice for Microsoft to standardize this structure for us and let all devs know, then hide it from the user (but provide a facility to know how much each app is consuming in it) Also mandate any app using the SkyDrive API has to have a facility to delete data from skydrive so it can reach in and clean up its own isolated storage. This isn’t rocket science folks.

  • Pingback: Windows Live Program Manager reassures developers their apps will not be pulled for backing up to SkyDrive | WMPoweruser()

  • Nice workaround, let’s hope it becomes standard. It would be cool if Microsoft hides that folder from ordinary SkyDrive browsing.

  • HDW Production

    This folder structure is good for synchronizing, not for backups. E.g. one user can have multiple PCs, both having the same app installed. Both apps would override each others data. To make it a backup solution, add the unique DeviceId to the folder structure.

    • Brandon

      Definitely a good point. The desire here is for user-level synchronization a la user preferences w/in an app. If there are device-specific things you wish to squirrel off, another layer needs to be added.

  • svi

    Nice Structure, but I would remove the “Windows Phone” folder, or renamed it to “Windows” to keep same folders for the same app on different platforms (WP8, W8, …)

    • Brandon

      Due to the differences in the windows platforms, though – at least right now with WP7 – I can definitely see a scenario where a franchise distributes apps that are complementary yet functionally different, so I’m still inclined to keep Phone separate from Desktop/Slate. But again, YMMV and as long as you “hide” these things from the user so they aren’t bombarded with 400 app folders when they view their SkyDrive root, I think we’re miles ahead no matter what.

  • Aco

    any example to create this directory structure? until now I have achieved only create the folder in the root …Regards

    • Brandon

      Done and done, thanks for the suggestion, hope it helps!

      • Aco

        fantastic! this will help implement this structure. You are great! :)

  • ProgramData sounds too retro and roots to desktop past. It should be AppData!

    • Brandon

      lol I suppose so. However Windows also has AppData under your User directory… I think in Windows it’s meant for AppData to be specific per user, while ProgramData is specific to the program (across users)
      Given that, if we were going to be sticklers for meaning, AppData would be the way to go. But, since what I’ve proposed has already grown some pretty impressive legs, I won’t change it ;)

      Good suggestion though!

  • Pingback: Async alternative | Jisku.com - Developers Network()

  • Good information about folder structure best practice. Please see the complete implementation of SkyDrive Backup and Restore in a windows 8 app http://www.coderewind.com/2012/08/how-to-integrate-skydrive-backup-in-windows-8-app/

    • Brandon

      Great post as well, would be better if it used the post’s folder structure, though ;)

      • Yes, i will be refactoring the code sample. :)

        • Brandon

          Glad to hear! when you do I would much appreciate a link in your article ;)

  • Henrik

    Why not follow the style of DropBox? Have an Apps root folder and then below that each app/application has its own folder. In fact, why does SkyDrive not have the possibility to sandbox an app’s access to its own folder in the Apps folder (just like DropBox does). I don’t like giving an app free-range access to my whole SkyDrive and it does not need to have that kind of access.

    • No doubt that DropBox’s app-centric API does a great job of managing this already, however SkyDrive doesn’t have that model – yet. So this is the best we can do.