I can't find any documentation that outlines the correct way to use OneDrive to store and keep app files syncrhonised across devices in C#
I have read the documentation at OneDrive Dev Center but I don't understand the http code. (self taught C# only).
I kind of understand that I use the delta method to get changed files from OneDrive, to then save locally, but I can't figure out exactly how, so have gotten around it by checking local vs OneDrive manually using the GetAsync<>
methods.
My current implementation (below for reference) seems to me to be rather clunky compared to what is probably handled better in the API.
In addition, it doesn't appear that there is a reverse 'delta' function? That is, where I write a file to the app locally, then tell OneDrive to sync the change. Is that because I need to actually upload it using the PutAsync<>
method? (Currently what I am doing)
public async Task<T> ReadFromXML<T>(string gamename, string filename)
{
string filepath = _appFolder + @"\" + gamename + @"\" + filename + ".xml";
T objectFromXML = default(T);
var srializer = new XmlSerializer(typeof(T));
Item oneDItem = null;
int casenum = 0;
//_userDrive is the IOneDriveClient
if (_userDrive != null && _userDrive.IsAuthenticated)
{
try
{
oneDItem = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Request().GetAsync();
if (oneDItem != null) casenum += 1;
}
catch (OneDriveException)
{ }
}
StorageFile localfile = null;
try
{
localfile = await ApplicationData.Current.LocalFolder.GetFileAsync(filepath);
if (localfile != null) casenum += 2;
}
catch (FileNotFoundException)
{ }
switch (casenum)
{
case 0:
//neither exist. Throws exception to tbe caught by the calling method, which should then instantiate a new object of type <T>
throw new FileNotFoundException();
case 1:
//OneDrive only - should copy the stream to a new local file then return the object
StorageFile writefile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filepath, CreationCollisionOption.ReplaceExisting);
using (var newlocalstream = await writefile.OpenStreamForWriteAsync())
{
using (var oneDStream = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Content.Request().GetAsync())
{
oneDStream.CopyTo(newlocalstream);
}
}
using (var newreadstream = await writefile.OpenStreamForReadAsync())
{ objectFromXML = (T)srializer.Deserialize(newreadstream); }
break;
case 2:
//Local only - returns the object
using (var existinglocalstream = await localfile.OpenStreamForReadAsync())
{ objectFromXML = (T)srializer.Deserialize(existinglocalstream); }
break;
case 3:
//Both - compares last modified. If OneDrive, replaces local data then returns the object
var localinfo = await localfile.GetBasicPropertiesAsync();
var localtime = localinfo.DateModified;
var oneDtime = (DateTimeOffset)oneDItem.FileSystemInfo.LastModifiedDateTime;
switch (oneDtime > localtime)
{
case true:
using (var newlocalstream = await localfile.OpenStreamForWriteAsync())
{
using (var oneDStream = await _userDrive.Drive.Special.AppRoot.ItemWithPath(filepath).Content.Request().GetAsync())
{ oneDStream.CopyTo(newlocalstream); }
}
using (var newreadstream = await localfile.OpenStreamForReadAsync())
{ objectFromXML = (T)srializer.Deserialize(newreadstream); }
break;
case false:
using (var existinglocalstream = await localfile.OpenStreamForReadAsync())
{ objectFromXML = (T)srializer.Deserialize(existinglocalstream); }
break;
}
break;
}
return objectFromXML;
}