Android için Chrome'da NFC cihazlarıyla etkileşimde bulunma

NFC etiketlerini okumak ve etiketlere yazmak artık mümkün.

François Beaufort
François Beaufort

Web NFC nedir?

NFC, 13,56 MHz'te çalışan ve 10 cm'den kısa mesafede 424 kbit/sn.ye varan aktarım hızıyla cihazlar arasında iletişim sağlayan kısa menzilli bir kablosuz teknoloji olan Near Field Communication'in kısaltmasıdır.

Web NFC, sitelerin kullanıcının cihazına yakın bir mesafede (genellikle 5-10 cm, 2-4 inç) NFC etiketlerini okuyup yazmalarına olanak tanır. Mevcut kapsam, farklı etiket biçimlerinde çalışan hafif bir ikili mesaj biçimi olan NFC Veri Değişimi Formatı (NDEF) ile sınırlıdır.

Telefon, veri alışverişi yapmak için NFC etiketini açıyor
NFC işleminin şeması

Önerilen kullanım alanları

Web NFC, NDEF verilerini okuma ve yazmanın güvenlik özellikleri daha kolay ölçülebilir olduğundan NDEF ile sınırlıdır. Düşük düzey I/O işlemleri (ör. ISO-DEP, NFC-A/B, NFC-F), Eşler Arası İletişim Modu ve Ana Makine Tabanlı Kart Emülasyonu (HCE) desteklenmez.

Web NFC'yi kullanabilecek sitelere örnek olarak şunlar verilebilir:

  • Müzeler ve sanat galerileri, kullanıcı cihazını serginin yanındaki NFC kartına değdirdiğinde sergiyle ilgili ek bilgiler gösterebilir.
  • Envanter yönetimi siteleri, içerikleriyle ilgili bilgileri güncellemek için kapsayıcıdaki NFC etiketinden veri okuyabilir veya bu etikete veri yazabilir.
  • Konferans siteleri, etkinlik sırasında NFC rozetlerini taramak ve üzerlerinde yazılı bilgilerde başka değişiklikler yapılmasını önlemek için rozetlerin kilitlendiğinden emin olmak için bu özelliği kullanabilir.
  • Siteler, cihaz veya hizmet sağlama senaryoları için gereken ilk sırlar paylaşmak ve ayrıca yapılandırma verilerini çalışma modunda dağıtmak için bu yöntemi kullanabilir.
Telefonda birkaç NFC etiketi taranırken
NFC envanter yönetimi gösterilmektedir

Mevcut durum

Step Durum
1. Açıklayıcı oluşturma Tamamlandı
2. Spesifikasyonun ilk taslağını oluşturma Tamamlandı
3. Geri bildirim toplayın ve tasarımda iterasyon yapın Tamamlandı
4. Kaynak denemesi Tamamlandı
5. Lansman Tamamlandı

Web NFC'yi kullanma

Özellik algılama

Donanım için özellik algılama, muhtemelen alıştığınızdan farklıdır. NDEFReader simgesinin bulunması, tarayıcının Web NFC'yi desteklediğini gösterir ancak gerekli donanımın mevcut olup olmadığını belirtmez. Özellikle donanım eksikse belirli çağrılar tarafından döndürülen söz reddedilir. NDEFReader hakkında bilgi verirken ayrıntıları da paylaşacağım.

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

Terminoloji

NFC etiketi, pasif bir NFC cihazıdır. Yani etkin bir NFC cihazı (telefon gibi) yakınındayken manyetik indüksiyonla çalışır. NFC etiketleri çıkartma, kredi kartı, bileklik gibi birçok farklı biçimde ve tarzda bulunur.

Şeffaf bir NFC etiketinin fotoğrafı
Şeffaf NFC etiketi

NDEFReader nesnesi, bir NDEF etiketi yakınlık alanına geldiğinde gerçekleştirilen okuma ve/veya yazma işlemlerini hazırlamak için işlevleri açıkta bırakan Web NFC giriş noktasıdır. NDEFReader içindeki NDEF, NFC Forum tarafından standartlaştırılmış hafif bir ikili mesaj biçimi olan NFC Veri Değişimi Biçimi'ni ifade eder.

NDEFReader nesnesi, NFC etiketlerinden gelen NDEF mesajlarını işlemek ve menzildeki NFC etiketlerine NDEF mesajları yazmak için kullanılır.

