التفاعل مع أجهزة NFC على Chrome لنظام Android

أصبحت إمكانية القراءة والكتابة باستخدام علامات NFC متاحة الآن.

François Beaufort
François Beaufort

ما هي تقنية Web NFC؟

يعني الاختصار NFC اتصالات الحقل القصير، وهي تقنية لاسلكية قصيرة المدى تعمل بتردد 13.56 ميغاهرتز تتيح الاتصال بين الأجهزة عن بُعد أقل من 10 سم ومعدل نقل يصل إلى 424 كيلوبت/ثانية.

توفر تقنية NFC على الويب للمواقع الإلكترونية القدرة على قراءة علامات NFC والكتابة إليها عندما على مسافة قريبة من جهاز المستخدم (عادةً 5-10 سم، 2-4 بوصة) يقتصر النطاق الحالي على تنسيق تبادل البيانات عبر NFC (NDEF)، وهو بروتوكول خفيف تنسيق رسالة ثنائية يعمل عبر تنسيقات مختلفة للعلامات.

هاتف يشغِّل علامة NFC لتبادل البيانات
مخطّط بياني لعملية تقنية NFC

حالات الاستخدام المقترَحة

تقتصر تقنية NFC على الويب على NDEF نظرًا لأن خصائص الأمان للقراءة كتابة بيانات NDEF قابلة للقياس الكمي بسهولة أكبر. عمليات إدخال/إخراج منخفضة (على سبيل المثال: ISO-DEP وNFC-A/B وNFC-F ووضع الاتصال بين شبكة الند للند وبطاقة مستندة إلى المضيف المحاكاة (HCE) غير متاحة.

تشمل أمثلة المواقع الإلكترونية التي قد تستخدم تقنية NFC على الويب ما يلي:

  • يمكن للمتاحف والمعارض الفنية عرض معلومات إضافية حول عرض عندما يلمس المستخدم جهازه ببطاقة NFC بالقرب من المعرض.
  • يمكن لمواقع إدارة المستودعات قراءة البيانات أو كتابتها في علامة NFC على لتحديث المعلومات عن محتوياتها.
  • يمكن للمواقع الإلكترونية الخاصة بالمؤتمرات استخدامها لمسح شارات NFC ضوئيًا أثناء الفعالية والتأكّد من يتم قفلها لمنع أي تغييرات أخرى على المعلومات المكتوبة عليها.
  • يمكن للمواقع الإلكترونية استخدامها لمشاركة المفاتيح السرّية الأولية اللازمة للجهاز أو الخدمة. سيناريوهات توفير المتطلبات اللازمة وكذلك نشر بيانات التهيئة في بيئة التشغيل الحالي.
يُجري الهاتف مسحًا ضوئيًا لعدة علامات NFC.
صورة توضيحية حول إدارة مستودع NFC

الوضع الحالي

الخطوة الحالة
1. إنشاء شرح مكتمل
2. إنشاء مسودة أولية للمواصفات مكتمل
3- جمع الملاحظات التكرار التحسيني للتصميم مكتمل
4. مرحلة التجربة والتقييم مكتمل
5- الإطلاق مكتمل

استخدام تقنية NFC على الويب

رصد الميزات

يختلف اكتشاف الميزات للأجهزة عما اعتدت عليه على الأرجح. يشير ظهور NDEFReader إلى أنّ المتصفّح متوافق مع Web NFC، ولكنّه وليس ما إذا كان الأجهزة المطلوبة موجودة أم لا. على وجه الخصوص، إذا كانت الأجهزة مفقود، سيتم رفض الوعد الذي تم إرجاعه بسبب مكالمات معينة. سأقدّم التفاصيل عندما أصف NDEFReader.

if ('NDEFReader' in window) { /* Scan and write NFC tags */ }

المصطلحات

علامة NFC هي جهاز NFC سلبي، ما يعني أنه يعمل بواسطة تقنية مغناطيسية حثّ على التفاعل عندما يكون جهاز NFC نشطًا (مثل الهاتف) على مسافة قريبة علامات NFC بأشكال وأزياء عديدة، مثل الملصقات وبطاقات الائتمان ومعصمات الذراع أخرى.

صورة لعلامة NFC شفافة
علامة NFC شفافة

العنصر NDEFReader هو نقطة الدخول في تقنية Web NFC التي تعرض الوظائف. لإعداد إجراءات القراءة و/أو الكتابة التي يتم تحقيقها عند استخدام علامة NDEF تأتي في نطاق التقارب. الاختصار NDEF في NDEFReader يعني تبادل البيانات عبر NFC. التنسيق، هو تنسيق خفيف للرسائل الثنائية، موحّدًا في منتدى NFC.

الغرض من الكائن NDEFReader هو التعامل مع رسائل NDEF الواردة من علامات NFC. ولكتابة رسائل NDEF إلى علامات NFC داخل النطاق.

تشبه علامة NFC التي تدعم NDEF الملاحظات اللاصقة. يمكن لأي شخص قراءته، ما لم تكن القراءة فقط، يمكن لأي شخص الكتابة إليها. يحتوي على NDEF واحد تحتوي على سجل NDEF واحد أو أكثر. يُعد كل سجل NDEF بنية ثنائية تحتوي على حمولة بيانات ومعلومات النوع المرتبطة بها. تتوافق تقنية NFC على الويب مع أنواع السجلّات الموحّدة التالية في منتدى NFC: عنوان URL والملصق الذكي ونوع MIME وعنوان URL المطلق والنوع الخارجي وغير معروف والمحلي الكتابة.

مخطّط بياني لرسالة NDEF
رسم بياني لرسالة NDEF

مسح علامات NFC ضوئيًا

لمسح علامات NFC ضوئيًا، أنشئ أولاً مثيلاً لعنصر NDEFReader جديد. جارٍ الاتصال بالرقم scan() ويعدك بوعد. قد يُطلب من المستخدم إذا لم يسبق له الوصول إلى الحساب ممنوح. سيحلّ الوعد في حال استيفاء جميع الشروط التالية:

  • لم يتم استدعاؤه إلا استجابةً لإيماءة المستخدم مثل إيماءة اللمس أو ونقر بالماوس.
  • سمح المستخدم للموقع الإلكتروني بالتفاعل مع أجهزة NFC.
  • يتوافق هاتف المستخدم مع تقنية NFC.
  • فعّل المستخدم تقنية NFC على هاتفه.

بمجرد حل الوعد، تتوفر رسائل NDEF الواردة من خلال الاشتراك في أحداث "reading" من خلال أداة معالجة الأحداث عليك أيضًا الاشتراك إلى حدثَين (readingerror) ليتم إشعارهما عند عدم توافق علامات NFC التقارب.

const ndef = new NDEFReader();
ndef.scan().then(() => {
  console.log("Scan started successfully.");
  ndef.onreadingerror = () => {
    console.log("Cannot read data from the NFC tag. Try another one?");
  };
  ndef.onreading = event => {
    console.log("NDEF message read.");
  };
}).catch(error => {
  console.log(`Error! Scan failed to start: ${error}.`);
});

وعندما تكون علامة NFC قريبة، يتم تنشيط حدث NDEFReadingEvent. أُنشأها جون هنتر، الذي كان متخصصًا يحتوي على خاصيتين فريدتين له:

  • يمثل serialNumber الرقم التسلسلي للجهاز (مثل 00-11-22-33-44-55-66)، أو سلسلة فارغة في حال عدم توفّر أي منها.
  • يمثّل message رسالة NDEF المخزّنة في علامة NFC.

لقراءة محتوى رسالة NDEF، استخدم التكرار خلال message.records و معالجة الأعضاء في data بشكل ملائم استنادًا إلى recordType. يظهر العضو data كـ DataView بما يسمح بالمعالجة. الحالات التي تكون فيها البيانات مشفرة بـ UTF-16.

ndef.onreading = event => {
  const message = event.message;
  for (const record of message.records) {
    console.log("Record type:  " + record.recordType);
    console.log("MIME type:    " + record.mediaType);
    console.log("Record id:    " + record.id);
    switch (record.recordType) {
      case "text":
        // TODO: Read text record with record data, lang, and encoding.
        break;
      case "url":
        // TODO: Read URL record with record data.
        break;
      default:
        // TODO: Handle other records with record data.
    }
  }
};

كتابة علامات NFC

لكتابة علامات NFC، عليك أولاً إنشاء مثيل كائن NDEFReader جديد. إجراء المكالمات تم إرجاع وعد من قِبل "write()". قد يُطلب من المستخدم في حال عدم منح إذن الوصول ممنوحة مسبقًا. في هذه المرحلة، تكون رسالة NDEF "جاهزة" واعِد سيتم حله إذا تم استيفاء جميع الشروط التالية:

  • لم يتم استدعاؤه إلا استجابةً لإيماءة المستخدم مثل إيماءة اللمس أو ونقر بالماوس.
  • سمح المستخدم للموقع الإلكتروني بالتفاعل مع أجهزة NFC.
  • يتوافق هاتف المستخدم مع تقنية NFC.
  • فعّل المستخدم تقنية NFC على هاتفه.
  • نقر المستخدم على علامة NFC وتمت كتابة رسالة NDEF بنجاح.

لكتابة نص إلى علامة NFC، مرِّر سلسلة إلى الطريقة write().

const ndef = new NDEFReader();
ndef.write(
  "Hello World"
).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

لكتابة سجلّ عنوان URL إلى علامة NFC، يجب ضبط قاموس يمثّل معيار NDEF. رسالة إلى write(). في المثال أدناه، تعد رسالة NDEF قاموسًا باستخدام مفتاح records. وقيمته هي مصفوفة من السجلات - في هذه الحالة، عنوان URL سجلّ محدّد ككائن مع ضبط مفتاح recordType على "url" وdata إلى سلسلة عنوان URL.

const ndef = new NDEFReader();
ndef.write({
  records: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }]
}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

