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

NFC etiketlerine okuma ve yazma işlemleri artık mümkün.

François Beaufort
François Beaufort

Web NFC nedir?

NFC, Near Field Communications (Yakın Alan İletişimi) anlamına gelir.13,56 MHz'de çalışan, 10 cm'den daha kısa mesafedeki cihazlar arasında iletişimi ve 424 kbit/sn'ye kadar iletim hızını sağlayan kısa mesafeli bir kablosuz teknolojidir.

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

Telefon, veri alışverişi için NFC etiketine güç veriyor
NFC işleminin şeması

Önerilen kullanım alanları

Web NFC, NDEF verilerini okuma ve yazma işlemlerinin güvenlik özellikleri daha kolay ölçülebildiği için NDEF ile sınırlıdır. Düşük düzeyde G/Ç işlemleri (ör. ISO-DEP, NFC-A/B, NFC-F), eşler arası iletiş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 yakınındaki bir NFC kartına dokundurduğunda sergiyle ilgili ek bilgiler gösterebilir.
  • Envanter yönetim siteleri, içeriklerle ilgili bilgileri güncellemek için bir konteynerdeki NFC etiketine veri okuyabilir veya yazabilir.
  • Konferans siteleri, etkinlik sırasında NFC rozetlerini taramak ve üzerlerine yazılan bilgilerin daha fazla değiştirilmesini önlemek için bu özelliği kullanabilir.
  • Siteler, cihaz veya hizmet sağlama senaryoları için gereken ilk sırları paylaşmak ve yapılandırma verilerini operasyonel modda dağıtmak için bu hizmeti kullanabilir.
Telefonun birden fazla NFC etiketini taraması
NFC envanter yönetimi gösterimi

Mevcut durum

Step Durum
1. Açıklayıcı oluşturma Tamamlandı
2. Spesifikasyonun ilk taslağını oluşturma Tamamlandı
3. Geri bildirim toplama ve tasarım üzerinde yineleme yapma 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 simgesi, 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 aramalar tarafından döndürülen söz reddedilir. NDEFReader açıklarken ayrıntılı bilgi vereceğim.

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

Terminoloji

NFC etiketi pasif bir NFC cihazıdır. Yani etkin bir NFC cihazı (ör. telefon) yakındayken manyetik indüksiyonla çalışır. NFC etiketleri; çıkartma, kredi kartı, kol bandı gibi birçok biçimde ve tarzda olabilir.

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

NDEFReader nesnesi, NDEF etiketi yaklaştığında okuma ve/veya yazma işlemlerini hazırlama işlevini kullanıma sunan Web NFC'deki 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 iletileriyle işlem yapmak ve aralık içindeki NFC etiketlerine NDEF iletileri yazmak için kullanılır.

NDEF'yi destekleyen bir NFC etiketi, yapışkanlı not kağıdına benzer. Herkes okuyabilir ve salt okunur değilse herkes yazabilir. Bir veya daha fazla NDEF kaydını kapsayan tek bir NDEF ileti içerir. Her NDEF kaydı, veri yükü ve ilişkili tür bilgileri içeren bir ikili 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ının şeması

NFC etiketlerini tarama

NFC etiketlerini taramak için önce yeni bir NDEFReader nesnesi oluşturun. scan() işlevini çağırmak bir promise döndürür. Daha önce erişim izni verilmediyse kullanıcıdan izin istenebilir. Aşağıdaki koşulların tümü karşılandığında söz yerine getirilir:

  • Yalnızca dokunma hareketi veya fare tıklaması gibi bir kullanıcı hareketine yanıt olarak çağrıldı.
  • Kullanıcı, web sitesinin NFC cihazlarıyla etkileşimde bulunmasına izin vermiş olmalıdır.
  • Kullanıcının telefonu NFC'yi destekliyor olmalıdır.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.

Promise çözümlendikten sonra, gelen NDEF mesajları bir etkinlik işleyici aracılığıyla reading etkinliklerine abone olarak kullanılabilir. Ayrıca, uyumsuz NFC etiketleri yakındayken bildirim almak için readingerror etkinliklerine 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ındayken NDEFReadingEvent etkinliği tetiklenir. Bu mülkte, mülke özgü iki özellik bulunur:

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

NDEF mesajının içeriğini okumak için message.records üzerinden döngü oluşturun ve recordType'lerine göre data üyelerini uygun şekilde işleyin. data üyesi, verilerin UTF-16 olarak kodlandığı durumların işlenmesine olanak tanıdığı için 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 etiketleri yazma

NFC etiketlerine yazmak için önce yeni bir NDEFReader nesnesi oluşturun. Calling write() bir promise döndürür. Daha önce erişim izni verilmemişse 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 çö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 cihazlarıyla etkileşimde bulunmasına izin vermiş olmalıdır.
  • Kullanıcının telefonu NFC'yi destekliyor olmalıdır.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.
  • Kullanıcı bir NFC etiketine dokunduğunda NDEF mesajı başarıyla yazılır.

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

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

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

