واجهات برمجة التطبيقات للتخزين

يتضمن كل جانب من جوانب تطوير التطبيق تقريبًا أحد عناصر إرسال البيانات أو استلامها. بدءًا من الأساسيات، يجب استخدام إطار عمل MVC لمساعدتك في تصميم تطبيقك وتنفيذه حتى تكون البيانات منفصلة تمامًا عن رأي التطبيق في تلك البيانات (راجع بنية MVC).

عليك أيضًا التفكير في كيفية التعامل مع البيانات عندما يكون تطبيقك بلا اتصال بالإنترنت (راجع بلا اتصال بالإنترنت أولاً). يقدم هذا المستند باختصار خيارات التخزين لإرسال البيانات واستقبالها وحفظها محليًا، ويوضح لك الجزء المتبقي من المستند كيفية استخدام واجهات برمجة التطبيقات لنظام الملفات ومزامنة الملفات في Chrome (يمكنك الاطلاع أيضًا على واجهة برمجة التطبيقات fileSystem وواجهة برمجة التطبيقات syncFileSystem).

خيارات التخزين

تستخدم التطبيقات المجمّعة العديد من الآليات المختلفة لإرسال البيانات واستلامها. بالنسبة إلى البيانات الخارجية (الموارد وصفحات الويب)، يجب أن تكون على دراية بسياسة أمان المحتوى (CSP). وعلى غرار إضافات Chrome، يمكنك استخدام XMLHttpRequests من مصادر متعددة للاتصال بالخوادم البعيدة. يمكنك أيضًا عزل الصفحات الخارجية حتى يكون باقي التطبيق آمنًا (راجع تضمين صفحات الويب الخارجية).

عند حفظ البيانات على الجهاز، يمكنك استخدام Chrome Storage API لحفظ كميات صغيرة من بيانات السلسلة وIndexedDB لحفظ البيانات المنظَّمة. باستخدام IndexedDB، يمكنك الاحتفاظ بكائنات JavaScript في مخزن كائنات واستخدام فهارس المتجر للاستعلام عن البيانات (لمزيد من المعلومات، يمكنك الاطلاع على الدروس البسيطة لقائمة المهام في HTML5 Rock). بالنسبة إلى جميع أنواع البيانات الأخرى، مثل البيانات الثنائية، استخدِم واجهات برمجة تطبيقات Filesystem وSync Filesystem.

تعمل واجهات برمجة التطبيقات Filesystem وSync Filesystem API في Chrome على توسيع واجهة برمجة تطبيقات HTML5 FileSystem. باستخدام واجهة برمجة التطبيقات Filesystem API في Chrome، يمكن للتطبيقات إنشاء قسم في وضع الحماية لنظام الملفات المحلي للمستخدم وقراءته والتنقّل فيه والكتابة فيه. على سبيل المثال، يمكن لتطبيق مشاركة الصور استخدام واجهة برمجة التطبيقات Filesystem لقراءة وكتابة أي صور يختارها المستخدم.

باستخدام واجهة برمجة تطبيقات Sync Filesystem API في Chrome، يمكن للتطبيقات حفظ البيانات ومزامنتها في Google Drive للمستخدم حتى تتوفّر البيانات نفسها على برامج مختلفة. على سبيل المثال، يمكن لتطبيق محرر النصوص المستند إلى السحابة الإلكترونية مزامنة الملفات النصية الجديدة مع حساب المستخدم على Google Drive تلقائيًا. عندما يفتح المستخدم محرر النصوص في برنامج جديد، يرسل Google Drive الملفات النصية الجديدة إلى مثيل محرر النصوص.

استخدام واجهة برمجة تطبيقات نظام ملفات Chrome

إضافة إذن نظام الملفات

لاستخدام واجهة برمجة التطبيقات File System API في Chrome، يجب إضافة إذن "fileSystem" إلى البيان، بحيث يمكنك الحصول على إذن من المستخدم لتخزين البيانات الدائمة.

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

خيارات المستخدم لاختيار الملفات

يتوقع المستخدمون اختيار الملفات بالطريقة نفسها التي يختارونها دائمًا، لذا يتوقعون على الأقل توفُّر زر "اختيار ملف" ومحدِّد عادي للملفات. إذا كان تطبيقك يستخدم تسليمًا سريعًا للملفات، عليك أيضًا تنفيذ السحب والإفلات (انظر أدناه واطلع أيضًا على السحب والإفلات الأصلي بتنسيق HTML5).

