Commercial SupportGuaranteed response times on Shiny bug fixes, straight from the maintainers. Plans from US$1,500 a year.Guaranteed response times on Shiny bug fixes, straight from the maintainers. Plans from US$1,500 a year.See the plans
AI Conversations, Speech, & Audio ReleaseHave a full conversation with AI, use speech commands, and interact with audio content seamlessly.Have a full conversation with AI, use speech commands, and interact with audio content seamlessly.
BLE Hubs 1.0Think SignalR for BLE!Think SignalR for BLE!Hub it up!
UniHub 1.0Universal Hubs - SignalR Styled Hub BLE or HTTP - Why not both!?Universal Hubs - SignalR Styled Hub BLE or HTTP - Why not both!?YES PLEASE!
NFC
The NFC bridge reads and writes NDEF tags (URLs, text, MIME payloads, smart posters and Android app records) for
the page. It’s built on Shiny.Nfc. A WebView has no Web NFC (neither Android’s WebView nor WKWebView
implements it), so this is the page’s only way to reach the NFC radio.
Android needs <uses-permission android:name="android.permission.NFC" />. iOS needs NFCReaderUsageDescription and
the com.apple.developer.nfc.readersession.formats entitlement with TAG. See Shiny.Nfc.
read answers 204 (null) when the scan ended before a tag was tapped, for example when the user dismissed the iOS
sheet. write then answers { written: false }. Aborting the request ends the scan.
To keep scanning, listen for nfc.tag first (the scan answers 409 not_listening otherwise), then start it. Each tag
arrives with its message already read:
// subscribe before starting - the scan needs a listener
conststopTags=await nfc.onTag(tag=> {
console.log(tag.identifier, tag.records); // identifier is null on iOS
});
await nfc.onScanEnded(e=> console.log("scan ended:", e.reason)); // Stopped, Dismissed or Failed
await nfc.startScan({ alertMessage: "Tap your badge" });
// …
await nfc.stopScan();
The scan also stops when the page stops listening for nfc.tag, so a page that navigates away doesn’t leave the iOS
sheet up. Only one NFC session runs at a time: a one-tap call during a scan answers 409 nfc_busy. Before starting, the
scan answers 409 nfc_unavailable when NFC is switched off on Android.
A native tag only exists while the scan is handling it, so to write to or lock a tag from nfc.tag, scan with
holdSeconds (up to 60). The scan then holds each tag until the page releases it or the hold runs out. A tag tapped
meanwhile waits its turn.
await nfc.releaseTag(tag.tagId); // move on to the next tag now
});
await nfc.startScan({ holdSeconds: 10 });
tagId is the bridge’s handle for the held tag, not its UID. Once the tag is released, its routes answer
404 tag_not_held. With holdSeconds left at 0, the default, every tag is released straight away. That’s the setting
for read-only scanning, such as a check-in kiosk.
lockTag(tagId) makes the tag read-only. This is permanent: no app can ever write to it again.
A record from a tag carries its raw parts (format, type, base64 payload, id) plus the decoded value for the
common types: uri (URI records and smart posters), text and language, and mimeType.
To write, set exactly one kind per record:
Record
Fields
URI
{ uri }
Text
{ text, language? } (en by default)
MIME
{ mimeType, data } (base64)
Android Application Record
{ androidPackage }: opens, or offers to install, the app
Raw
{ format, type, data }, for example { format: "External", type: "example.com:thing", data }
Any record can also set id. A message has 1 to 32 records and at most 32 KB.
Waits for one tag and reads it. Null when the scan ended first (iOS: the user dismissed the sheet) or the request was aborted. Fails with 422 invalid_ndef when the tag holds bytes that are not NDEF.
C#INfcBridge.ReadAsyncTSNfcBridge.read
Body
application/json · NfcReadRequestNfcReadRequest · 1 field
alertMessage
string | null
iOS: the prompt on the scan sheet, such as "Hold your iPhone near the tag".
Response
200NfcReadResult· or 204 when there is noneNfcReadResult · 2 fields
identifier
string | null
The tag's UID as hex, or null where the platform does not expose it (iOS).
Waits for one tag and writes a message to it. Fails with 400 for a malformed record, 409 tag_read_only, 413 message_too_large (nothing written) and 410 tag_lost (the tag left mid-write; its previous message may be gone).
Starts a scan session. Each tag fires nfc.tag with its message already read; the session runs until stopScan, the page stops listening, or the platform ends it (nfc.scan). Listen for nfc.tag first, or it answers 409 not_listening.
How long, up to 60, each tag stays available to writeTag and lockTag after nfc.tag fires, unless released sooner. The next tag waits until then. 0 (the default) releases every tag straight away, for read-only scanning.
How long, up to 60, each tag stays available to writeTag and lockTag after nfc.tag fires, unless released sooner. The next tag waits until then. 0 (the default) releases every tag straight away, for read-only scanning.