API Storage

Quasi ogni aspetto dello sviluppo delle app implica l'invio o la ricezione di dati. In fase di avvio con le basi, dovresti usare un framework MVC per progettare e implementare la tua app in modo che sono completamente separati da quelli dell'app su tali dati (vedi Architettura di MTV).

Devi anche pensare a come vengono gestiti i dati quando l'app è offline (vedi Prima offline). Questo documento presenta brevemente le opzioni di archiviazione per l'invio, la ricezione e il salvataggio dei dati localmente; il La parte restante del documento mostra come utilizzare le API File System e Sync File System di Chrome (vedi anche API fileSystem e API syncFileSystem).

Opzioni di archiviazione

Le app in pacchetto utilizzano diversi meccanismi per inviare e ricevere dati. Per i dati esterni (risorse, pagine web), devi conoscere il Criterio di sicurezza del contenuto (CSP). Simile a Chrome Per le estensioni, puoi usare XMLHttpRequests multiorigine per comunicare con i server remoti. Tu è anche possibile isolare le pagine esterne, in modo che il resto dell'app sia sicuro (vedi Incorporare siti web esterni). pagine).

Quando salvi i dati localmente, puoi utilizzare l'API Chrome Storage per salvare piccole quantità di stringhe e IndexedDB per salvare i dati strutturati. Con IndexedDB, puoi rendere persistenti gli oggetti JavaScript in una e utilizzare gli indici dell'archivio per eseguire query sui dati (per saperne di più, consulta la sezione Semplici cose da fare di HTML5 Rock) Elenco tutorial). Per tutti gli altri tipi di dati, come i dati binari, usa lo strumento File system e sincronizzazione API di file system.

Le API Filesystem e Sync Filesystem di Chrome estendono l'API HTML5 FileSystem. Con il API Filesystem, le app possono creare, leggere, navigare e scrivere in una sezione sandbox del file system locale. Ad esempio, un'app di condivisione di foto può utilizzare l'API Filesystem per leggere e scrivere foto selezionate da un utente.

Con l'API Sync Filesystem di Chrome, le app possono salvare e sincronizzare i dati sul Google Drive di un utente per gli stessi dati possono essere disponibili tra diversi client. Ad esempio, un testo basato su cloud Editor può sincronizzare automaticamente i nuovi file di testo con l'account Google Drive di un utente. Quando un utente apre l'editor di testo in un nuovo client, Google Drive invia i nuovi file di testo a quell'istanza di l'editor di testo.

Utilizzo dell'API Chrome Filesystem

Aggiunta dell'autorizzazione del file system in corso...

Per utilizzare l'API File System di Chrome, devi aggiungere "fileSystem" l'autorizzazione per il manifest, che puoi ottenere dall'utente per archiviare dati permanenti.

"permissions": [
  "...",
  "fileSystem"
]

Opzioni utente per la selezione dei file

Gli utenti si aspettano di selezionare i file come hanno sempre fatto. Come minimo, si aspettano di ricevere file e strumento di selezione file standard. Se la tua app fa un uso intensivo della gestione dei file, dovresti anche implementare il trascinamento (vedi sotto e vedi anche Trascinamento HTML5 nativo).

Ottenere il percorso di un fileEntry

Per ottenere il percorso completo del file selezionato dall'utente, fileEntry, chiama getDisplayPath():

function displayPath(fileEntry) {
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    console.log(path)
  });
}

Implementazione del trascinamento

Se devi implementare la selezione mediante trascinamento, utilizza il controller del file con trascinamento (dnd.js) in l'esempio filesystem-access è un buon punto di partenza. Il controller crea una voce relativa al file da DataTransferItem tramite trascinamento. In questo esempio, fileEntry è impostato sul primo l'elemento perso.

var dnd = new DnDFileController('body', function(data) {
  var fileEntry = data.items[0].webkitGetAsEntry();
  displayPath(fileEntry);
});

Lettura di un file

Il codice seguente apre il file (di sola lettura) e lo legge come testo utilizzando un oggetto FileReader. Se il file non esiste, viene generato un errore.

var chosenFileEntry = null;

chooseFileButton.addEventListener('click', function(e) {
  chrome.fileSystem.chooseEntry({type: 'openFile'}, function(readOnlyEntry) {

    readOnlyEntry.file(function(file) {
      var reader = new FileReader();

      reader.onerror = errorHandler;
      reader.onloadend = function(e) {
        console.log(e.target.result);
      };

      reader.readAsText(file);
    });
    });
});

Scrittura di un file

I due casi d'uso comuni per scrivere un file sono "Salva" e "Salva con nome". Il seguente codice crea un'istanza writableEntry dal chosenFileEntry di sola lettura e vi scrive il file selezionato.

 chrome.fileSystem.getWritableEntry(chosenFileEntry, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = callback;

    chosenFileEntry.file(function(file) {
      writer.write(file);
    });
  }, errorHandler);
});

Il seguente codice crea un nuovo file con il comando "Salva con nome" e scrive il nuovo blob nel utilizzando il metodo writer.write().

chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry) {
    writableFileEntry.createWriter(function(writer) {
      writer.onerror = errorHandler;
      writer.onwriteend = function(e) {
        console.log('write complete');
      };
      writer.write(new Blob(['1234567890'], {type: 'text/plain'}));
    }, errorHandler);
});

Utilizzo dell'API Chrome Sync Filesystem

Utilizzando l'archiviazione di file sincronizzabile, gli oggetti di dati restituiti possono essere utilizzati come file system offline nell'API FileSystem, ma con la relativa sincronizzazione aggiuntiva (e automatica) su Google Drive.

Aggiunta dell'autorizzazione di accesso al file system di sincronizzazione