NDEF'yi destekleyen NFC etiketi, not kağıdına benzer. Herkes bu dosyayı okuyabilir ve salt okuma modunda olmadığı sürece herkes bu dosyaya yazabilir. Bir veya daha fazla NDEF kaydını kapsayan tek bir NDEF mesajı içerir. Her NDEF kaydı, veri yükü ve ilişkili tür bilgilerini içeren ikili bir yapıdır. Web NFC, aşağıdaki NFC Forum standartlaştırılmış kayıt türlerini destekler: boş, metin, URL, akıllı poster, MIME türü, mutlak URL, harici tür, bilinmeyen ve yerel tür.

NDEF mesajı diyagramı
NDEF mesajı şeması

NFC etiketlerini tarama

NFC etiketlerini taramak için önce yeni bir NDEFReader nesnesi oluşturun. scan() çağrısı bir promise döndürür. Daha önce erişim izni verilmediyse kullanıcıdan izin istenebilir. Söz, aşağıdaki koşulların tümü karşılanırsa çözülür:

  • Yalnızca dokunma hareketi veya fare tıklaması gibi bir kullanıcı hareketine yanıt olarak çağrıldı.
  • Kullanıcı, web sitesinin NFC cihazlarla etkileşime geçmesine izin vermiştir.
  • Kullanıcının telefonu NFC'yi desteklemelidir.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.

Sözleşme çözüldükten sonra, bir etkinlik işleyici aracılığıyla reading etkinliklerine abone olarak gelen NDEF mesajlarını alabilirsiniz. Uyumlu olmayan NFC etiketleri yakınınızda olduğunda bildirim almak için readingerror etkinliklerine de abone olmanız gerekir.

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

Bir NFC etiketi yakınınızda olduğunda NDEFReadingEvent etkinliği tetiklenir. Kendine özgü iki özelliğe sahiptir:

  • serialNumber, cihazın seri numarasını (ör. 00-11-22-33-44-55-66) veya seri numarası yoksa boş bir dize gösterir.
  • message, NFC etiketinde depolanan NDEF mesajını temsil eder.

NDEF mesajının içeriğini okumak için message.records içinde döngü yapın ve data üyelerini recordType'lerine göre uygun şekilde işleyin. Verilerin UTF-16 olarak kodlandığı durumların ele alınmasına olanak tanıdığı için data üyesi DataView olarak gösterilir.

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 etiketlerine yazma

NFC etiketlerine yazmak için önce yeni bir NDEFReader nesnesi oluşturun. write() çağrısı bir promise döndürür. Daha önce erişim izni verilmediyse kullanıcıdan izin istenebilir. Bu noktada bir NDEF mesajı "hazırlanır" ve aşağıdaki koşulların tümü karşılanırsa söz verilen işlem gerçekleşir:

  • Yalnızca dokunma hareketi veya fare tıklaması gibi bir kullanıcı hareketine yanıt olarak çağrıldı.
  • Kullanıcı, web sitesinin NFC cihazlarla etkileşime geçmesine izin vermiştir.
  • Kullanıcının telefonu NFC'yi desteklemelidir.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.
  • Kullanıcı bir NFC etiketine dokundu ve NDEF mesajı başarıyla yazıldı.

NFC etiketine metin yazmak için write() yöntemine bir dize iletin.

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

NFC etiketine URL kaydı yazmak için write()'e bir NDEF mesajını temsil eden bir sözlük iletin. Aşağıdaki örnekte NDEF mesajı, records anahtarına sahip bir sözlüktür. Değeri bir kayıt dizisidir. Bu durumda, recordType anahtarı "url" olarak ayarlanmış ve data anahtarı URL dizesine ayarlanmış bir nesne olarak tanımlanan bir URL kaydı.

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 etiketine birden fazla kayıt da yazılabilir.

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 etiketi, üzerine yazılmaması gereken bir NDEF mesajı içeriyorsa write() yöntemine iletilen seçeneklerde overwrite mülkünü false olarak ayarlayın. Bu durumda, NFC etiketinde zaten bir NDEF mesajı depolanmışsa döndürülen söz reddedilir.

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 etiketlerini salt okunur yapma

