مستقبل PWA وواجهات برمجة التطبيقات الناشئة
تتطور تطبيقات الويب التقدمية باستمرار مع قدرات جديدة تقربها من تجارب التطبيقات الأصلية. في هذا الدرس الأخير، سنستكشف واجهات برمجة تطبيقات الويب المتطورة والاتجاه المستقبلي لـ PWAs.
Project Fugu
Project Fugu هو مبادرة من Google و Microsoft و Intel وشركاء آخرين لجلب قدرات جديدة قوية إلى منصة الويب. الهدف هو تمكين تطبيقات الويب من فعل أي شيء يمكن للتطبيقات الأصلية فعله.
ما هو Project Fugu؟ سُمي على اسم الكلمة اليابانية لسمكة الفوجو، يهدف Project Fugu إلى "توسيع قدرات الويب" مع الحفاظ على الأمان والخصوصية وتحكم المستخدم. تخضع كل واجهة برمجة تطبيقات جديدة لمراجعة أمنية صارمة وتجارب أصلية قبل أن تصبح متاحة.
المبادئ الأساسية
- محوره المستخدم: يجب أن تخدم الميزات احتياجات المستخدم الحقيقية
- آمن افتراضياً: تتطلب جميع واجهات برمجة التطبيقات إذن المستخدم وHTTPS
- تدريجي: تتدهور الميزات بأمان على المنصات غير المدعومة
- معايير مفتوحة: تمر جميع الميزات من خلال توحيد W3C
File System Access API
تسمح واجهة برمجة تطبيقات الوصول إلى نظام الملفات لتطبيقات الويب بقراءة وكتابة الملفات على نظام الملفات المحلي للمستخدم بإذنه.
// Open a file picker and read file
async function openFile() {
try {
// Show file picker
const [fileHandle] = await window.showOpenFilePicker({
types: [
{
description: 'ملفات نصية',
accept: {
'text/plain': ['.txt'],
'text/markdown': ['.md']
}
}
]
});
// Get file contents
const file = await fileHandle.getFile();
const contents = await file.text();
console.log('محتوى الملف:', contents);
return { fileHandle, contents };
} catch (error) {
console.error('خطأ في فتح الملف:', error);
}
}
// Save file
async function saveFile(fileHandle, contents) {
try {
// Create a writable stream
const writable = await fileHandle.createWritable();
// Write contents
await writable.write(contents);
// Close the file
await writable.close();
console.log('تم حفظ الملف بنجاح');
} catch (error) {
console.error('خطأ في حفظ الملف:', error);
}
}
// Save new file (with picker)
async function saveFileAs(contents) {
try {
const fileHandle = await window.showSaveFilePicker({
types: [
{
description: 'ملفات نصية',
accept: { 'text/plain': ['.txt'] }
}
]
});
await saveFile(fileHandle, contents);
return fileHandle;
} catch (error) {
console.error('خطأ في حفظ الملف:', error);
}
}
// Example: Simple text editor
class TextEditor {
constructor() {
this.fileHandle = null;
this.isDirty = false;
}
async open() {
const result = await openFile();
if (result) {
this.fileHandle = result.fileHandle;
this.isDirty = false;
return result.contents;
}
}
async save(contents) {
if (this.fileHandle) {
await saveFile(this.fileHandle, contents);
this.isDirty = false;
} else {
this.fileHandle = await saveFileAs(contents);
}
}
async saveAs(contents) {
this.fileHandle = await saveFileAs(contents);
}
}
حالات الاستخدام: محررات النصوص، محررات الصور، محررات الفيديو، محررات الأكواد، معالجات المستندات، تطبيقات تدوين الملاحظات، مديري ملفات المشاريع.
Web Bluetooth API
تمكّن واجهة برمجة تطبيقات Web Bluetooth من الاتصال بأجهزة Bluetooth منخفضة الطاقة (BLE) مباشرة من تطبيقات الويب.
// Connect to Bluetooth device
async function connectToBluetoothDevice() {
try {
// Request device
const device = await navigator.bluetooth.requestDevice({
filters: [
{ services: ['heart_rate'] }
],
optionalServices: ['battery_service']
});
console.log('الجهاز:', device.name);
// Connect to GATT server
const server = await device.gatt.connect();
// Get service
const service = await server.getPrimaryService('heart_rate');
// Get characteristic
const characteristic = await service.getCharacteristic('heart_rate_measurement');
// Listen for notifications
characteristic.addEventListener('characteristicvaluechanged', event => {
const value = event.target.value;
const heartRate = value.getUint8(1);
console.log('معدل ضربات القلب:', heartRate);
});
await characteristic.startNotifications();
return { device, server, characteristic };
} catch (error) {
console.error('خطأ Bluetooth:', error);
}
}
// Disconnect
function disconnectDevice(server) {
if (server && server.connected) {
server.disconnect();
console.log('تم قطع الاتصال');
}
}
// Example: Fitness tracker integration
class FitnessTracker {
constructor() {
this.device = null;
this.heartRateData = [];
}
async connect() {
const result = await connectToBluetoothDevice();
if (result) {
this.device = result.device;
this.setupHeartRateMonitor(result.characteristic);
}
}
setupHeartRateMonitor(characteristic) {
characteristic.addEventListener('characteristicvaluechanged', event => {
const heartRate = event.target.value.getUint8(1);
this.heartRateData.push({
timestamp: Date.now(),
bpm: heartRate
});
this.onHeartRateUpdate(heartRate);
});
}
onHeartRateUpdate(bpm) {
// Update UI
console.log(`معدل ضربات القلب الحالي: ${bpm} نبضة في الدقيقة`);
}
getAverageHeartRate() {
if (this.heartRateData.length === 0) return 0;
const sum = this.heartRateData.reduce((acc, data) => acc + data.bpm, 0);
return Math.round(sum / this.heartRateData.length);
}
}
حالات الاستخدام: تطبيقات اللياقة، أجهزة مراقبة الصحة، التحكم في أجهزة إنترنت الأشياء، تطبيقات المنزل الذكي، الأجهزة الطبية، ملحقات الألعاب.
Web NFC API
تسمح واجهة برمجة تطبيقات Web NFC بقراءة والكتابة إلى علامات NFC من تطبيقات الويب على أجهزة Android.
// Check NFC support
if ('NDEFReader' in window) {
console.log('Web NFC مدعوم');
}
// Read NFC tags
async function readNFCTag() {
try {
const ndef = new NDEFReader();
await ndef.scan();
console.log('بدأ مسح NFC');
ndef.addEventListener('reading', ({ message, serialNumber }) => {
console.log(`تم اكتشاف علامة NFC: ${serialNumber}`);
for (const record of message.records) {
console.log('نوع السجل:', record.recordType);
console.log('نوع MIME:', record.mediaType);
if (record.recordType === 'text') {
const textDecoder = new TextDecoder(record.encoding);
const text = textDecoder.decode(record.data);
console.log('النص:', text);
}
}
});
ndef.addEventListener('readingerror', () => {
console.error('خطأ في قراءة NFC');
});
} catch (error) {
console.error('خطأ NFC:', error);
}
}
// Write to NFC tag
async function writeNFCTag(text) {
try {
const ndef = new NDEFReader();
await ndef.write({
records: [
{
recordType: 'text',
data: text
},
{
recordType: 'url',
data: 'https://example.com'
}
]
});
console.log('تمت كتابة علامة NFC بنجاح');
} catch (error) {
console.error('فشلت الكتابة:', error);
}
}
// Example: Digital business card
class DigitalBusinessCard {
async shareViaNFC() {
const cardData = {
name: 'أحمد محمد',
title: 'مطور أول',
email: 'ahmed@example.com',
phone: '+966-555-0123',
website: 'https://ahmeddev.com'
};
const vCard = this.generateVCard(cardData);
try {
const ndef = new NDEFReader();
await ndef.write({
records: [{
recordType: 'mime',
mediaType: 'text/vcard',
data: new TextEncoder().encode(vCard)
}]
});
console.log('تمت مشاركة بطاقة العمل عبر NFC');
} catch (error) {
console.error('فشلت مشاركة NFC:', error);
}
}
generateVCard(data) {
return `BEGIN:VCARD
VERSION:3.0
FN:${data.name}
TITLE:${data.title}
EMAIL:${data.email}
TEL:${data.phone}
URL:${data.website}
END:VCARD`;
}
}
Idle Detection API
تسمح واجهة برمجة تطبيقات الكشف عن الخمول باكتشاف متى يكون المستخدم خاملاً (لا يتفاعل مع الجهاز).
// Check idle state
async function setupIdleDetection() {
try {
// Request permission
const permission = await IdleDetector.requestPermission();
if (permission !== 'granted') {
console.log('تم رفض إذن الكشف عن الخمول');
return;
}
const idleDetector = new IdleDetector();
idleDetector.addEventListener('change', () => {
const userState = idleDetector.userState; // 'active' or 'idle'
const screenState = idleDetector.screenState; // 'locked' or 'unlocked'
console.log(`المستخدم: ${userState}، الشاشة: ${screenState}`);
if (userState === 'idle') {
handleUserIdle();
} else {
handleUserActive();
}
});
// Start detection (check after 60 seconds of inactivity)
await idleDetector.start({
threshold: 60000 // milliseconds
});
console.log('بدأ الكشف عن الخمول');
} catch (error) {
console.error('خطأ في الكشف عن الخمول:', error);
}
}
function handleUserIdle() {
console.log('المستخدم خامل');
// Pause animations, videos, reduce network activity
}
function handleUserActive() {
console.log('المستخدم نشط');
// Resume normal operation
}
حالات الاستخدام: تطبيقات الدردشة (إظهار كـ غير متواجد)، مؤتمرات الفيديو (إيقاف الفيديو عند الخمول)، الألعاب (إيقاف تلقائي)، لوحات المعلومات (تقليل التحديثات)، ميزات توفير الطاقة.
Screen Capture API
تمكّن واجهة برمجة تطبيقات التقاط الشاشة من التقاط محتويات الشاشة للتسجيل أو المشاركة.
// Capture screen
async function captureScreen() {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
cursor: 'always' // Include cursor in capture
},
audio: false
});
// Use the stream
const videoElement = document.querySelector('video');
videoElement.srcObject = stream;
// Record the stream
const mediaRecorder = new MediaRecorder(stream);
const chunks = [];
mediaRecorder.ondataavailable = event => {
if (event.data.size > 0) {
chunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(chunks, { type: 'video/webm' });
const url = URL.createObjectURL(blob);
// Download or save the recording
const a = document.createElement('a');
a.href = url;
a.download = 'screen-recording.webm';
a.click();
};
mediaRecorder.start();
// Stop recording after user interaction or timeout
stream.getVideoTracks()[0].addEventListener('ended', () => {
mediaRecorder.stop();
});
return { stream, mediaRecorder };
} catch (error) {
console.error('خطأ في التقاط الشاشة:', error);
}
}
Badging API
تسمح واجهة برمجة تطبيقات الشارة بتعيين شارة على أيقونة التطبيق لعرض عدد الإشعارات.
// Set badge
async function setBadge(count) {
if ('setAppBadge' in navigator) {
try {
await navigator.setAppBadge(count);
console.log(`تم تعيين الشارة إلى ${count}`);
} catch (error) {
console.error('خطأ في الشارة:', error);
}
}
}
// Clear badge
async function clearBadge() {
if ('clearAppBadge' in navigator) {
await navigator.clearAppBadge();
console.log('تم مسح الشارة');
}
}
// Example: Notification manager
class NotificationManager {
constructor() {
this.unreadCount = 0;
}
async addNotification(notification) {
this.unreadCount++;
await this.updateBadge();
}
async markAsRead(notificationId) {
this.unreadCount = Math.max(0, this.unreadCount - 1);
await this.updateBadge();
}
async markAllAsRead() {
this.unreadCount = 0;
await clearBadge();
}
async updateBadge() {
if (this.unreadCount > 0) {
await setBadge(this.unreadCount);
} else {
await clearBadge();
}
}
}
قدرات PWA المستقبلية
واجهات برمجة تطبيقات وميزات قادمة:
- Local Font Access: الوصول إلى الخطوط المثبتة محلياً لأدوات التصميم
- EyeDropper API: اختيار الألوان من أي مكان على الشاشة
- Web Serial API: الاتصال بأجهزة التسلسل (Arduino، إلخ)
- Web HID API: التفاعل مع أجهزة الواجهة البشرية
- Web USB API: الاتصال بأجهزة USB
- Keyboard Lock API: التقاط جميع مدخلات لوحة المفاتيح (للألعاب)
- Virtual Keyboard API: تحكم أفضل في لوحات المفاتيح على الشاشة
- Window Controls Overlay: تخصيص منطقة شريط العنوان
- Multi-Screen Window Placement: التحكم في موضع النافذة عبر شاشات متعددة
أفضل الممارسات لواجهات برمجة التطبيقات الناشئة
// Feature detection pattern
function supportsFeature(feature) {
const features = {
fileSystem: 'showOpenFilePicker' in window,
bluetooth: 'bluetooth' in navigator,
nfc: 'NDEFReader' in window,
idle: 'IdleDetector' in window,
badge: 'setAppBadge' in navigator,
screenCapture: 'getDisplayMedia' in navigator.mediaDevices
};
return features[feature] || false;
}
// Progressive enhancement
async function enhanceWithNewFeatures() {
const features = {};
if (supportsFeature('fileSystem')) {
features.fileSystem = await import('./file-system-handler.js');
}
if (supportsFeature('bluetooth')) {
features.bluetooth = await import('./bluetooth-handler.js');
}
// Provide fallbacks for unsupported features
if (!features.fileSystem) {
features.fileSystem = await import('./file-system-fallback.js');
}
return features;
}
اتجاهات PWA المستقبلية
ما يمكن توقعه في السنوات 2-3 القادمة:
- دعم أفضل لـ iOS: تضيف Apple تدريجياً المزيد من ميزات PWA إلى Safari
- نضج PWA على سطح المكتب: دمج أفضل مع نظام التشغيل على Windows و macOS و Linux
- دمج الذكاء الاصطناعي: واجهات برمجة تطبيقات الويب لميزات التعلم الآلي والذكاء الاصطناعي
- دعم AR/VR: WebXR للتجارب الغامرة
- تحسينات الأداء: محركات JavaScript أسرع وتخزين مؤقت أفضل
- ميزات تعطي الأولوية للخصوصية: واجهات برمجة تطبيقات جديدة تعطي الأولوية لخصوصية المستخدم
- تجارب عبر الأجهزة: مزامنة أفضل وانتقال بين الأجهزة
ملخص الدورة
تهانينا على إكمال برنامج تطبيقات الويب التقدمية! لنلخص ما تعلمناه:
✓ أساسيات PWA
- فهم مبادئ وفوائد PWA
- الفرق بين PWAs والتطبيقات الأصلية
- دعم المتصفح والتوافق
✓ التقنيات الأساسية
- Service Workers للوظائف دون اتصال
- Web App Manifest لإمكانية التثبيت
- HTTPS ومتطلبات الأمان
✓ استراتيجيات التخزين المؤقت
- Cache-first، network-first، stale-while-revalidate
- التخزين المؤقت الديناميكي وإدارة ذاكرة التخزين المؤقت
- صفحات احتياطية دون اتصال
✓ الميزات المتقدمة
- الإشعارات الفورية
- المزامنة في الخلفية
- IndexedDB للتخزين المحلي
- مطالبات التثبيت ودورة حياة التطبيق
✓ تحسين الأداء
- هندسة app shell
- التحميل الكسول وتقسيم الكود
- تحسين الموارد
- تدقيقات Lighthouse
✓ التنفيذ في العالم الحقيقي
- بناء TaskMaster PWA كامل
- التعلم من دراسات حالة ناجحة
- استراتيجيات النشر والمراقبة
✓ التقنيات المستقبلية
- Project Fugu وواجهات برمجة التطبيقات الناشئة
- File System، Bluetooth، NFC
- قدرات PWA القادمة
التحدي النهائي: ابنِ PWA خاص بك من الصفر يتضمن:
- وظائف دون اتصال مع service worker
- ملف manifest وقابلية التثبيت
- واجهة برمجة تطبيقات متقدمة واحدة على الأقل (إشعارات، مزامنة في الخلفية، إلخ)
- درجة Lighthouse 90+ في جميع الفئات
- النشر إلى الإنتاج مع HTTPS
- توثيق الهندسة المعمارية وقرارات التصميم
شارك PWA الخاص بك مع المجتمع واحصل على ملاحظات!
الخطوات التالية:
- ابقَ على اطلاع بـ web.dev/pwa
- تابع تقدم Project Fugu في fugu-tracker.web.app
- انضم إلى مجتمعات ومنتديات PWA
- جرّب واجهات برمجة التطبيقات الناشئة في Chrome Canary
- ساهم في مشاريع PWA مفتوحة المصدر
- شارك معرفتك وساعد الآخرين على التعلم
شكراً لإكمالك هذه الدورة. استمر في بناء تطبيقات الويب التقدمية الرائعة!