B4i Library NFCEx class - Write Ndef tags

Erel

Administrator
Staff member
Licensed User
Starting from iOS 13 it is possible to write Ndef tags.
NFCEx adds writing support to iNFC library.

Before you start with writing, make sure to follow the "reading" tutorial and get the example working: https://www.b4x.com/android/forum/threads/nfc-reading-ndef-tags.84784/#post-536918
It requires some configuration.

With NFCEx class the reading and writing is done inside the class. NFCEx is not built as a library. You are expected to modify Scan method.

The Scan method:
B4X:
Public Sub Scan (DialogMessage As String)
   NFC.Scan(DialogMessage)
   Wait For NFC_TagConnected (Success As Boolean, Tag As Object)
   If Success Then
       Dim no As NativeObject = NFC
       no.RunMethod("checkStatus:", Array(Tag))
       Wait For NFC_Status(Success As Boolean, Status As Int, Capacity As Int)
       '1 = not supported
       '2 = read / wrute
       '3 = read only
       Main.LogMsg("Status: " & Status)
       no.RunMethod("read:", Array(Tag)) 'read previous value
       Wait For NFC_TagRead (Success As Boolean, Messages As List)
       If Success Then
           ReadMessages (Messages)
           If Status = 2 Then
               Dim msg As Object = CreateTextNdefMessage("This is the value that will be written") '<-- write new value
               no.RunMethod("write::", Array(Tag, msg))
               Wait For NFC_WriteComplete (Success As Boolean)
               Main.LogMsg("Write complete: " & Success)
           End If
       End If
   End If
   NFC.StopScan
End Sub
The steps are:

1. Scan for tags.
2. Check the connected tag state.
3. Read and / or write.
4. Stop scanning.

As the code is based on iOS 13 it must be compiled with Xcode 11+. Hosted builders run Xcode 11.

Bytes message: https://www.b4x.com/android/forum/threads/nfcex-class-write-ndef-tags.110726/#post-691504
URL message: https://www.b4x.com/android/forum/threads/nfcex-class-write-ndef-tags.110726/#post-692860
 

Attachments

Last edited:

walterf25

Expert
Licensed User
Starting from iOS 13 it is possible to write Ndef tags.
NFCEx adds writing support to iNFC library.

Before you start with writing, make sure to follow the "reading" tutorial and get the example working: https://www.b4x.com/android/forum/threads/nfc-reading-ndef-tags.84784/#post-536918
It requires some configuration.

With NFCEx class the reading and writing is done inside the class. NFCEx is not built as a library. You are expected to modify Scan method.

The Scan method:
B4X:
Public Sub Scan (DialogMessage As String)
   NFC.Scan(DialogMessage)
   Wait For NFC_TagConnected (Success As Boolean, Tag As Object)
   If Success Then
       Dim no As NativeObject = NFC
       no.RunMethod("checkStatus:", Array(Tag))
       Wait For NFC_Status(Success As Boolean, Status As Int, Capacity As Int)
       '1 = not supported
       '2 = read / wrute
       '3 = read only
       Main.LogMsg("Status: " & Status)
       no.RunMethod("read:", Array(Tag)) 'read previous value
       Wait For NFC_TagRead (Success As Boolean, Messages As List)
       If Success Then
           ReadMessages (Messages)
           If Status = 2 Then
               Dim msg As Object = CreateTextNdefMessage("This is the value that will be written") '<-- write new value
               no.RunMethod("write::", Array(Tag, msg))
               Wait For NFC_WriteComplete (Success As Boolean)
               Main.LogMsg("Write complete: " & Success)
           End If
       End If
   End If
   NFC.StopScan
End Sub
The steps are:

1. Scan for tags.
2. Check the connected tag state.
3. Read and / or write.
4. Stop scanning.

As the code is based on iOS 13 it must be compiled with Xcode 11+. Currently the online builders are still running Xcode 10.
Thank you Erel, this works great for sending Text data, but how about sending Data in Bytes?

