Uploadare/Scaricare files da Windows Phone 8 su Skydrive

Una delle features a mio avviso che è poco sfruttata all’interno delle app Windows Phone è quella di poter uploadare/scaricare files dallo smartphone sul cloud (nel caso specifico Skydrive). A cosa potrebbe servire? Beh, immaginatevi un’app di qualsiasi tipo, che abbia impostazioni, files, fotografie, audio, qualsiasi contenuto. Se comprate un altro telefono Windows Phone, oppure se resettate il telefono, quei contenuti li perdete, perchè erano inclusi nell’Isolated Storage di quell’app specifica. Esempio concreto: immaginate Rowi, uno dei client Twitter più importanti ed utilizzati: voi lo acquistate la prima volta, lo impostate con i vostri account, e regolate le impostazioni come piacciono a voi. Poi sostituite il telefono, oppure resettate l’attuale, e perdete tutto quanto, e siete costretti a reimpostare daccapo tutto quanto. Oppure un gioco come Angry Birds: tutte le volte che lo installate, non c’è alcun modo per recuperare le partite che avevate. E così via, in generale il discorso si può applicare a bene o male tutte le app Windows Phone.

Grazie al Live Connect SDK, possiamo sfruttare le potenzialità del cloud Skydrive all’interno delle nostre app Windows Phone. Quindi: all’interno di una nostra app possiamo:

  • inviare su Skydrive qualsiasi files che abbia un senso (impostazioni, file di dati dell’utente, etc.)
  • scaricare i files per recuperare i vecchi contenuti

Il livello base l’ha già spiegato l’amico Matteo Pagani, in questo post sul suo blog in inglese. Qui viene spiegato quali reference aggiungere al progetto, come aggiungere il pulsante di login, e come inviare/scaricare files. Il tutto riguarda Windows Phone 7, ma va benissimo anche per Windows Phone 8: possiamo però sfruttare qualche miglioria, che ai tempi della stesura del post non esisteva (esempio: possiamo utilizzare le tecniche async/await, evitando le varie callback che complicano la leggibilità del codice). Però il 95% va più che bene.

Quello che non mi piace è che quel codice salva i files alla root di Skydrive.

Questo comporta che l’utente potrebbe inavvertitamente cancellare i files, perchè non li riconosce. Oppure potrebbe capitare che più app vadano a scrivere sugli stessi files: cosa un po’ assurda da pensare, ma mica tanto: non è poi così assurdo pensare che le impostazioni di un’app vengano salvate in un file chiamato Settings.xml, tramite serializzazione/deserializzazione. E quindi è assolutamente una cosa da evitare (almeno io la penso così).

La conclusione di tutto ciò è che si comincia a lavorare con i folder su SkyDrive.

Quindi, supponiamo: stiamo sviluppando un’app chiamato “La mia bella app”, che intenda inviare/scaricare files su Skydrive, dentro un folder chiamato “La mia bella app”. Cosa si realizza tutto ciò? Io mi sono inventato questo metodo helper, che in pratica fa una cosa molto semplice: dopo che ha ottenuto l’accesso al vostro account Skydrive, legge la root, e scansiona tutte le directory presenti, alla ricerca di quella che si chiama “La mia bella app”. Se la trova, ne recupera il Folder ID; se non la trova, la crea e ne recupera il Folder ID. Tramite questo Folder ID, possiamo utilizzare gli stessi metodi spiegati da Matteo Pagani nel suo post, solo che invece di lavorare alla root, lavoriamo all’interno del nostro folder.

private async Task EnsureSkyDriveFolderExists(string folderName)
{
    this.SkyDriveOperationWaiting.IsIndeterminate = true;
    this.SkyDriveOperationDescription.Text = "Controllo cartella su SkyDrive";
    var response1 = await client.GetAsync("me/skydrive/files");
    List<object> items = response1.Result["data"] as List<object>;

    foreach (object item in items)
    {
        IDictionary<string, object> directories = item as IDictionary<string, object>;

        if (directories["name"].ToString() == folderName)
        {
            this.SkyDriveOperationDescription.Text = "Cartella su SkyDrive ok";
            ApplicationContext.Instance.FolderIdSkyDrive = directories["id"].ToString();
            App.SaveSettings();
            return;
        }
    }

    this.SkyDriveOperationDescription.Text = "Creazione cartella su SkyDrive";
    
    var folderData = new Dictionary<string, object>();
    folderData.Add("name", folderName);

    var response4 = await client.PostAsync("me/skydrive", folderData);
    ApplicationContext.Instance.FolderIdSkyDrive = response4.Result["id"].ToString();
    App.SaveSettings();

    this.SkyDriveOperationDescription.Text = "Cartella su SkyDrive ok";
}

 

Il codice va un po’ ripulito, perchè ci sono riferimenti a controllo sulla UI, come ProgressBar e TextBlock, che mantengono informato l’utente su ciò che sta accadendo. La logica è questa:

  1. Grazie al path “me/skydrive/files” recupero l’elenco di file e directory presenti alla root di Skydrive
  2. Ottenuto l’elenco, lo ciclo alla ricerca della directory chiamata “folderName”, che è una stringa che arriva in input a questo metodo
  3. Se la trova, salva il Folder ID da qualche parte (io la memorizzo in una classe singleton AppicationContext), salva le nuove impostazioni ed esce
  4. Se il folder non viene trovato, allora viene creato (metodo PostAsync), viene recuperato il Folder ID, il tutto viene salvato e si esce dal metodo

Una precisazione è d’obbligo.

Teoricamente parlando, il codice potrebbe salvarsi il Folder ID al momento della prima generazione della cartella, in modo tale che si eviterebbe ogni volta di controllare se esiste oppure no. Sbagliato! Ricordiamoci che l’utente potrebbe cancellare il folder su SkyDrive (attraverso il sito, oppure attraverso una qualsiasi app Windows Phone, Windows 8, etc.). Quindi è importante andare a controllare l’esistenza del folder, ogni volta.

Una volta che si esce da questo metodo, si è pronti per inviare files all’interno di questo folder:

await client.UploadAsync(ApplicationContext.Instance.FolderIdSkyDrive, s,
    stream, OverwriteOption.Overwrite);

 

Il primo parametro del metodo UploadAsync è proprio il Folder ID che abbiamo ottenuto. Matteo nel suo post indicava “me/skydrive”, per uploadare nella root. Indicando il Folder ID, i files vengono uploadati all’interno del nostro folder.

Scaricare un files è un filo più complesso. Con questo metodo:

var response2 = await client.GetAsync(
    string.Format("{0}/files",
    ApplicationContext.Instance.FolderIdSkyDrive));

recuperiamo l’elenco dei files contenuti nel folder indicato da Folder ID. Una volta che abbiamo l’elenco, dobbiamo ciclare la lista e scaricare solo quello che ci interessa (oppure banalmente implementare un foreach per scaricarli tutti quanti). Per scaricare un file, si utilizza questo metodo:

var response3 = await client.DownloadAsync
    (string.Format("{0}/content",
    fileId));

Il risultato di tutto questo giro di codice è che sulo Skydrive del nostro utente ci sarà un folder chiamato come vogliamo noi, con tutto ciò che abbiamo deciso di uploadare. Se abbiamo dato un nome chiaro al folder, l’utente lo riconoscerà senza problemi: potrebbe decidere di cancellarlo oppure no (questo è chiaramente al di fuori del nostro controllo, per cui non ci dobbiamo fare troppo affidamento).

Send to Kindle

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.