How to simply access SkyDrive, write and read files? - c#

I want to use SkyDrive to backup some information.
But seems they have removed this namespace Microsoft.Live.Controls; from the new SDK, and all code samples and also answers here are outdated.
this reference also is outdated; there is no more LiveConnectClient
How can I simply backup files to SkyDrive after these changes?
(any code sample or reference is appreciated.)

It's not that hard, but there really are no references or tutorials. Everything that's below works just fine in my Windows Phone 8 project.
You need to include Microsoft.Live namespace after installing Live SDK.
First you have to create and initialize the client. After that, you log in and can send over some data:
LiveConnectClient client;
var auth = new LiveAuthClient("YourGeneratedKey");
var result = await auth.InitializeAsync(new [] {"wl.basic", "wl.signin", "wl.skydrive_update" });
// If you're not connected yet, that means you'll have to log in.
if(result.Status != LiveConnectSessionStatus.Connected)
{
// This will automatically show the login screen
result = await auth.LoginAsync(new [] {"wl.basic", "wl.signin", "wl.skydrive_update" });
}
if(result.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(result.Session);
}
Maybe the process above could be simplified, but it works for me.
Now you can use the client if everything went as planned. I've managed to successfully upload files from streams.
Let's say you've obtained a Stream to the file you want to send (I got that via WinRT file API on Windows Phone 8, IStorageFolder, then getting the file, then file.OpenStreamForReadAsync()), I'll just assume it's a text file for example purposes:
using(stream)
{
await client.UploadAsync("me/skydrive", "myfile.txt", stream, OverwriteOption.Overwrite);
}
Actually, I've used the overload that also accepts CancellationToken and IProgress<LiveOperationProgress>, mostly for progress notifications.
There, that should upload the file to the main directory on logged user's SkyDrive.

Related

LiveSDK for Universal Windows App background upload

I'm developing Universal Windows App and use Live SDK 5.6 to upload files to OneDrive. I see examples of usage here and instructions about versions here.
According to instructions I should use:
For Windows and WP81: CreateBackgroundUploadAsync method;
For WP8 Silverlight: BackgroundUploadAsync method
CreateBackgroundUploadAsync works like a charm on Windows and returns correct progress values by LiveOperationProgress but on a WP81 it shows 0% progress all the time and at last it becames 100%. So it actually does not track progress.
Then I tried to use BackgroundUploadAsync(it is for Silverlight apps) and it works on phone - uploads file and tracks progress right. But when I tried to upload big file(in my case > 150Mb) I noted that exactly after 120 seconds upload operation just resets to 0% and starts again without any exceptions.
Here is code for Windows & WP81 approach:
var progressHandler = new Progress<LiveOperationProgress>(
(progress) =>
{
var res = progress.ProgressPercentage;
});
LiveUploadOperation uploadOperation = await liveConnectClient.CreateBackgroundUploadAsync(uploadPath, "testfile.wav", file, OverwriteOption.Rename);
LiveOperationResult uploadResult = await uploadOperation.StartAsync(new CancellationToken(), progressHandler);
And for Silverlight:
var progressHandler = new Progress<LiveOperationProgress>(
(progress) =>
{
var res = progress.ProgressPercentage;
});
LiveOperationResult opResult = await connectClient.BackgroundUploadAsync(CurrentFolderId,
file.Name,
stream,
OverwriteOption.Rename,
record.GetCTS().Token,
progressHandler);
So question - how to make it upload files of any size, redefine timeout(currently 120s) and track progress on both Windows and WP81?
UPD:
I found the reason of 2 mins timeout here:
After the connection has been established, an HTTP request message that has not received a response within two minutes is aborted.
Is it normal for PUT request?

Cannot read JSON file - FileNotFoundException