Per utilizzare l'API Sync Filesystem di Chrome, devi aggiungere "syncFileSystem" l'autorizzazione per per poter ottenere l'autorizzazione dell'utente per archiviare e sincronizzare i dati permanenti.

"permissions": [
  "...",
  "syncFileSystem"
]

Avvio dell'archiviazione dei file sincronizzabili

Per avviare l'archiviazione dei file sincronizzabili nella tua app, chiama semplicemente syncFileSystem.requestFileSystem. Questo metodo restituisce un file system sincronizzabile supportato da Google Drive, ad esempio:

chrome.syncFileSystem.requestFileSystem(function (fs) {
   // FileSystem API should just work on the returned 'fs'.
   fs.root.getFile('test.txt', {create:true}, getEntryCallback, errorCallback);
});

Informazioni sullo stato di sincronizzazione dei file

Utilizza syncFileSystem.getFileStatus per ottenere lo stato di sincronizzazione di un file corrente:

chrome.syncFileSystem.getFileStatus(entry, function(status) {...});

I valori dello stato di sincronizzazione dei file possono essere uno dei seguenti: 'synced', 'pending' o 'conflicting'. Sincronizzato significa che il file è completamente sincronizzato. non ci sono modifiche locali in attesa che non sono state sincronizzati con Google Drive. Tuttavia, possono esserci modifiche in attesa su Google Drive che non sono stati ancora recuperati.

'In attesa' indica che il file ha modifiche in attesa non ancora sincronizzate su Google Drive. Se l'app è eseguite online, le modifiche locali vengono (quasi) immediatamente sincronizzate con Google Drive, L'evento syncFileSystem.onFileStatusChanged viene attivato con lo stato 'synced' (vedi di seguito per ulteriori dettagli).

Quando lo stato di un file cambia in syncFileSystem.onFileStatusChanged viene attivato 'conflicting'. 'In conflitto' significa che esistono modifiche in conflitto sia per lo spazio di archiviazione locale Google Drive. Un file può essere in questo stato solo se il criterio di risoluzione dei conflitti è impostato su 'manual'. Il criterio predefinito è 'last_write_win' e i conflitti vengono risolti automaticamente entro il giorno è una semplice norma ultima scrittura/scrittura. Il criterio di risoluzione dei conflitti del sistema può essere modificato syncFileSystem.setConflictResolutionPolicy.

Se il criterio di risoluzione dei conflitti è impostato su 'manual' e un file restituisce lo stato 'conflicting', l'app può ancora leggere e scrivere il file come file offline locale, ma le modifiche non vengono sincronizzate e il file verrà mantenuto scollegato dalle modifiche remote apportate su altri client finché il conflitto non risolto. Il modo più semplice per risolvere un conflitto è eliminare o rinominare la versione locale del file. Questa operazione forza la sincronizzazione della versione remota, lo stato in conflitto viene risolto L'evento onFileStatusChanged viene attivato con lo stato 'synced'.

In attesa delle modifiche dello stato sincronizzato

L'evento syncFileSystem.onFileStatusChanged viene attivato quando lo stato di sincronizzazione di un file viene modificato. Ad esempio, supponiamo che un file abbia modifiche in attesa e che si trovi nello stato "In attesa" stato. L'app potrebbe essere stata offline, per cui la modifica sta per essere sincronizzata. Quando il servizio di sincronizzazione rileva in attesa della modifica locale e carica la modifica su Google Drive, il servizio attiva onFileStatusChanged evento con i seguenti valori: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }.

Analogamente, indipendentemente dalle attività locali, il servizio di sincronizzazione può rilevare le modifiche un altro client e scarica le modifiche da Google Drive allo spazio di archiviazione locale. Se il telecomando della modifica riguarda l'aggiunta di un nuovo file, viene attivato un evento con i seguenti valori: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }.

Se il lato locale e quello remoto hanno modifiche in conflitto per lo stesso file e se il conflitto il criterio di risoluzione è impostato su 'manual', lo stato del file viene modificato in conflicting, è dal servizio di sincronizzazione e non sarà sincronizzato finché il conflitto non sarà risolto. In questo se viene attivato un evento con i seguenti valori: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }.

Puoi aggiungere un listener per questo evento che risponda a eventuali cambiamenti di stato. Ad esempio, L'app Chrome Music Player ascolta tutta la nuova musica sincronizzata da Google Drive, ma non ancora. importati nello spazio di archiviazione locale dell'utente su un determinato client. La musica trovata viene sincronizzata con questo cliente:

chrome.syncFileSystem.onFileStatusChanged.addListener(function(fileInfo) {
  if (fileInfo.status === 'synced') {
    if (fileInfo.direction === 'remote_to_local') {
      if (fileInfo.action === 'added') {
        db.add(fileInfo.fileEntry);
      } else if (fileInfo.action === 'deleted') {
        db.remove(fileInfo.fileEntry);
      }
    }
  }
});

Controllo dell'utilizzo dell'API in corso...

Per verificare la quantità di dati utilizzati dall'API, esegui una query nella directory sandbox locale dell'app o nella byte di utilizzo restituiti da syncFileSystem.getUsageAndQuota:

chrome.syncFileSystem.getUsageAndQuota(fileSystem, function (storageInfo) {
   updateUsageInfo(storageInfo.usageBytes);
   updateQuotaInfo(storageInfo.quotaBytes);
});

Puoi anche controllare lo spazio di archiviazione del servizio di backend di sincronizzazione dell'utente (su Google Drive). I file sincronizzati sono salvato in una cartella nascosta di Google Drive, Chrome Syncable FileSystem. La cartella non verrà visualizzata in da "Il mio Drive" ma è possibile accedervi cercando il nome della cartella nella casella di ricerca. Tieni presente che non è garantito che il layout delle cartelle remote rimanga compatibile con le versioni precedenti tra le release).