Thanks,
Walter
 

walterf25

Expert
Licensed User
You will need to build the payload yourself. There is no API for binary messages.

Another option is to use base64 strings.
I'm not sure i follow, i have a String similar to this "010005000010000000001" and I need to send it to the tag in bytes, how do I build the payload?

Walter
 

walterf25

Expert
Licensed User
The class I posted supports text messages. There is no method to write binary data. You will need to learn the NDEF payload protocol and implement it with: https://developer.apple.com/documen...fpayload/3043842-initwithformat?language=objc
Ah yes, that's what I've been trying to do for the past few hours, though I'm not having much luck, I'm confused with the parameters that need to be passed to the initWithFormat Method, I will get some rest and continue playing with it tomorrow.

Thanks,
Walter
 

walterf25

Expert
Licensed User
After a few days of banging my head against the table, I finally figured out how to send data to an NFC Tag in Bytes, I have modifed @Erel's NFCEx CreateTextNDEFMessage function and by using the method initWithFormat you are now able to send data to an NFC Tag in a binary format,the initWithFormat method takes 4 parameters, Format, type, identifier and the payload according to NFCCore documentation here.

All the parameters except for NFCTypeFormat needs to be of NSData type.

I'm not sure if there would be an easier way to do it but here's my solution, not sure if Erel would want to integrate it into his Example?

B4X:
Private Sub CreateByteNdefMessage (Text As String) As Object
    Dim payload As NativeObject
    Dim msg2 As NdefRecord
    Dim format As Int = msg2.FORMAT_NFCExternal ''in my case the tag is identified as NFCExternal type format which is equals to 4
    Log("format: " & format)
    Dim typ() As Byte = Array As Byte() ''For the Type parameter just create an empty array and convert it to NSData
    Dim typp As NativeObject
    typp = typp.ArrayToNSData(typ)
    Dim identifier As String = "ZMF/Clock"  'The identifier parameter identifies the payload, it can be "Text/Plain" or any other string that identifies the type of payload
    Dim identifier2() As Byte = identifier.GetBytes("UTF8")  'get the byte array
    Dim identifier3 As NativeObject   '
    identifier3 = identifier3.ArrayToNSData(identifier2)   'Convert it to NSData type
    Dim message() As Byte = Text.GetBytes("UTF8")   'Get the payload's Text message and convert it to Bytes
    Dim data As NativeObject
    data = data.ArrayToNSData(message)  'Convert the message's bytes to NSData type
    payload = payload.Initialize("NFCNDEFPayload").RunMethod("alloc", Null).RunMethod("initWithFormat:type:identifier:payload:", Array(format, typp, identifier3, data)) 'Initialize the Payload method with initWithFormat and pass the above created parameters
    Dim payloads As List = Array(payload)
    Dim ndef As NativeObject
    ndef = ndef.Initialize("NFCNDEFMessage").RunMethod("alloc", Null).RunMethod("initWithNDEFRecords:", Array(payloads))
    Return ndef
End Sub
Hope this is of help to someone else.

Regards,
Walter
 
Last edited by a moderator:

Erel

Administrator
Staff member
Licensed User
Creating a URL message:
B4X:
Private Sub CreateURLNdefMessage (Url As String) As Object
   Dim u As NativeObject
   u = u.Initialize("NSURL").RunMethod("URLWithString:", Array(Url))
   Dim payload As NativeObject
   payload = payload.Initialize("NFCNDEFPayload").RunMethod("wellKnownTypeURIPayloadWithURL:", Array(u))
   Dim payloads As List = Array(payload)
   Dim ndef As NativeObject
   ndef = ndef.Initialize("NFCNDEFMessage").RunMethod("alloc", Null).RunMethod("initWithNDEFRecords:", Array(payloads))
   Return ndef
End Sub
 
Top