I was following tutorial on this page http://channel9.msdn.com/Series/Windows-Phone-8-1-Development-for-Absolute-Beginners/Part-22-Storing-and-Retrieving-Serialized-Data because I want my app to store data in JSON file and then read it back. 2 things about the tutorial:
I press write button - works fine, then press read button and it also works, however, I close down win phone 8.1 emulator, open it again, press read button and I got the An exception of type 'System.IO.FileNotFoundException'exception! Why is that, I should have the file already on disk from previously running the app ? Or is does it get erased when I close down emulator ? Also I looked for the specified file on disk and cannot find it ! Any help ?
private const string JSONFILENAME = "data.json";
private async Task readJsonAsync()
{
string content = String.Empty;
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);
using (StreamReader reader = new StreamReader(myStream))
{
content = await reader.ReadToEndAsync();
}
resultTextBlock.Text = content;
}
private async Task writeJsonAsync()
{ // Notice that the write is ALMOST identical ... except for the serializer.
var myCars = buildObjectGraph();
var serializer = new DataContractJsonSerializer(typeof(List<Car>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
JSONFILENAME,
CreationCollisionOption.ReplaceExisting))
{
serializer.WriteObject(stream, myCars);
}
resultTextBlock.Text = "Write succeeded";
}
When you close the Emulator its state is is not preserved, meaning that the apps that you tested are not there when you restart the emulator. Therefore, VS will make a new install when you open up the emulator again.
The same happens when you do a rebuild of your project. Then, VS will remove the app from the emulator and reinstall it from scratch. This in turn will also result in loosing your JSON file.
When you want to make sure that your data is preserved then don't close the emulator and just use Build from within VS (VS decides from time to time to rebuild your app though).
On order to test your app more properly I suggest you have a look at the Windows Phone Power Tools (http://wptools.codeplex.com/). There you can explicitly choose to install or update a given XAP package.

ExpressionPlayer does not play Azure Smooth Streaming Source

I'm writing a VOD solution. For some time I have been working with the SSME:SmoothStreamingMediaElement successfully for testing and now I would like to utilise one of the Expression Players.
I'm using Azure Media Services, specifically Smooth Streaming. While these work fine in SSME I can't get them to work with an ExpressionPlayer. I don't know why.
I'm now at a point where I'm hard coding a Uri to try and get this to work as below:
void dataConectorPopulatePlaylistDownloadComplete(MemoryStream returnData, EventArgs e)
{
<snip>
var myPlaylist = new ExpressionMediaPlayer.Playlist();
var playlistItem = new PlaylistItem();
playlistItem.MediaSource = new Uri("http://xxxxxms1.origin.mediaservices.windows.net/b78750fc-9e2f-448c-86e3-d5de084791ea/GOPR0009.MP4-b2d2b578-3560-42c6-9927-2a791f395e19.ism/manifest",UriKind.Absolute);
playlistItem.IsAdaptiveStreaming = true;
myPlaylist.Items.Add(playlistItem);
SmoothPlayerStreaming.Playlist = myPlaylist;
<snip>
}
Using the above returns 404 not found in the player video playback window.
This is a valid URL and a valid Smooth Streaming Uri. Using this exact same Uri in a SSME control works fine.
What have I done wrong?
The ExpressionMediaPlayer class makes a hidden call to the ClientBin/SmoothStreaming.xap file. If you don't have it there - you should add it.
Here is the link to the blog post where you can download the xap file and source code of the expression player. Direct link
After you download the archive above, you can find this file at this path: EE4SP1SilverlightDefaultWithAudioVolume.zip\Templates\Silverlight Default -- with Audio Volume On Start\SmoothStreaming.xap
If it still doesn't work, you should replace the MediaPlayer.dll by projects from the archive. You need to add (Add -> Existing Project) 3 projects from the SharedV4SP1 folder: MediaPlayer, OfflineShared, PlugInMSSCtrl.
I've already tested your code in my application and it started to work after I have copied the xap file and replaced the dll-reference by existing projects.

Moving XML file to be hosted

Please be gentle. I am not a terribly proficient developer!
So this is the last thing I need to fix in my Windows Phone 7.5 app before I consider it done. In short, the data sources on the menus are driven by an xml file. That file is stored locally with the app. I would like to store that file somewhere on the Internet). Currently if I need to make a change to this xml file, I have to re-submit the app to the Marketplace taking about 5 days before the change goes live. How 2003 of me.
So I can't figure out what they are expecting returned in the code below. I've hacked away and it always give some error I don't understand.
I've set the filename variable to a URL of a file on the Internet but apparently that is not supported. So I either need a new way for that whole section to work or a way to convert the hosted filename converted into something that will work.
private static void FirstLaunch()
{
// On the first launch, just add everything from the OPML file
string filename;
//This file should really be hosted on the Internet somewhere.
filename = "/RSSReader;component/LyncNews-opml.xml";
StreamResourceInfo xml = App.GetResourceStream(new Uri(filename, UriKind.Relative));
List<RSSPage> rssPages = ParseOPML(xml.Stream);
}
You can set it to a URL, but you'll need to download the content, not through App.GetResourceStream. Try WebClient, it's easy and simple.
A simple usage:
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Client_DownloadStringCompleted);
Uri token = new Uri("your url");
client.DownloadStringAsync(token);
and handle xml parsing in the event.