ويمكن أيضًا كتابة سجلات متعددة لعلامة NFC.

const ndef = new NDEFReader();
ndef.write({ records: [
    { recordType: "url", data: "https://w3c.github.io/web-nfc/" },
    { recordType: "url", data: "https://web.dev/nfc/" }
]}).then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

إذا كانت علامة NFC تحتوي على رسالة NDEF لا يُقصد استبدالها، يجب ضبط السمة overwrite إلى false في الخيارات التي تم ضبطها إلى write() . في هذه الحالة، سيتم رفض الوعد الذي تم إرجاعه إذا كانت رسالة NDEF مخزنة بالفعل في علامة NFC.

const ndef = new NDEFReader();
ndef.write("Writing data on an empty NFC tag is fun!", { overwrite: false })
.then(() => {
  console.log("Message written.");
}).catch(error => {
  console.log(`Write failed :-( try again: ${error}.`);
});

جعل علامات NFC للقراءة فقط

لمنع المستخدمين الضارين من استبدال محتوى علامة NFC، يمكن: جعل علامات NFC للقراءة فقط بشكل دائم. هذه العملية هي عملية أحادية الاتجاه لا يمكن التراجع عنه. بعد تحويل علامة NFC للقراءة فقط، لا يمكن كتابتها إليه بعد الآن.