Kötü amaçlı kullanıcıların NFC etiketinin içeriğini üzerine yazmasını önlemek için NFC etiketlerini kalıcı olarak salt okuma moduna alabilirsiniz. Bu işlem tek yönlü bir işlemdir ve geri alınamaz. Bir NFC etiketi salt okunur hale getirildikten sonra üzerine yazılamaz.

NFC etiketlerini salt okunur yapmak için önce yeni bir NDEFReader nesnesi oluşturun. makeReadOnly() çağrısı bir promise döndürür. Daha önce erişim izni verilmediyse kullanıcıdan izin istenebilir. Sözleşme, aşağıdaki koşulların tümü karşılanırsa çözülür:

  • Yalnızca dokunma hareketi veya fare tıklaması gibi bir kullanıcı hareketine yanıt olarak çağrıldı.
  • Kullanıcı, web sitesinin NFC cihazlarla etkileşime geçmesine izin vermiştir.
  • Kullanıcının telefonu NFC'yi desteklemelidir.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.
  • Kullanıcı bir NFC etiketine dokundu ve NFC etiketi başarıyla salt okuma moduna geçirildi.
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 etiketine yazıldıktan sonra etiketi kalıcı olarak salt okunur hale getirmek için aşağıdaki adımları uygulayın.

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(), Android'de Chrome 100 veya sonraki sürümlerde kullanılabildiğinden, bu özelliğin aşağıdaki cihazlarda desteklenip desteklenmediğini kontrol edin:

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

Güvenlik ve izinler

Chrome ekibi, Web NFC'yi tasarlarken ve uygularken Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme başlıklı makalede belirtilen temel ilkeleri (kullanıcı kontrolü, şeffaflık ve ergonomi gibi) temel almıştır.

NFC, kötü amaçlı web sitelerinin erişebileceği bilgi alanını genişlettiğinden, kullanıcıların NFC kullanımı hakkındaki farkındalığını ve kontrolünü en üst düzeye çıkarmak için NFC'nin kullanılabilirliği kısıtlanır.

Bir web sitesindeki Web NFC isteğinin ekran görüntüsü
Web NFC kullanıcı istemi

Web NFC yalnızca üst düzey çerçeveler ve güvenli tarama bağlamlarında (yalnızca HTTPS) kullanılabilir. Kaynaklar, kullanıcı hareketini (ör.düğme tıklaması) işlerken önce "nfc" izni istemelidir. Daha önce erişim izni verilmemişse NDEFReader, scan(), write() ve makeReadOnly() yöntemleri kullanıcı istemi tetikler.

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

Kullanıcı tarafından başlatılan izin istemi ile cihazı hedef NFC etiketine getirmenin gerçek dünyadaki fiziksel hareketinin kombinasyonu, diğer dosya ve cihaz erişimi API'lerinde bulunan seçici kalıbını yansıtır.

Tarama veya yazma işlemi gerçekleştirmek için kullanıcı cihazıyla NFC etiketine dokunduğunda web sayfasının görünür olması gerekir. Tarayıcı, dokunmayı belirtmek için dokunsal geri bildirim kullanır. Ekran kapalıysa veya cihaz kilitliyse NFC radyosuna erişim engellenir. Görünmeyen web sayfalarında NFC içeriği alma ve gönderme işlemi askıya alınır ve web sayfası tekrar görünür hale geldiğinde devam ettirilir.

Sayfa Görünürlük API'si sayesinde doküman görünürlüğünün ne zaman değiştiğini izleyebilirsiniz.

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

Yemek Kitabı

Başlamanıza yardımcı olacak bazı kod örnekleri aşağıda verilmiştir.

İzin olup olmadığını kontrol etme

Permissions API, "nfc" izninin verilip verilmediğini kontrol etmenize olanak tanır. Bu örnekte, erişim daha önce verilmişse NFC etiketlerinin kullanıcı etkileşimi olmadan nasıl taranacağı veya aksi takdirde bir düğmenin nasıl gösterileceği gösterilmektedir. Aynı mekanizmanın, arka planda aynı izni kullandığı için NFC etiketlerine yazmak için de çalıştığını unutmayın.

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 işlemlerini iptal etme