الحصول على مسار إدخال ملف

للحصول على المسار الكامل للملف الذي اختاره المستخدم، fileEntry، استدعِ getDisplayPath():

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

تنفيذ السحب والإفلات

إذا كنت بحاجة إلى تنفيذ اختيار السحب والإفلات، تُعدّ وحدة التحكم في الملفات من خلال السحب والإفلات (dnd.js) في النموذج filesystem-access نقطة بداية جيدة. تنشئ وحدة التحكّم إدخال ملف من DataTransferItem عن طريق السحب والإفلات. في هذا المثال، يتم ضبط fileEntry على أول عنصر تم إسقاطه.

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

قراءة ملف

يفتح الرمز التالي الملف (للقراءة فقط) ويقرأه كنص باستخدام كائن FileReader. في حال عدم وجود الملف، يتم عرض خطأ.

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);
    });
    });
});

كتابة ملف

هناك حالتا استخدام شائعتان لكتابة ملف هما "حفظ" و "حفظ باسم". ينشئ الرمز التالي writableEntry من chosenFileEntry للقراءة فقط ويكتب الملف المحدَّد إليه.

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

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

تنشئ التعليمة البرمجية التالية ملفًا جديدًا مع وظيفة "Save as" (حفظ باسم) وتكتب كائن ثنائي النقاط الجديد في الملف باستخدام الطريقة 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);
});

استخدام واجهة برمجة تطبيقات Chrome Sync Filesystem API

باستخدام مساحة تخزين الملفات القابلة للمزامنة، يمكن تشغيل كائنات البيانات المعروضة بالطريقة نفسها التي يتم بها تشغيل أنظمة الملفات المحلية بلا اتصال بالإنترنت في FileSystem API، ولكن مع المزامنة المضافة (والتلقائية) لتلك البيانات مع Google Drive.

جارٍ إضافة إذن نظام ملفات المزامنة

لاستخدام واجهة برمجة تطبيقات Sync Filesystem API في Chrome، يجب إضافة إذن "syncFileSystem" إلى البيان، بحيث يمكنك الحصول على إذن من المستخدم لتخزين البيانات الدائمة ومزامنتها.

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

بدء تخزين الملفات القابلة للمزامنة

لبدء تخزين الملفات القابلة للمزامنة في تطبيقك، ما عليك سوى استدعاء syncFileSystem.requestFileSystem. تعرض هذه الطريقة نظام ملفات قابل للمزامنة والمستند إلى Google Drive، على سبيل المثال:

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

لمحة عن حالة مزامنة الملفات

استخدِم syncFileSystem.getFileStatus للحصول على حالة المزامنة لملف حالي:

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

يمكن أن تكون قيم حالة مزامنة الملفات إحدى القيم التالية: 'synced' أو 'pending' أو 'conflicting'. تعني الحالة "تمت المزامنة" أن الملف تمت مزامنته بالكامل؛ وليست هناك تغييرات محلية معلقة لم تتم مزامنتها مع Google Drive. ومع ذلك، يمكن أن تكون هناك تغييرات معلّقة من جانب Google Drive لم يتم جلبها بعد.

تعني الحالة "في انتظار المراجعة" أنّ الملف يحتوي على تغييرات معلّقة لم تتم مزامنتها بعد مع Google Drive. إذا كان التطبيق قيد التشغيل على الإنترنت، تتم مزامنة التغييرات المحلية (تقريبًا) مع Google Drive، ويتم تنشيط الحدث syncFileSystem.onFileStatusChanged بالحالة 'synced' (انظر أدناه لمزيد من التفاصيل).

يتم تنشيط syncFileSystem.onFileStatusChanged عندما تتغير حالة الملف إلى 'conflicting'. تعني الحالة "تعارض" أن هناك تغييرات متعارضة في كل من مساحة التخزين المحلية وGoogle Drive. ولا يمكن أن يكون الملف بهذه الحالة إلا في حال ضبط سياسة حل التعارض على 'manual'. إنّ السياسة التلقائية هي 'last_write_win'، ويتم حلّ التعارضات تلقائيًا من خلال سياسة بسيطة متعلقة بالكتابة الأخيرة. يمكن تغيير سياسة حل التعارضات في النظام من خلال syncFileSystem.setConflictResolutionPolicy.