لجعل علامات NFC للقراءة فقط، يجب أولاً إنشاء مثيل كائن NDEFReader جديد. إجراء المكالمات تم إرجاع وعد من قِبل "makeReadOnly()". قد يُطلب من المستخدم في حال عدم منح إذن الوصول ممنوحة مسبقًا. سيحلّ الوعد في حال استيفاء الشروط التالية التقاء:

  • لم يتم استدعاؤه إلا استجابةً لإيماءة المستخدم مثل إيماءة اللمس أو ونقر بالماوس.
  • سمح المستخدم للموقع الإلكتروني بالتفاعل مع أجهزة NFC.
  • يتوافق هاتف المستخدم مع تقنية NFC.
  • فعّل المستخدم تقنية NFC على هاتفه.
  • نقر المستخدم على علامة NFC وأصبحت علامة NFC للقراءة فقط بنجاح.
const ndef = new NDEFReader();
ndef.makeReadOnly()
.then(() => {
  console.log("NFC tag has been made permanently read-only.");
}).catch(error => {
  console.log(`Operation failed: ${error}`);
});

في ما يلي كيفية جعل علامة NFC للقراءة فقط بشكل دائم بعد الكتابة إليها.

const ndef = new NDEFReader();
try {
  await ndef.write("Hello world");
  console.log("Message written.");
  await ndef.makeReadOnly();
  console.log("NFC tag has been made permanently read-only after writing to it.");
} catch (error) {
  console.log(`Operation failed: ${error}`);
}