Bir NFC etiketine birden fazla kayıt yazmak da mümkündür.

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 overwrite özelliğini write() yöntemine iletilen seçeneklerde false olarak ayarlayın. Bu durumda, NFC etiketinde zaten bir NDEF mesajı varsa 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 hale getirme

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 okunur hale getirebilirsiniz. Bu işlem tek yönlüdür ve geri alınamaz. Salt okunur hale getirilen NFC etiketlerine artık yazılamaz.

NFC etiketlerini salt okunur hale getirmek için önce yeni bir NDEFReader nesnesi oluşturun. Calling makeReadOnly() bir promise döndürür. Daha önce erişim izni verilmemişse kullanıcıdan izin istenebilir. Aşağıdaki koşulların tümü karşılandığında söz çözümlenir:

  • Yalnızca dokunma hareketi veya fare tıklaması gibi bir kullanıcı hareketine yanıt olarak çağrıldı.
  • Kullanıcı, web sitesinin NFC cihazlarıyla etkileşimde bulunmasına izin vermiş olmalıdır.
  • Kullanıcının telefonu NFC'yi destekliyor olmalıdır.
  • Kullanıcı, telefonunda NFC'yi etkinleştirmiş olmalıdır.
  • Kullanıcı bir NFC etiketine dokunmuş ve NFC etiketi başarıyla salt okunur hale getirilmiştir.
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 yazdı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(), Chrome 100 veya sonraki sürümlerde Android'de kullanılabildiğinden bu özelliğin aşağıdakilerle desteklenip desteklenmediğini kontrol edin:

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

Güvenlik ve izinler

Chrome Ekibi, kullanıcı kontrolü, şeffaflık ve ergonomi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme'de tanımlanan temel ilkeleri kullanarak Web NFC'yi tasarlayıp uygulamıştır.

NFC, kötü amaçlı web sitelerinin erişebileceği bilgilerin kapsamını genişlettiği için kullanıcıların NFC kullanımıyla ilgili farkındalığını ve kontrolünü en üst düzeye çıkarmak amacıyla NFC'nin kullanılabilirliği kısıtlanmıştır.

Web sitesindeki Web NFC isteminin ekran görüntüsü
Web NFC kullanıcı istemi

Web NFC yalnızca üst düzey çerçevelerde ve güvenli göz atma bağlamlarında (yalnızca HTTPS) kullanılabilir. Kaynaklar, kullanıcı hareketi (ör.düğme tıklama) işlerken önce "nfc" izni istemelidir. NDEFReader scan(), write() ve makeReadOnly() yöntemleri, daha önce erişim izni verilmemişse kullanıcı istemini 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ın hedef NFC etiketinin üzerine getirilmesi gibi gerçek dünyadaki fiziksel hareketlerin 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 bir NFC etiketine dokunduğunda web sayfası görünür olmalıdır. Tarayıcı, dokunma işlemini belirtmek için dokunsal geri bildirim kullanır. Ekran kapalıysa veya cihaz kilitliyse NFC radyosuna erişim engellenir. Görünür olmayan web sayfalarında NFC içeriği alma ve gönderme işlemleri askıya alınır. Bu işlemler, web sayfası tekrar görünür hâle geldiğinde devam eder.

Page Visibility API 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 örneklerini aşağıda bulabilirsiniz.

İzinleri kontrol etme

Permissions API, "nfc" izninin verilip verilmediğini kontrol etmeye olanak tanır. Bu örnekte, erişim daha önce verildiyse kullanıcı etkileşimi olmadan NFC etiketlerinin nasıl taranacağı, aksi takdirde ise bir düğmenin nasıl gösterileceği açıklanmaktadır. Aynı mekanizmanın, arka planda aynı izni kullandığı için NFC etiketlerine yazma işleminde de geçerli olduğunu 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 temel öğesini kullanarak NFC işlemlerini kolayca iptal edebilirsiniz. Aşağıdaki örnekte, AbortController öğesinin signal değerini NDEFReader scan(), makeReadOnly(), write() yöntemlerinin seçenekleri üzerinden nasıl ileteceğiniz ve her iki NFC işlemini aynı anda nasıl iptal edeceğiniz 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

write() ve ardından AbortController ilkelini kullanarak scan(), bir NFC etiketine mesaj yazdıktan sonra etiketi okumayı mümkün kılar. Aşağıdaki örnekte, NFC etiketine nasıl kısa mesaj yazılacağı ve NFC etiketindeki yeni mesajın nasıl okunacağı 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ı okuma ve yazma