في حال ضبط سياسة حل التعارض على 'manual' وكان الملف يؤدي إلى حالة 'conflicting'، سيظل بإمكان التطبيق قراءة الملف وكتابته كملف محلي بلا اتصال بالإنترنت، ولكن لن تتم مزامنة التغييرات، وسيبقى الملف منفصلاً عن التغييرات عن بُعد التي يتم إجراؤها على البرامج الأخرى حتى يتم حل التضارب. أسهل طريقة لحل التعارض هي حذف الإصدار المحلي للملف أو إعادة تسميته. ويؤدي ذلك إلى فرض مزامنة النسخة البعيدة، وحلّ حالة التعارض، وتنشيط حدث onFileStatusChanged بالحالة 'synced'.

رصد التغييرات في الحالة المتزامنة

يتم تنشيط الحدث syncFileSystem.onFileStatusChanged عندما تتغير حالة المزامنة لأحد الملفات. على سبيل المثال، لنفترض أنّ الملف يحتوي على تغييرات معلّقة وهو في حالة "في انتظار المراجعة". قد يكون التطبيق في حالة عدم اتصال بحيث يكون التغيير على وشك المزامنة. عندما ترصد خدمة المزامنة التغيير المحلي المعلّق وتحمّل التغيير إلى Google Drive، تنشِّط الخدمة حدث onFileStatusChanged بالقيم التالية: { fileEntry:a fileEntry for the file, status: 'synced', action: 'updated', direction: 'local_to_remote' }.

وبالمثل، بغض النظر عن الأنشطة المحلية، قد تكتشف خدمة المزامنة التغييرات عن بُعد التي أجراها عميل آخر، وتنزّل التغييرات من Google Drive إلى وحدة التخزين المحلية. إذا كان التغيير عن بُعد يتعلق بإضافة ملف جديد، يتم تنشيط حدث بالقيم التالية: { fileEntry: a fileEntry for the file, status: 'synced', action: 'added', direction: 'remote_to_local' }.

إذا كان هناك تغييرات متعارضة بين كل من الطرفَين المحلي والبعيد للملف نفسه وتم ضبط سياسة حلّ التعارض على 'manual'، سيتم تغيير حالة الملف إلى حالة conflicting، وفصلها عن خدمة المزامنة، ولن تتم مزامنتها حتى يتم حلّ التعارض. وفي هذه الحالة، يتم تنشيط حدث يحتوي على القيم التالية: { fileEntry: a fileEntry for the file, status: 'conflicting', action: null, direction: null }.

يمكنك إضافة مستمع لهذا الحدث للاستجابة لأي تغييرات في الحالة. على سبيل المثال، ينتظر تطبيق Chrome Music Player الاستماع إلى أي موسيقى جديدة تمت مزامنتها من Google Drive، ولكن لم يتم استيرادها بعد إلى وحدة التخزين المحلية للمستخدم على برنامج معين. تتم مزامنة أي موسيقى موجودة مع هذا البرنامج:

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);
      }
    }
  }
});

التحقق من استخدام واجهة برمجة التطبيقات

للتحقّق من مقدار البيانات التي تستخدمها واجهة برمجة التطبيقات، يمكنك الاستعلام عن الدليل المحلي في وضع الحماية الخاص بالتطبيق أو وحدات بايت الاستخدام التي تعرضها syncFileSystem.getUsageAndQuota:

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

يمكنك أيضًا إلقاء نظرة على مساحة تخزين خدمة الواجهة الخلفية للمزامنة لدى المستخدم (في Google Drive). يتم حفظ الملفات التي تمت مزامنتها في مجلد مخفي في Google Drive، وهو Chrome Syncable FileSystem. لن يتم عرض المجلد في قائمة "ملفاتي" ولكن يمكن الوصول إليه بالبحث عن اسم المجلد في مربع البحث. (لاحظ أن تنسيق المجلد البعيد لا يضمن بقاءه متوافقًا مع الأنظمة القديمة بين الإصدارات).