AbortController ilkelini kullanmak, NFC işlemlerini iptal etmeyi kolaylaştırır. Aşağıdaki örnekte, bir AbortController öğesinin signal değerinin NDEFReader scan(), makeReadOnly(), write() yöntemlerinin seçenekleri aracılığıyla nasıl iletileceği ve aynı anda her iki NFC işleminin de nasıl iptal edileceği gösterilmektedir.

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

Yazdıktan sonra okuma

AbortController ilkeliyle birlikte write() ve ardından scan() kullanıldığında, NFC etiketine mesaj yazıldıktan sonra etiket okunabilir. Aşağıdaki örnekte, NFC etiketine nasıl kısa mesaj yazılacağını ve NFC etiketindeki yeni mesajın nasıl okunacağını gösterilmektedir. Üç saniye sonra taramayı durdurur.

// 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.

Metin kaydını okuma ve yazma

Metin kaydı data, encoding kaydı özelliğiyle örneklendirilmiş bir TextDecoder ile kod çözülebilir. Metin kaydının dilinin lang mülkü aracılığıyla kullanılabildiğini unutmayın.

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

Basit bir metin kaydı yazmak için NDEFReader write() yöntemine bir dize iletin.

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

Metin kayıtları varsayılan olarak UTF-8'dir ve geçerli belgenin dilini varsayar ancak özel bir NDEF kaydı oluşturmak için her iki özellik de (encoding ve lang) tam söz dizimi kullanılarak belirtilebilir.

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 kaydını okuma ve yazma

Kaydın data değerini çözmek için TextDecoder değerini kullanın.

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

URL kaydı yazmak için NDEFReaderwrite() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında bulunan URL kaydı, recordType anahtarı "url" olarak ayarlanmış ve data anahtarı URL dizesine ayarlanmış bir nesne olarak tanımlanır.

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

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

MIME türü kaydını okuma ve yazma

MIME türü kaydının mediaType mülkü, data'un kodunun doğru şekilde çözülebilmesi için NDEF kayıt yayının MIME türünü temsil eder. Örneğin, JSON metninin kodunu çözmek için JSON.parse öğesini, resim verilerinin kodunu çözmek için ise bir resim öğesini kullanın.

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 türü kaydı yazmak için NDEFReaderwrite() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında bulunan MIME türü kaydı, recordType anahtarı "mime" olarak ayarlanmış, mediaType anahtarı içeriğin gerçek MIME türüne ayarlanmış ve data anahtarı ArrayBuffer olabilecek veya ArrayBuffer'e bir görünüm sağlayan bir nesneye ayarlanmış bir nesne olarak tanımlanır (ör. 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] });

Mutlak URL kaydı okuma ve yazma

data mutlak URL kaydının kodu, basit bir TextDecoder ile çözülebilir.

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

Mutlak URL kaydı yazmak için NDEFReader write() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında bulunan absolute-URL kaydı, recordType anahtarı "absolute-url" olarak ayarlanmış ve data anahtarı URL dizesine ayarlanmış bir nesne olarak tanımlanır.

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

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

Akıllı poster kaydını okuma ve yazma

Akıllı poster kaydı (dergi reklamlarında, broşürlerde, reklam panolarında vb. kullanılır), bazı web içeriklerini yükü olarak NDEF mesajı içeren bir NDEF kaydı olarak tanımlar. data değerini akıllı poster kaydında bulunan bir kayıt listesine dönüştürmek için record.toRecords() işlevini çağırın. Bir URL kaydı, başlık için bir metin kaydı, resim için bir MIME türü kaydı ve akıllı poster kaydının türü, işlemi ve boyutu için sırasıyla ":t", ":act" ve ":s" gibi bazı özel yerel tür kayıtları içermelidir.

Yerel tür kayıtları yalnızca kapsayıcı NDEF kaydının yerel bağlamı içinde benzersizdir. Türlerin anlamı, içeren kaydın yerel bağlamı dışında önemli olmadığında ve depolama alanı kullanımı katı bir kısıtlama olduğunda bunları kullanın. Web NFC'de yerel türdeki kayıt adları her zaman : ile başlar (ör. ":t", ":s", ":act"). Bu, bir metin kaydını yerel türdeki bir metin kaydından ayırt etmek içindir.

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

Akıllı poster kaydı yazmak için NDEFReader write() yöntemine bir NDEF mesajı iletin. NDEF mesajında bulunan akıllı poster kaydı, recordType anahtarı "smart-poster" olarak ayarlanmış ve data anahtarı akıllı poster kaydında bulunan bir NDEF mesajını (tekrar) temsil eden bir öğe olarak tanımlanır.

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