بما أنّ makeReadOnly() متوفّر على الإصدار 100 من Chrome أو إصدار أحدث على نظام التشغيل Android، يُرجى التحقّق من إذا كانت هذه الميزة متاحة مع ما يلي:

if ("NDEFReader" in window && "makeReadOnly" in NDEFReader.prototype) {
  // makeReadOnly() is supported.
}

الأمان والأذونات

صمَّم فريق Chrome ونفّذ تقنية NFC على الويب باستخدام المبادئ الأساسية. محدد في التحكم في الوصول إلى نظام أساسي قوي على الويب الميزات، بما في ذلك إمكانية تحكُّم المستخدم والشفافية وتسهيل الاستخدام

نظرًا لأن NFC توسّع نطاق المعلومات التي قد تكون متاحة للبرامج الضارة مواقع الويب، فسيتم تقييد توفر تقنية الاتصال القصير المدى (NFC) لتحقيق أقصى قدر من الوعي التحكم في استخدام NFC.

لقطة شاشة لطلب الاتصال القصير المدى (NFC) على الويب على موقع إلكتروني
طلب من مستخدم NFC على الويب

لا تتوفر تقنية NFC على الويب إلا لإطارات المستوى الأعلى وسياقات التصفح الآمن (HTTPS. فقط). يجب أن تطلب المصادر أولاً الإذن "nfc" أثناء التعامل مع إيماءة المستخدم (مثل النقر على الزر). إنّ scan() وwrite() وNDEFReader تؤدي makeReadOnly() طريقة إلى تشغيل طلب من المستخدم، إذا لم يكن إذن الوصول قد سبق. ممنوح.

  document.querySelector("#scanButton").onclick = async () => {
    const ndef = new NDEFReader();
    // Prompt user to allow website to interact with NFC devices.
    await ndef.scan();
    ndef.onreading = event => {
      // TODO: Handle incoming NDEF messages.
    };
  };

الجمع بين طلب الإذن الذي يبدأه المستخدم مع طلب الحصول على إذن فوري إن حركة جلب الجهاز عبر علامة NFC المستهدفة تنسخ أداة الاختيار الذي تم العثور عليه في واجهات برمجة التطبيقات الأخرى للملفات والأجهزة للوصول إلى البيانات.

لإجراء فحص أو كتابة، يجب أن تكون صفحة الويب مرئية عندما يلمس المستخدم. علامة NFC بأجهزتهم. يستخدم المتصفح تجاوبًا حسيًا للإشارة إلى النقر. يتم حظر الوصول إلى راديو NFC إذا كانت الشاشة مغلقة أو تم تشغيل الجهاز مُقفل. بالنسبة إلى صفحات الويب غير المرئية، يكون استلام محتوى NFC وإرساله وتعليقها واستئنافها عندما تصبح صفحة الويب مرئية مرة أخرى.

بفضل واجهة برمجة تطبيقات مستوى رؤية الصفحة، يمكن تتبع أوقات ظهور مستوى الرؤية للتغيير.

document.onvisibilitychange = event => {
  if (document.hidden) {
    // All NFC operations are automatically suspended when document is hidden.
  } else {
    // All NFC operations are resumed, if needed.
  }
};

كتاب الطبخ

فيما يلي بعض نماذج التعليمات البرمجية لمساعدتك على البدء.

التحقّق من الإذن

تسمح Permissions API بالتحقّق مما إذا كان إذن "nfc" قد تمّ ممنوح. يعرض هذا المثال كيفية فحص علامات NFC بدون تفاعل المستخدم إذا كان قد تم منحه حق الوصول سابقًا، أو عرض زر بخلاف ذلك. لاحظ أن نفس لكتابة علامات NFC لأنها تستخدم الإذن نفسه بموجب مدخنة.

