Come si scrive e si blocca un tag NDEF da un'applicazione iOS?
Apri una sessione NDEF che non finisca alla prima lettura, connettiti al tag che il delegato riceve, e interroga stato e capacità prima di scrivere tutto il messaggio in una sola chiamata. writeLock mette il tag in sola lettura per sempre. Tutto avviene dentro una sessione sola, quindi il telefono resta fermo finché l'applicazione non dice di aver finito.
Una sessione che resta aperta
La scrittura avviene dentro una sessione di lettura, quindi la sessione non deve finire alla prima lettura. La nota di Apple sull'inizializzatore dice di passare falso a invalidateAfterFirstRead in una sessione che scrive, il che la tiene attiva finché l'applicazione non ha finito.
Il delegato realizza readerSession(_:didDetect:), disponibile da iOS 13, per ricevere oggetti NFCNDEFTag invece che messaggi, poi chiama connect(to:) su quello che vuole. Un tag resta connesso finché l'applicazione non si connette a un altro o non riavvia il sondaggio.
Due tag nel campo sono un caso reale. L'esempio di lettore di tag di Apple conta i tag prima di scrivere, chiede tramite alertMessage di toglierli tutti, e riavvia il sondaggio dopo una breve pausa invece di scrivere su quello sbagliato.
Prima lo stato e la capacità
queryNDEFStatus rende due valori che decidono se andare avanti: uno stato, notSupported, readOnly o readWrite, e la capacità, il messaggio NDEF più grande che il tag può conservare, in byte.
Confronta la capacità con il messaggio prima di scrivere. Un messaggio che non ci sta fallisce con ndefReaderSessionErrorTagSizeTooSmall, dopo che chi usa il telefono lo ha tenuto fermo per niente.
La scrittura
writeNDEF(_:) salva tutto il messaggio in una chiamata sola e riferisce al proprio gestore di completamento, oppure solleva un errore nella sua forma asincrona. Il suo riferimento lo lega allo stato: scrivi solo quando queryNDEFStatus ha reso readWrite.
Gli errori dicono quale passo è fallito: ndefReaderSessionErrorTagNotWritable per un tag in sola lettura, ndefReaderSessionErrorTagSizeTooSmall per un messaggio troppo lungo, ndefReaderSessionErrorTagUpdateFailure per un aggiornamento che non è arrivato in fondo, e readerTransceiveErrorTagConnectionLost quando il tag ha lasciato il campo.
Dopo un aggiornamento fallito o una connessione persa, rileggi il tag prima di riprovare. La scrittura può essersi fermata a metà, il caso che la pagina della scrittura interrotta copre dal lato di chi usa il telefono.
Quando la scrittura riesce, dillo nel foglio e chiudi la sessione con invalidate(). Fino ad allora, chi usa il telefono non sa che lo può muovere.
Il blocco è permanente
writeLock() porta lo stato del tag a sola lettura. La sua documentazione spiega che aggiorna il byte della condizione di accesso in scrittura nel controllo del file NDEF del tag, e la chiama un'azione permanente su cui non si torna indietro.
Tienila come azione separata dalla scrittura, presa una volta che il contenuto è stato riletto e verificato sull'altra piattaforma. Se bloccare sia il caso è coperto dalla pagina del blocco.
Quello che le chiamate NDEF non sanno fare
Le chiamate NDEF si fermano al messaggio. Una password, un contatore o una pagina di configurazione sono comandi del chip, raggiunti tramite una sessione di tag e il protocollo proprio del tag, come sendMiFareCommand su un tag MIFARE, con i comandi presi dalla scheda tecnica del chip.
Quel lavoro esce del tutto dalla sessione NDEF, ed è per questo che la scelta della sessione viene prima, nella pagina delle sessioni.
Domande frequenti
Perché la mia scrittura fallisce con ndefReaderSessionErrorTagSizeTooSmall?
Il messaggio è più grande di quanto il tag possa conservare. queryNDEFStatus rende la capacità in byte, quindi confronta i due prima di scrivere.
Un tag bloccato si può sbloccare da iOS?
No. Apple descrive writeLock come un'azione permanente su cui non si torna indietro.
Un'applicazione iPhone può mettere una password su un tag?
Non con le chiamate NDEF. Una password si mette con comandi del chip, inviati in una sessione di tag tramite il protocollo del tag, con i comandi presi dalla scheda tecnica del chip.
Perché la sessione deve restare aperta dopo la lettura?
La scrittura avviene dentro di essa. Con invalidateAfterFirstRead a vero, la sessione finisce dopo la prima lettura e non lascia niente con cui scrivere.