Harici tür kaydını okuma ve yazma

Uygulama tanımlı kayıtlar oluşturmak için harici tür kayıtlarını kullanın. Bunlar, toRecords() ile erişilebilen bir yük olarak NDEF mesajı içerebilir. Bu ad, veren kuruluşun alan adını, iki nokta işaretini ve en az bir karakter uzunluğunda bir tür adını (ör. "example.com:foo") içerir.

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.
    }
  }
}

Harici türde bir kayıt yazmak için NDEFReader write() yöntemine bir NDEF ileti sözlüğü iletin. NDEF mesajında bulunan harici tür kaydı, harici türün adına ayarlanmış bir recordType anahtarı ve harici tür kaydında bulunan NDEF mesajını temsil eden bir nesneye ayarlanmış bir data anahtarı içeren bir nesne olarak tanımlanır. data anahtarının bir ArrayBuffer olabileceğini veya bir ArrayBuffer'a (ör. Uint8Array, DataView) bakış sağlayabileceğini unutmayın.

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

Boş bir kaydı okuma ve yazma

Boş bir kayıtta yük yoktur.

Boş bir kayıt yazmak için NDEFReaderwrite() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında yer alan boş kayıt, recordType anahtarı "empty" olarak ayarlanmış bir nesne olarak tanımlanır.

const emptyRecord = {
  recordType: "empty"
};

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

Tarayıcı desteği

Web NFC, Android'de Chrome 89'da kullanılabilir.

Geliştirici İpuçları

Web NFC ile çalışmaya başladığımda bilmeyi isterdim dediğim şeylerin listesini aşağıda bulabilirsiniz:

  • Android, Web NFC'nin çalışmaya başlamasından önce NFC etiketlerini işletim sistemi düzeyinde işler.
  • NFC simgesini material.io adresinde bulabilirsiniz.
  • Gerekirse bir kaydı kolayca tanımlamak için NDEF kaydı id'ü kullanın.
  • NDEF'yi destekleyen biçimlendirilmemiş bir NFC etiketi, boş türün tek bir kaydını içerir.
  • Aşağıda gösterildiği gibi, Android uygulama kaydı yazmak kolaydır.
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] });

Demolar

Resmi örneği deneyin ve bazı harika Web NFC demolarına göz atın:

Chrome Geliştirici Zirvesi 2019'daki Web NFC kartları demosu

Geri bildirim

Web NFC Topluluk Grubu ve Chrome Ekibi, Web NFC ile ilgili düşüncelerinizi ve deneyimlerinizi öğrenmekten memnuniyet duyar.

API tasarımı hakkında bilgi verin

API ile ilgili beklendiği gibi çalışmayan bir şey var mı? Yoksa fikrinizi uygulamak için ihtiyaç duyduğunuz yöntemler veya özellikler eksik mi?

Web NFC GitHub deposunda spesifikasyon sorunu bildirin veya mevcut bir soruna düşüncelerinizi ekleyin.

Uygulamayla ilgili sorunları bildirme

Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?

https://new.crbug.com adresinden hata kaydı oluşturun. Mümkün olduğunca fazla ayrıntı eklediğinizden, hatayı yeniden oluşturmayla ilgili basit talimatlar sağladığınızdan ve Bileşenler'in Blink>NFC olarak ayarlandığından emin olun. Glitch, hızlı ve kolay yeniden oluşturma işlemlerini paylaşmak için mükemmel bir araçtır.

Destek gösterme

Web NFC'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome ekibinin özelliklere öncelik vermesine yardımcı olur ve diğer tarayıcı tedarikçi firmalarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.

#WebNFC hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin ve bu özelliği nerede ve nasıl kullandığınızı bize bildirin.

Faydalı bağlantılar

Teşekkür ederiz

Web NFC'yi uygulayan Intel ekibine çok teşekkür ederiz. Google Chrome, Chromium projesini ilerletmek için birlikte çalışan bir taahhütte bulunanlar topluluğuna dayanır. Chromium'a katkıda bulunanların tümü Google çalışanı değildir. Bu katkıda bulunanlar özel olarak takdir edilmeyi hak ediyor.