const ndef = new NDEFReader();

async function startScanning() {
  await ndef.scan();
  ndef.onreading = event => {
    /* handle NDEF messages */
  };
}

const nfcPermissionStatus = await navigator.permissions.query({ name: "nfc" });
if (nfcPermissionStatus.state === "granted") {
  // NFC access was previously granted, so we can start NFC scanning now.
  startScanning();
} else {
  // Show a "scan" button.
  document.querySelector("#scanButton").style.display = "block";
  document.querySelector("#scanButton").onclick = event => {
    // Prompt user to allow UA to send and receive info when they tap NFC devices.
    startScanning();
  };
}

إلغاء عمليات NFC

يؤدي استخدام مجموعة AbortController الأساسية إلى تسهيل عملية إلغاء تقنية الاتصال القصير المدى (NFC) العمليات التجارية. يوضح المثال أدناه كيفية تمرير signal من AbortController من خلال خيارات NDEFReader scan()، makeReadOnly()، write() وسيتم إلغاء عمليتين NFC في نفس الوقت.

const abortController = new AbortController();
abortController.signal.onabort = event => {
  // All NFC operations have been aborted.
};

const ndef = new NDEFReader();
await ndef.scan({ signal: abortController.signal });

await ndef.write("Hello world", { signal: abortController.signal });
await ndef.makeReadOnly({ signal: abortController.signal });

document.querySelector("#abortButton").onclick = event => {
  abortController.abort();
};

القراءة بعد الكتابة

يتم استخدام write() ثم scan() مع AbortController. يتيح قراءة علامة NFC بعد كتابة رسالة إليها. يوضح المثال أدناه كيفية كتابة رسالة نصية إلى علامة NFC وقراءة الرسالة الجديدة في علامة NFC. ويتوقّف المسح بعد ثلاث ثوانٍ.

// Waiting for user to tap NFC tag to write to it...
const ndef = new NDEFReader();
await ndef.write("Hello world");
// Success! Message has been written.

// Now scanning for 3 seconds...
const abortController = new AbortController();
await ndef.scan({ signal: abortController.signal });
const message = await new Promise((resolve) => {
  ndef.onreading = (event) => resolve(event.message);
});
// Success! Message has been read.

await new Promise((r) => setTimeout(r, 3000));
abortController.abort();
// Scanning is now stopped.

قراءة سجلّ النص وكتابته

يمكن فك ترميز سجل النص data باستخدام الرمز TextDecoder الذي تم إنشاء مثيل له باستخدام تسجيل السمة encoding. لاحظ أن لغة سجل النص هي متاحة من خلال الموقع الإلكتروني lang.

function readTextRecord(record) {
  console.assert(record.recordType === "text");
  const textDecoder = new TextDecoder(record.encoding);
  console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
}

لكتابة سجل نص بسيط، مرر سلسلة إلى إجراء NDEFReader write().

const ndef = new NDEFReader();
await ndef.write("Hello World");

تكون السجلات النصية UTF-8 بشكل افتراضي وتفترض لغة المستند الحالي ولكن يمكن تحديد كلتا السمتَين (encoding وlang) باستخدام البنية الكاملة لإنشاء سجل NDEF مخصص.

function a2utf16(string) {
  let result = new Uint16Array(string.length);
  for (let i = 0; i < string.length; i++) {
    result[i] = string.codePointAt(i);
  }
  return result;
}

const textRecord = {
  recordType: "text",
  lang: "fr",
  encoding: "utf-16",
  data: a2utf16("Bonjour, François !")
};

const ndef = new NDEFReader();
await ndef.write({ records: [textRecord] });

قراءة سجلّ عنوان URL وكتابته

استخدِم TextDecoder لفك ترميز data في السجلّ.

function readUrlRecord(record) {
  console.assert(record.recordType === "url");
  const textDecoder = new TextDecoder();
  console.log(`URL: ${textDecoder.decode(record.data)}`);
}

لكتابة سجل عنوان URL، قم بتمرير قاموس رسالة NDEF إلى NDEFReader طريقة write(). يتم تعريف سجل عنوان URL الموجود في رسالة NDEF على أنه مع ضبط مفتاح recordType على "url" وعلى مفتاح data على عنوان URL السلسلة.