Silverlight Loading Reference Data On Demand from a 'dumb' server

I have a text file with a list of 300,000 words and the frequency with wich they occur. Each line is in the format Word:FequencyOfOccurence.
I want this information to be accessible from within the C# code. I can't hard code the list since it is too long, and I'm not sure how to go about accessing it from a file on the server. Ideally I'd ideally like the information to be downloaded only if it's used (To save on bandwidth) but this is not a high priority as the file is not too big and internet speeds are always increasing.
It doesn't need to be useable for binding.
The information does not need to be editable once the project has been built.
Here is another alternative. Zip the file up and stick it in the clientBin folder next to the apllication XAP. Then at the point in the app where the content is needed do something like this:-
public void GetWordFrequencyResource(Action<string> callback)
{
WebClient client = new WebClient();
client.OpenReadAsync += (s, args) =>
{
try
{
var zipRes = new StreamResourceInfo(args.Result, null)
var txtRes = Application.GetResourceStream(zipRes, new Uri("WordFrequency.txt", UriKind.Relative));
string result = new StreamReader(txtRes.Stream).ReadToEnd();
callback(result);
}
catch
{
callback(null); //Fetch failed.
}
}
client.OpenReadAsync(new Uri("WordFrequency.zip", UriKind.Relative"));
}
Usage:-
var wordFrequency = new Dictionary<string, int>();
GetWordFrequencyResource(s =>
{
// Code here to burst string into dictionary.
});
// Note code here is asynchronous with the building of the dictionary don't attempt to
// use the dictionary here.
The above code allows you to store the file in an efficient zip format but not in the XAP itself. Hence you can download it on demand. It makes use of the fact that a XAP is a zip file so Application.GetResourceStream which is designed to pull resources from XAP files can be used on a zip file.
BTW, I'm not actually suggesting you use a dictionary, I'm just using a dictionary as simple example. In reality I would imagine the file is in sorted order. If that is the case you could use a KeyValuePair<string, int> for each entry but create a custom collection type that holds them in an array or List and then use some Binary search methods to index into it.
Based on your comments, you could download the word list file if you are required to have a very thin server layer. The XAP file containing your Silverlight application is nothing more than a ZIP file with all the referenced files for your Silverlight client layer. Try adding the word list as content that gets compiled into the XAP and see how big the file gets. Text usually compresses really well. In general, though, you'll want to be friendly with your users in how much memory your application consumes. Loading a huge text file into memory, in addition to everything else you need in your app, may untimately make your app a resource hog.
A better practice, in general, would be to call a web service. The service could would perform whatever look up logic you need. Here's a blog post from a quick search that should get you started: (This was written for SL2, but should apply the same for SL3.)
Calling web services with Silverlight 2
Even better would be to store your list in a SQL Server. It will be much easier and quicker to query.
You could create a WCF service on the server side that will send the data to the Silverlight application. Once you retrieve the information you could cache it in-memory inside the client. Here's an example of calling a WCF service method from Silverlight.
Another possibility is to embed the text file into the Silverlight assembly that is deployed to the client:
using (var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("namespace.data.txt"))
using (var reader = new StreamReader(stream))
{
string data = reader.ReadToEnd();
// Do something with the data
}

Categories

Resources