The new mobile operating system from Apple iOS 13 is bringing extended support for NFC Type-5 tags (ISO 15693) to applications developers. During the company’s last Worldwide Developers Conference (WWDC), attendees got a talk highlighting the updates to Core NFC, the framework that handles the connection and interactions with a tag. Developers can now read and write data in the NFC Data Exchange Format (NDEF) as well as use custom commands, among many other things. Engineers using our ST25T and ST25D tags already have access to our massive open online courses to help them write applications faster , and we even offer the source code of our iOS and Android apps. We now wanted to look at the new features of Core NFC that Apple made public last June to prepare for the release of the final version of iOS 13 this fall.
Our support of both iOS and Android is a crucial advantage to our customer because it ensures that they can adapt to the differences inherent to these two operating systems. Both have different underlying philosophies and it’s by understanding each of them that engineers can genuinely optimize their code to offer the best performances to their users. For instance, an NFC reader application for Android demands that developers traditionally work at a lower applicative level. On the other hand, Core NFC from Apple provides an abstraction layer that implements functions that developers call. Let’s explore some of the new features available in Core NFC.
Supporting NDEF in iOS 13
One of the significant new features of Core NFC is its ability to write data on a tag using NDEF thanks to the new NFCNDEFReaderSession
class. Very simply, developers first create a session and then connect to the tag, checking if it is compatible with NDEF message writing and the capacity available. They can then use the NFCNDEFMessage
class which will take in an array of payload records and pass it as a parameter to the writeNDEF
command. The application must then invalidate the session to release the tag and end the operation. It’s important to know that only one NFC NDEF reader session can be active at a time, meaning that iOS 13 puts additional sessions in a queue and processes them in a first-in-first-out basis. It is, therefore, strongly preferable to invalidate a session before starting a new one.
The code is an excerpt showing how we implemented our NFCNDEF session and how we are calling it to write the contact information on an NFC tag. Developers can also check out the full source code of that particular project.
//Here's the function to handle writing an NDEF Tag
@IBAction func handleWrite(_ sender: UIButton) {
if (cnPicker != nil) {
cnPicker.dismiss(animated: false, completion: nil)
}
// Create ST25SDK + coreNFC NDEF Message
updateNdefVcardRecord(imageView: mContactImageView!)
ndefMessage = updateNDEFMessage()
nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
nfcSession?.alertMessage = "Hold your iPhone near an NFC tag for WRITE."
nfcSession?.begin()
// When a tag is read-writable and has sufficient capacity,
// write an NDEF message to it.
tag.writeNDEF(self.ndefMessage!) { (error: Error?) in
if error != nil {
session.invalidate(errorMessage: "Update tag failed. Please try again."+error.debugDescription)
} else {
session.alertMessage = "Write success!"
session.invalidate()
}
}
Supporting Custom Commands in iOS 13
ISO15693 (Type-5) tags have numerous convenience methods that are now available in Core NFC, such as reading and writing single or multiple blocks, permanently locking a tag, or supporting custom commands. Custom commands take the form of a hexadecimal value that ranges from 0xA0 to 0xDF and which tells the NFC Tag to perform certain operations. According to the standards, 00 is never a custom command, and each vendor can associate a code to a different function, which means that it is essential to grasp the specificities of a particular tag. Under iOS 13, developers that wish to send a custom command must use the customCommand
function which takes in the command code, and potential custom parameters then create a data packet that iOS 13 will send to the tag itself.
To illustrate this, we are sharing the source code of a demo application that uses custom commands to read and write the Mailbox of an ST25DV-IC tag, which is a 256-byte rewritable buffer. The 0xAC custom command in the example code below shows how to read the Mailbox.
/* Read full Buffer from MB (Mailbox)*/
iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x02), customCommandCode: 0xAC, customRequestParameters: Data(bytes: [0x00,0x00])){ (response: Data, error: Error?) in
if error != nil {
session.invalidate(errorMessage: "Read Buffer Mail Box. Please try again."+error!.localizedDescription)
print(error!.localizedDescription)
//return
}
DispatchQueue.main.sync {
self.readBufferTextView.text = response.toHexString().replacingOccurrences(of: " ", with: "")
}
if (self.writeBuffer == false){
session.invalidate()
}
}
if (self.writeBuffer) {
// Creating buffer to write
var bufferData:NSData!
DispatchQueue.main.sync {
let bufferIOSByteArray = ComStSt25sdkHelper.convertHexStringToByteArray(with: self.bufferTextField.text)
bufferData = bufferIOSByteArray?.toNSData() as NSData?
}
var data = Data(referencing: bufferData)
data.insert(Data.Element(bufferData.length-1), at: 0)
In the case of our ST25 tags, we offer a software development kit (STSW-ST25SDK001) that contains documentation referencing how we use custom commands. For instance, 0xB4 returns a random number, 0xDB can read a digital signature, 0xB1 will update the Kill password, and 0xB2 will lock it indefinitely, while 0xA6 will kill the tag by rendering it mute, meaning that the RF will no longer answer any command. To get a list of our custom commands, developers can open our ST25 SDK, then the documentation
folder and the index.html
file before selecting Iso15693CustomCommandInterface
under all classes on the lower left column.
Tips, Tricks, and Advise
Engineers using our ST25 tags can now work toward creating even more powerful iOS programs and make their NFC solutions a lot more pertinent and practical. There are also ways to use the new Core NFC features to perform unusual tasks, such as energy harvesting. When the ST25 tags receive energy from a phone, there’s always a little bit of extra current that the NFC device doesn’t need and that engineers can send onto a pin to power a small device, such as an LED. However, it demands that the smartphone continuously poll the tag, which wasn’t possible until iOS 13. With the new operating system, an application can use the restartPolling()
function available in the NFCNDEFReaderSession
class to continuously poll the tag and to power that LED, thus offering more interactivity to the user.
The code below shows our helper function using restartPolling()
. We are also offering the source code of our demo application to help developers see how it fit in their application.
// NFCTagReaderSessionDelegate
// Private helper functions
func tagRemovalDetect(_ tag: NFCTag) {
self.tagSession?.connect(to: tag) { (error: Error?) in
if error != nil || !tag.isAvailable {
self.tagSession?.restartPolling()
return
}
DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(500), execute: {
self.tagRemovalDetect(tag)
})
}
}
Developers ought to keep in mind that iOS 13 is still in beta, and they should check the latest updates by Apple to its Core NFC. Furthermore, unlike past years, developers that wish to get a head start must download the beta version of macOS Catalina and Xcode 11, while the lack of iTunes means installing the iOS beta differently than usual. We encourage developers to try Core NFC early as the beta version is already quite impressive, which will enable them to start working on the new features early. In tandem with SwiftUI, they can create modern and feature-rich applications. Our community can also expect us to publish the source code of our iOS 13 app once it is in the App Store.
- Learn more about our ST25 tags
- Master NFC Type 5 with our Webinar