const urlRecord = {
  recordType: "url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [urlRecord] });

قراءة سجلّ من نوع MIME وكتابته

تمثّل السمة mediaType لسجلّ نوع MIME نوع MIME حمولة سجلّ NDEF بحيث يمكن فك ترميز data بشكل صحيح على سبيل المثال، استخدم JSON.parse لفك ترميز نص JSON وعنصر صورة لفك ترميز بيانات الصور.

function readMimeRecord(record) {
  console.assert(record.recordType === "mime");
  if (record.mediaType === "application/json") {
    const textDecoder = new TextDecoder();
    console.log(`JSON: ${JSON.parse(decoder.decode(record.data))}`);
  }
  else if (record.mediaType.startsWith('image/')) {
    const blob = new Blob([record.data], { type: record.mediaType });
    const img = new Image();
    img.src = URL.createObjectURL(blob);
    document.body.appendChild(img);
  }
  else {
    // TODO: Handle other MIME types.
  }
}

لكتابة سجل من نوع MIME، قم بتمرير قاموس رسالة NDEF إلى NDEFReader طريقة write(). يتم تحديد سجلّ نوع MIME المضمّن في رسالة NDEF ككائن مع ضبط مفتاح recordType على "mime"، أو ضبط مفتاح mediaType على ونوع MIME الفعلي للمحتوى، وضبط مفتاح data على كائن يمكن أن إما ArrayBuffer أو يوفر مشاهدة لـ ArrayBuffer (على سبيل المثال، Uint8Array، DataView).

const encoder = new TextEncoder();
const data = {
  firstname: "François",
  lastname: "Beaufort"
};
const jsonRecord = {
  recordType: "mime",
  mediaType: "application/json",
  data: encoder.encode(JSON.stringify(data))
};

const imageRecord = {
  recordType: "mime",
  mediaType: "image/png",
  data: await (await fetch("icon1.png")).arrayBuffer()
};

const ndef = new NDEFReader();
await ndef.write({ records: [jsonRecord, imageRecord] });

قراءة سجلّ عنوان URL كامل وكتابته

يمكن فك ترميز سجل عنوان URL المطلق data باستخدام TextDecoder بسيط.

function readAbsoluteUrlRecord(record) {
  console.assert(record.recordType === "absolute-url");
  const textDecoder = new TextDecoder();
  console.log(`Absolute URL: ${textDecoder.decode(record.data)}`);
}

لكتابة سجل عنوان URL مطلق، مرر قاموس رسالة NDEF إلى NDEFReader write(). سجل عنوان URL المطلق المتوفر في NDEF يتم تحديد الرسالة ككائن مع ضبط مفتاح recordType على "absolute-url" وضبط مفتاح data على سلسلة عنوان URL.

const absoluteUrlRecord = {
  recordType: "absolute-url",
  data:"https://w3c.github.io/web-nfc/"
};

const ndef = new NDEFReader();
await ndef.write({ records: [absoluteUrlRecord] });

قراءة سجلّ الملصق الذكي وكتابته

سجل الملصقات الذكية (المستخدم في إعلانات المجلات والمنشورات واللوحات الإعلانية وغيرها)، يصف بعض محتوى الويب كسجل NDEF يحتوي على NDEF كحمولة لها. طلب record.toRecords() لتحويل data إلى قائمة من السجلات الموجودة في سجل الملصق الذكي. ينبغي أن يحتوي على سجل عنوان URL، سجلّ نصي للعنوان، وسجلّ من نوع MIME للصورة، بالإضافة إلى بعض البيانات النوع المحلي مثل ":t" و":act" و":s" على التوالي ونوع سجل الملصق الذكي وعمله وحجمه.

تكون سجلات النوع المحلي فريدة فقط ضمن السياق المحلي لعنوان URL الذي يتضمن سجلّ NDEF. استخدمها عندما لا يكون معنى الأنواع مهمًا خارج للسياق المحلي للسجل الذي يتضمن المحتوى، وعندما يكون من الصعب استخدام مساحة التخزين . تبدأ دائمًا أسماء السجلات المحلية بـ : في تقنية NFC على الويب (مثل ":t" و":s" و":act"). بغرض التفريق بين سجل نصي محلي لكتابة سجل النص على سبيل المثال.

function readSmartPosterRecord(smartPosterRecord) {
  console.assert(record.recordType === "smart-poster");
  let action, text, url;

  for (const record of smartPosterRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      text = decoder.decode(record.data);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      url = decoder.decode(record.data);
    } else if (record.recordType == ":act") {
      action = record.data.getUint8(0);
    } else {
      // TODO: Handle other type of records such as `:t`, `:s`.
    }
  }

  switch (action) {
    case 0:
      // Do the action
      break;
    case 1:
      // Save for later
      break;
    case 2:
      // Open for editing
      break;
  }
}