data metin kaydının kodu, encoding kaydı özelliğiyle oluşturulan bir TextDecoder ile çözülebilir. Metin kaydının dilinin lang özelliği 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 mevcut belgenin dilini varsayar ancak özel bir NDEF kaydı oluşturmak için her iki özellik (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 kodunu çözmek için TextDecoder 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 NDEFReader write() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında bulunan URL kaydı, recordType anahtarı "url" olarak ve data anahtarı URL dizesi olarak ayarlanmış bir nesne şeklinde 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

Bir MIME türü kaydının mediaType özelliği, data öğesinin düzgün şekilde kodunun çözülebilmesi için NDEF kaydı yükünün MIME türünü temsil eder. Örneğin, JSON metninin kodunu çözmek için JSON.parse, görüntü verilerinin kodunu çözmek için ise bir görüntü öğesi 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 NDEFReader write() yöntemine bir NDEF ileti sözlüğü iletin. NDEF iletisinde bulunan MIME türü kaydı, recordType anahtarı "mime" olarak ayarlanmış, mediaType anahtarı içeriğin gerçek MIME türü olarak ayarlanmış ve data anahtarı ArrayBuffer olabilen veya ArrayBuffer üzerinde görünüm sağlayan bir nesne olarak ayarlanmış (ör. Uint8Array, DataView) bir nesne olarak tanımlanır.

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

Mutlak URL kaydı data, basit bir TextDecoder ile kod çö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 mutlak URL kaydı, recordType anahtarı "absolute-url" olarak ve data anahtarı URL dizesi olarak ayarlanmış bir nesne şeklinde 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, el ilanlarında, bilboardlarda vb. kullanılır), bazı web içeriklerini yük olarak NDEF mesajı içeren bir NDEF kaydı olarak tanımlar. data öğesini, akıllı poster kaydında bulunan kayıtların listesine dönüştürmek için record.toRecords() işlevini çağırın. URL kaydı, başlık için metin kaydı, resim için 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ı olmalıdır.

Yerel tür kayıtları yalnızca kapsayan NDEF kaydının yerel bağlamında benzersizdir. Türlerin anlamı, kapsayan 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. Yerel tür kayıt adları, Web NFC'de her zaman : ile başlar (ör. ":t", ":s", ":act"). Bu, örneğin bir metin kaydını yerel tür metin kaydından ayırt etmek için kullanılır.

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 NDEF mesajını (bir kez daha) temsil eden bir nesne 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 NDEF mesajı içerebilir. Adları, veren kuruluşun alan adını, iki nokta üst üste 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ı, recordType anahtarı harici türün adına ayarlanmış ve data anahtarı, harici tür kaydında bulunan bir NDEF mesajını temsil eden bir nesneye ayarlanmış bir nesne olarak tanımlanır. data anahtarının ArrayBuffer olabileceğini veya ArrayBuffer hakkında bir görünüm sağlayabileceğini (ör. Uint8Array, DataView) 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ş kayıtta yük yoktur.

Boş bir kayıt yazmak için NDEFReader write() yöntemine bir NDEF mesaj sözlüğü iletin. NDEF mesajında bulunan 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, Chrome 89'da Android'de kullanılabilir.

Geliştiriciler için İpuçları

Web NFC ile oynamaya başladığımda bilmeyi istediğim şeylerin listesini aşağıda bulabilirsiniz:

  • Android, Web NFC çalışır duruma gelmeden önce NFC etiketlerini işletim sistemi düzeyinde işler.
  • material.io adresinde NFC simgesini bulabilirsiniz.
  • Gerekli olduğunda kaydı kolayca tanımlamak için NDEF kaydını id kullanın.
  • NDEF'yi destekleyen biçimlendirilmemiş bir NFC etiketi, boş türde tek bir kayıt 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ı Web NFC demolarına göz atın:

Chrome Geliştirici Zirvesi 2019'da 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 durum var mı? Yoksa fikrinizi uygulamak için eksik yöntemler veya özellikler mi var?

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

Uygulamayla ilgili sorun bildirme

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

https://new.crbug.com adresinden hata bildiriminde bulunun. Mümkün olduğunca fazla ayrıntı eklediğinizden, hatayı yeniden oluşturmak için basit talimatlar sağladığınızdan ve Bileşenler'in Blink>NFC olarak ayarlandığından emin olun.

Desteğinizi gösterme

Web NFC'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, Chrome Ekibi'nin özellikleri önceliklendirmesine yardımcı olur ve diğer tarayıcı satıcılarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.

#WebNFC hashtag'ini kullanarak @ChromiumDev'e tweet gönderin ve nerede, nasıl kullandığınızı bize bildirin.

Faydalı bağlantılar

Teşekkür

Web NFC'yi uygulayan Intel'deki arkadaşlara çok teşekkür ederiz. Google Chrome, Chromium projesini ileriye taşımak için birlikte çalışan bir geliştirici topluluğuna bağlıdır. Her Chromium committer'ı Google çalışanı değildir ve bu katkıda bulunanlar özel bir takdiri hak eder.