- From: François Beaufort via GitHub <sysbot+gh@w3.org>
- Date: Tue, 15 Oct 2019 08:39:28 +0000
- To: public-web-nfc@w3.org
The more I think about it, the more I'd like us to get rid of JSON, and even other special casing. I feel like Web NFC is trying to be both an API and a library at the same time. So here's my proposal.
I believe great documentation will make this API shine.
## Proposed spec changes
1. Merge "json" and "opaque" recordType into new "media" recordType
2. IDL changes (see below)
```diff
[Exposed=Window]
interface NDEFRecord {
constructor(NDEFRecordInit recordInit);
readonly attribute NDEFRecordType recordType;
readonly attribute USVString mediaType;
readonly attribute USVString id;
+ readonly attribute DataView? data;
- USVString? text();
- [NewObject] ArrayBuffer? arrayBuffer();
- [NewObject] any json();
sequence<NDEFRecord> toRecords();
};
dictionary NDEFRecordInit {
NDEFRecordType recordType;
USVString mediaType;
USVString id;
any data;
};
```
## Why
- new "data" attribute is a DataView: it is already used in other Web Devices API such as [Web Bluetooth](https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-value), [Web USB](https://wicg.github.io/webusb/#dom-usbisochronousintransferresult-data), [Web HID](https://wicg.github.io/webhid/#dom-hidinputreportevent-data) and is great for handling bytes.
- Using web platform primitives like `TextDecoder` for decoding text tags is really easy and can be reused. Moreover, it allows web developers to specify the encoding (UTF-16 for instance) which, once again, gives back web developer control. This allows us to not try to make the API [smart](https://w3c.github.io/web-nfc/#text-record) about it.
- "mediaType" is required only for "media" recordType instead of requiring "application/json" for "json". Note that documentation will basically say JSON has to be in a media record type: "Text is user facing, don't use it for JSON.
## JS example
```js
async function writeToNfcTag() {
const writer = new NFCWriter();
const records = [
{
recordType: "text",
data: "hello"
},
{
recordType: "url",
data: "https://google.com"
},
{
recordType: "media",
mediaType: "application/json",
data: { key1: "value1", key2: "value2" }
},
{
recordType: "media",
mediaType: "image/png",
data: await (await fetch("image.png")).arrayBuffer()
},
{
recordType: "android.com:pkg", // Known external type
data: new TextEncoder().encode("org.chromium.webapk.ace0b15a6ce931426")
.buffer
},
{
recordType: "example.com:a", // Custom external type
data: Uint8Array.of(1)
}
];
return writer.push({ records });
}
function readNfcTag() {
const reader = new NFCReader();
reader.scan();
reader.onreading = ({ message }) => {
const decoder = new TextDecoder(); // UTF-8 by default
for (const record of message.records) {
const data = record.data; // NEW!
switch (record.recordType) {
case "text":
console.log(`Text: ${decoder.decode(data)}`);
break;
case "url":
console.log(`URL: ${decoder.decode(data)}`);
break;
case "media":
// Let developer handle media case
if (record.mediaType === "application/json") {
console.log(`JSON: ${JSON.parse(decoder.decode(data))}`);
} else if (record.mediaType.startsWith("image/")) {
const blob = new Blob(data, { type: record.mediaType });
const img = document.createElement("img");
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
} else {
console.log(`Media not handled`);
}
break;
case "android.com:pkg":
console.log(`AAR Package Name: ${decoder.decode(data)}`);
break;
case "example.com:a":
console.log(`My custom external type: ${data.getUint8(0)}`);
break;
}
}
};
}
```
--
GitHub Notification of comment by beaufortfrancois
Please view or discuss this issue at https://github.com/w3c/web-nfc/issues/366#issuecomment-542104572 using your GitHub account
Received on Tuesday, 15 October 2019 08:39:30 UTC