لكتابة سجل ملصق ذكي، أرسِل رسالة NDEF إلى NDEFReader write() . يتم تعريف سجل الملصق الذكي المتوفر في رسالة NDEF على أنه مع ضبط مفتاح recordType على "smart-poster" ومفتاح data على كائنًا يمثل (مرة أخرى) رسالة NDEF مضمنة في سجل الملصق الذكي.

const encoder = new TextEncoder();
const smartPosterRecord = {
  recordType: "smart-poster",
  data: {
    records: [
      {
        recordType: "url", // URL record for smart poster content
        data: "https://my.org/content/19911"
      },
      {
        recordType: "text", // title record for smart poster content
        data: "Funny dance"
      },
      {
        recordType: ":t", // type record, a local type to smart poster
        data: encoder.encode("image/gif") // MIME type of smart poster content
      },
      {
        recordType: ":s", // size record, a local type to smart poster
        data: new Uint32Array([4096]) // byte size of smart poster content
      },
      {
        recordType: ":act", // action record, a local type to smart poster
        // do the action, in this case open in the browser
        data: new Uint8Array([0])
      },
      {
        recordType: "mime", // icon record, a MIME type record
        mediaType: "image/png",
        data: await (await fetch("icon1.png")).arrayBuffer()
      },
      {
        recordType: "mime", // another icon record
        mediaType: "image/jpg",
        data: await (await fetch("icon2.jpg")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
await ndef.write({ records: [smartPosterRecord] });

قراءة سجلّ نوع خارجي وكتابته

لإنشاء سجلّات محدَّدة للتطبيق، استخدِم سجلّات الأنواع الخارجية. قد تكون هذه سيحتوي على رسالة NDEF كحمولة يمكن الوصول إليها باستخدام toRecords(). يحتوي اسم النطاق على اسم نطاق المؤسسة المُصدِرة، وعلامة النقطتين والنوع، اسم لا يقل طوله عن حرف واحد، على سبيل المثال "example.com:foo".

function readExternalTypeRecord(externalTypeRecord) {
  for (const record of externalTypeRecord.toRecords()) {
    if (record.recordType == "text") {
      const decoder = new TextDecoder(record.encoding);
      console.log(`Text: ${textDecoder.decode(record.data)} (${record.lang})`);
    } else if (record.recordType == "url") {
      const decoder = new TextDecoder();
      console.log(`URL: ${decoder.decode(record.data)}`);
    } else {
      // TODO: Handle other type of records.
    }
  }
}

لكتابة سجل نوع خارجي، مرِّر قاموس رسالة NDEF إلى NDEFReader write(). يشير هذا المصطلح إلى سجلّ النوع الخارجي المضمَّن في NDEF. ككائن مع ضبط مفتاح recordType على اسم نوع خارجي ومجموعة مفاتيح data على كائن يمثّل رسالة NDEF الموجودة في سجل النوع الخارجي. لاحظ أن مفتاح data يمكن أيضًا إما ArrayBuffer أو يقدم طريقة عرض إلى ArrayBuffer (على سبيل المثال، Uint8Array، DataView).

const externalTypeRecord = {
  recordType: "example.game:a",
  data: {
    records: [
      {
        recordType: "url",
        data: "https://example.game/42"
      },
      {
        recordType: "text",
        data: "Game context given here"
      },
      {
        recordType: "mime",
        mediaType: "image/png",
        data: await (await fetch("image.png")).arrayBuffer()
      }
    ]
  }
};

const ndef = new NDEFReader();
ndef.write({ records: [externalTypeRecord] });

قراءة سجلّ فارغ وكتابته

لا يحتوي السجل الفارغ على حمولة.

لكتابة سجل فارغ، مرر قاموس رسالة NDEF إلى NDEFReader طريقة write(). يتم تعريف السجل الفارغ الموجود في رسالة NDEF على أنه كائن مع ضبط مفتاح recordType على "empty".

const emptyRecord = {
  recordType: "empty"
};

const ndef = new NDEFReader();
await ndef.write({ records: [emptyRecord] });

دعم المتصفح

تتوفّر تقنية NFC على الويب على نظام التشغيل Android في الإصدار Chrome 89.

نصائح لمطوّري البرامج

في ما يلي قائمة بالأشياء التي أتمنى لو كنت أعرفها عندما بدأت اللعب باستخدام تقنية Web NFC:

  • يعالج Android علامات NFC على مستوى نظام التشغيل قبل تشغيل تقنية NFC على الويب.
  • يمكنك العثور على رمز NFC على material.io.
  • يمكنك استخدام سجلّ NDEF id لتحديد السجلّ بسهولة عند الحاجة.
  • تحتوي علامة NFC غير المنسَّقة التي تتوافق مع NDEF على سجلّ واحد من النوع الفارغ.
  • وتُعدّ كتابة سجلّ تطبيق Android أمرًا سهلاً، كما هو موضّح أدناه.
const encoder = new TextEncoder();
const aarRecord = {
  recordType: "android.com:pkg",
  data: encoder.encode("com.example.myapp")
};

const ndef = new NDEFReader();
await ndef.write({ records: [aarRecord] });

إصدارات تجريبية

يمكنك تجربة النموذج الرسمي والاطّلاع على بعض عروض Web NFC الرائعة:

عرض توضيحي لبطاقات الاتصال القصير المدى (NFC) على الويب في مؤتمر Chrome Dev Summit لعام 2019

ملاحظات

مجموعة منتدى NFC على الويب يود فريق Chrome معرفة رأيك وخبراتك في استخدام تقنية Web NFC.

أخبِرنا عن تصميم واجهة برمجة التطبيقات

هل هناك أي مشكلة في واجهة برمجة التطبيقات لا تعمل كما هو متوقع؟ أم أن هناك الطرق المفقودة أو الخصائص التي تحتاجها لتنفيذ فكرتك؟

يُرجى الإبلاغ عن مشكلة في المواصفات على مستودع GitHub لتقنية الاتصال القصير المدى (NFC) على الويب أو إضافة أفكارك إلى مشكلة حالية.

الإبلاغ عن مشكلة في التنفيذ

هل واجهت مشكلة في التنفيذ في Chrome؟ أم أن التنفيذ عن المواصفات؟

يمكنك الإبلاغ عن الخطأ على https://new.crbug.com. تأكد من تضمين أكبر قدر قدر الإمكان، وتقديم إرشادات بسيطة لإعادة إنتاج الخطأ، تم ضبط المكوّنات على Blink>NFC. يعمل الخطأ بشكل رائع مشاركة عمليات إعادة الإنتاج السريعة والسهلة.

إظهار الدعم

هل تخطّط لاستخدام تقنية NFC على الويب؟ يساعد دعمك العام فريق Chrome تحديد أولويات الميزات وإظهار لموردي المتصفحات الآخرين مدى أهمية ودعمه.

إرسال تغريدة إلى @ChromiumDev باستخدام علامة التصنيف #WebNFC عليك إعلامنا بمكان تطبيقك وطريقة استخدامه

روابط مفيدة

شكر وتقدير

نتوجّه بالشكر إلى فريق Intel على تنفيذ تقنية Web NFC. متصفح Google Chrome يعتمد على مجموعة من الملتزمين الذين يتعاونون معًا لنقل Chromium مشروعك إلى الأمام. ليس كل مستخدمي Chromium موظفين في Google، وهذه للمساهمين يستحقون التقدير الخاص