NFC Module
Properties Methods Events Config Settings Errors
The NFC component is used to read and write to NFC tags.
Syntax
IPWorksNFC.NFC
Remarks
The NFC class supports tag management according to the specifications outlined in RFC 9428, in addition to RFC 4729, which defines a URN Namespace for the NFC Forum.
Project Setup
First, add the IPWorksNFC framework to your Xcode project. Before the class can run successfully, the Entitlements and Info.plist files must be configured appropriately. These files can be changed directly or via Xcode; see the demo project for reference.
To ensure the correct entitlement is applied to the project, in Xcode, first select the project and the appropriate target in the project view. After navigating to 'Signing & Capabilities', you must add the 'Near Field Communication Tag Reading' capability. Alternatively, you can add the following key to the Entitlements file. For example, the file contents may look like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
</dict>
</plist>
Next, ensure that the Info.plist file includes the NFCReaderUsageDescription key. For example, the file contents may look like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NFCReaderUsageDescription</key>
<string>This app needs NFC access to read contactless NFC tags</string>
</dict>
</plist>
You will also need to ensure the Info.plist file is referenced and is present in the 'Build Settings', under 'Packaging'.
Initialization
To use the NFC class, you must first import the IPWorks NFC module as needed:
import IPWorksNFC
Afterwards, you must create an instance of the class and assign a delegate that conforms to NFCDelegate. The delegate receives all NFC events, including when a tag is detected, when records are read, and when logs or errors occur.
A common approach is to wrap the NFC class in a manager class that implements NFCDelegate. This keeps the NFC logic separate from the UI and allows you to reference the manager in your main view:
class NFCManager: ObservableObject, NFCDelegate {
private var nfc: NFC?
init() {
do {
nfc = try NFC()
nfc?.delegate = self
// other settings
} catch {
print("Error initializing NFC: \\(error)")
}
}
// Delegated events
func onError(errorCode: Int32, description: String) { }
func onLog(logLevel: Int32, message: String, logType: String) { }
func onRecord(id: Data, payload: Data, recordType: Data, recordTypeFormat: Int32) { }
func onTag(forumType: Int32, maxSize: Int32, serialNumber: String, size: Int32, writable: Bool) { }
}
struct ContentView: View {
@StateObject private var nfcManager = NFCManager()
var body: some View {
// UI code here
}
}
Alternatively, you can have your SwiftUI view itself conform to NFCDelegate:
struct ContentView: View, NFCDelegate {
private var nfc: NFC?
// Delegated events
func onError(errorCode: Int32, description: String) { }
func onLog(logLevel: Int32, message: String, logType: String) { }
func onRecord(id: Data, payload: Data, recordType: Data, recordTypeFormat: Int32) { }
func onTag(forumType: Int32, maxSize: Int32, serialNumber: String, size: Int32, writable: Bool) { }
init() {
do {
nfc = try NFC()
nfc?.delegate = self
// other settings
} catch {
print("Error initializing NFC: \\(error)")
}
}
var body: some View {
// UI code here
}
}
Reading a Tag
To read the data from a tag, call the Read method and place the tag close to the device. Please note that the Read method is blocking, and should not be called from the UI (to prevent any freezing behavior). For example:
DispatchQueue.global().async {
do {
try nfc!.read()
} catch let e {
print("\(e)")
}
}
After the tag is detected, the component will attempt to parse the tag information and any stored records. As soon as the component has read all of the tag information, the Tag event will fire, containing relevant details about the tag, such as the tag's type and serial number, current and maximum size (i.e., the amount of data the tag is currently storing or can store), and whether the tag can be written to. For example, in the Tag event:
func onTag(forumType: Int32, maxSize: Int32, serialNumber: String, size: Int32, writable: Bool) {
print("Tag Detected. Details:")
print("Tag Type: \\(forumType)")
print("Serial Number: \\(serialNumber)")
print("Size: \\(size) / \\(maxSize) Bytes")
print("Writable: \\(writable)")
}
After the Tag event fires, the Record event will fire for each record that is detected. The Record event will contain relevant details about the record, such as the record TNF (type name format, or record type format), the actual record type (which is interpreted based on the TNF), the payload (actual record content), and the optional record ID (which is typically empty). For example, in the Record event:
func onRecord(id: Data, payload: Data, recordType: Data, recordTypeFormat: Int32) {
print("Record Detected.")
print("TNF: \\(recordTypeFormat)") // E.g., 0 -> 0x00 (Empty), 1 -> 0x01 (Well-known)
print("Record Type: \\(recordType)") // E.g., if TNF is 0x01 (Empty), this could be "T" (text record)
print("Record Payload: \\(payload)")
}
Note that, in addition to the tag and record details being made available via their corresponding events, the Tag property and Records collection will be populated after the Read method returns successfully. Tag and record details can also be accessed like so:
// Printing tag info
private func printTagInfo() {
guard let tag = nfc?.tag else { return }
print("Tag Type: \\(tag.forumType)")
print("Serial Number: \\(tag.serialNumber)")
print("Size: \\(tag.size) / \\(tag.maxSize) Bytes")
print("Writable: \\(tag.writable)")
}
// Printing record info
private func printRecordInfo() {
var recordNum = 1
for record in nfc!.records {
print("Record \\(recordNum) Info")
print("TNF: \\(record.recordTypeFormat)")
print("Record Type: \\(record.recordType)")
print("Record Payload: \\(record.Payload)")
print("")
recordNum += 1
}
}
Parsing Records
As mentioned, the Record event provides the raw components of each NDEF record detected on a tag. An NDEF (NFC Data Exchange Format) record is the standard way NFC tags encode and store data. Each record contains four key parts exposed by the Record event.
Typically, the RecordTypeFormat parameter will be checked first. This parameter represents the TNF (Type Name Format) associated with the record. Possible values for this parameter are:
Value | Name | Description |
0x00 | Empty | Empty record (padding or placeholder) |
0x01 | Well-Known | Standard types like text (T) and URI (U) |
0x02 | MIME Media Type | Type is a MIME type (e.g., text/plain, image/jpeg) |
0x03 | Absolute URI | Type field contains a full URI |
0x04 | External Type | Namespaced external types (e.g., com.example:type) |
0x05 | Unknown | Type is not provided or known |
0x06 | Unchanged | Used for chunked data (not common) |
After checking the value of the RecordTypeFormat parameter, the RecordType parameter can then be interpreted. As an example, if the TNF of a record is 0x01 (Well-Known), the RecordType is usually a single character that identifies the type of record. This value would be "T" to indicate a text record, or "U" to indicate a URI/URL record.
In either case, the mentioned parameters can be used to then determine how to interpret the Payload parameter, which is ultimately left up to the developer. For example, given a RecordTypeFormat of 0x01 and a RecordType of "T" (Well-Known Text Record), the following code (when iterating through the collection of records) can be used to extract the relevant data out of the Payload:
if record.recordTypeFormat == RecordTypeFormats.rtfWellKnown && record.recordType == "T" {
// Handle Text Record
let payload = record.payloadB
let status = payload[0]
let isUtf16 = (status & 0x80) != 0
let langCodeLen = Int(status & 0x3F)
let encoding: String.Encoding = isUtf16 ? .utf16 : .utf8
let languageCodeRange = 1..<1+langCodeLen
let languageCodeData = payload.subdata(in: languageCodeRange)
let languageCode = String(data: languageCodeData, encoding: .ascii) ?? ""
let textRange = (1 + langCodeLen)..<payload.count
let textData = payload.subdata(in: textRange)
let text = String(data: textData, encoding: encoding) ?? ""
print("Text Record (LangCode = \\(languageCode)) - \\(text)")
}
The format of a text record is defined and standardized, so the payload can be parsed in a predictable way (status byte, language code, then the actual text). Other record types follow similar conventions. For example:
- For a URI record (TNF = 0x01, RecordType = "U"), the first byte of the payload is the URI prefix code (e.g., 0x01 for "http://www.), followed by the rest of the URI string in UTF-8.
- For a MIME Media record (TNF = 0x02), the record type is a MIME type (e.g., "text/plain"), and the payload contains raw data of that type.
In practice, this means that the RecordTypeFormat (TNF) tells you how to interpret the RecordType, which in turn tells you how to parse the Payload. By combining these, you can effectively parse any NDEF record type.
Writing to a Tag
To write records to a tag, the Records collection should first be populated with any records that are to be written to the tag. To do so, the API exposes three methods:
The AddTextRecord method can be used to add a well-formed text record to the Records collection. This is typically used to encode human-readable text. This method takes two parameters: the actual text to store on the tag, and the language code that specifies the language of the text (for example, "en" for English).
The AddURLRecord method can be used to add a URI or URL record to the Records collection. This method takes a single parameter, which is the URL string to store on the tag.
For all other types of records, including custom or MIME-based records, the AddRecord method may be used. This method requires specifying the TNF (Type Name Format), the record type, an optional record ID, and the record payload.
As there are many possible types of records, this method is intended to give developers full control over record creation. While AddTextRecord and AddURLRecord cover some common scenarios, AddRecord allows developers to handle any custom, proprietary, or less common NDEF records without introducing additional specialized methods. As an example, you could create a MIME Media record like containing JSON like so:
do {
let tnf: Int32 = 0x02
let recordType = "application/json".data(using: .ascii)!
let id = Data() // empty
// Prepare JSON
let jsonObject: [String: Any] = [
"name": "NFC Example",
"version": "1.0",
"data": "some_json_data"
]
let payload = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
try nfc?.addRecord(tnf: tnf, type: recordType, payload: payload, id: id)
} catch {
print("Failed to add JSON MIME record: \(error)")
}
Once the desired records are added to the Records collection, the Write method should be called to write the records to the tag. If multiple records are added, they will be written together as a single NDEF message. Please note that the Write method is blocking. To prevent the UI from freezing, the method should be called like so:
DispatchQueue.global().async {
do {
try nfc!.write()
} catch let e {
print("\(e)")
}
}
Note that if you previously read a tag, the Records collection will likely be populated. Unless you are preserving the existing records from the prior read operation, you can clear the records from the collection like so:
nfc!.records.removeAll()
After clearing the records, you can add new records to write using the methods described previously.
Property List
The following is the full list of the properties of the module with short descriptions. Click on the links for further details.
Available | Indicates whether NFC is currently enabled and supported on the current device. |
Records | A collection of NDEF records. |
Tag | Information about the last nfctag detected with a Read operation. |
Timeout | Timeout in seconds to wait for a tag during Read and Write operations. |
Method List
The following is the full list of the methods of the module with short descriptions. Click on the links for further details.
Abort | Cancels an ongoing Read or Write operation that is waiting for a tag. |
AddRecord | Adds a custom NDEFRecord to the Records collection. |
AddTextRecord | Adds an NDEF Text record to the Records collection. |
AddURLRecord | Adds an NDEF URI/URL record to the Records collection. |
Config | Sets or retrieves a configuration setting. |
Read | Reads a presented NFC tag. |
Reset | Resets the component to its initial state by clearing records and tag information. |
Write | Writes the record(s) in the Records collection to a detected NFC tag. |
Event List
The following is the full list of the events fired by the module with short descriptions. Click on the links for further details.
Error | Fired when information is available about errors during data delivery. |
Log | Fired once for each log message. |
Record | Fires once for each NDEF Record discovered during a Read operation. |
Tag | Fires once when a tag is discovered during a Read operation. |
Config Settings
The following is a list of config settings for the module with short descriptions. Click on the links for further details.
PollingOptions | Specifies which NFC tag types the component polls for. |
BuildInfo | Information about the product's build. |
CodePage | The system code page used for Unicode to Multibyte translations. |
LicenseInfo | Information about the current license. |
MaskSensitiveData | Whether sensitive data is masked in log messages. |
UseInternalSecurityAPI | Whether or not to use the system security libraries or an internal implementation. |
Available Property (NFC Module)
Indicates whether NFC is currently enabled and supported on the current device.
Syntax
public var available: Bool { get {...} }
Default Value
False
Remarks
This property indicates whether NFC is currently enabled and supported on the current device.
If false, the class will not be able to perform any read or write operations. This property may be checked before attempting to call Read or Write. Note that availability is also checked during the calls to Read and Write, and the methods will return an error if NFC is not supported on the current device.
This property is read-only.
Records Property (NFC Module)
A collection of NDEF records.
Syntax
public var records: Array<NDEFRecord> { get {...} }
Remarks
This property holds a collection of NDEF records.
In the case of a Read operation, this property will hold a collection of NDEF records that were read on the tag (assuming Read returned successfully). Note that record information is also made available via the Record event. For example, to iterate through all detected records:
// Reading records after a successful read
for record in nfc!.records {
// Process records
}
In the case of a Write operation, this property will hold records to be written to a tag. To add a record to this collection, AddTextRecord, AddURLRecord, and AddRecord can be called. Once populated, Write can be called to write all records in this collection to a tag. For example:
// Adding records for writing
nfc?.addTextRecord(text: "Hello, World!", languageCode: "en")
nfc?.addURLRecord(url: "mailto:info@nsoftware.com")
if nfc?.records.count > 0 {
// Dispatch write
}
Note that if you previously read a tag, this collection will likely be populated. Unless you are preserving records from the prior read operation, you can clear the records from the collection before a write like so:
nfc!.records.removeAll()
Tag Property (NFC Module)
Information about the last nfctag detected with a Read operation.
Syntax
public var tag: NFCTag { get {...} }
Remarks
This property holds information about the last NFCTag detected with a Read operation. See NFCTag for the available fields.
For example, after reading a tag, you can access it's properties like so:
private func printTagInfo() {
guard let tag = nfc?.tag else { return }
print("Tag Type: \\(tag.forumType)")
print("Serial Number: \\(tag.serialNumber)")
print("Size: \\(tag.size) / \\(tag.maxSize) Bytes")
print("Writable: \\(tag.writable)")
}
This property is read-only.
Timeout Property (NFC Module)
Timeout in seconds to wait for a tag during Read and Write operations.
Syntax
public var timeout: Int32 { get {...} set {...} }
Default Value
30
Remarks
Applies to blocking operations; after the timeout elapses, the call returns without a tag.
Abort Method (NFC Module)
Cancels an ongoing Read or Write operation that is waiting for a tag.
Syntax
public func abort() throws -> Void
Remarks
This method cancels an ongoing Read or Write operation that is waiting for a tag. It may be invoked from any context (such as a background thread on Android or a background dispatch queue on iOS) to interrupt a pending operation.
Example:
// Dispatch read on a background queue
DispatchQueue.global().async {
do {
try nfc!.read() // waits for tag
} catch let e {
print("Read error or aborted: \(e)")
}
}
// Cancel from UI action (e.g., a button)
cancelButton.addTarget(self, action: #selector(cancelRead), for: .touchUpInside)
@objc func cancelRead() {
nfc?.abort()
}
AddRecord Method (NFC Module)
Adds a custom NDEFRecord to the Records collection.
Syntax
public func addRecord(recordTypeFormat: Int32, recordType: Data, payload: Data, id: Data) throws -> Void
Remarks
This method adds a custom NDEFRecord to the Records collection with the specified parameters.
The RecordTypeFormat is used to specify the format of the record (this is also known as the Type Name Format, or TNF). Possible values for this parameter are:
Value | Name | Description |
0x00 | Empty | Empty record (padding or placeholder) |
0x01 | Well-Known | Standard types like text (T) and URI (U) |
0x02 | MIME Media Type | Type is a MIME type (e.g., text/plain, image/jpeg) |
0x03 | Absolute URI | Type field contains a full URI |
0x04 | External Type | Namespaced external types (e.g., com.example:type) |
0x05 | Unknown | Type is not provided or known |
0x06 | Unchanged | Used for chunked data (not common) |
The RecordType parameter, normally assigned based on the RecordTypeFormat being specified, defines the type of the record. For example, if the RecordTypeFormat is set to MIME media (0x02), the RecordType might be "text/plain" or "application/json".
The Payload parameter contains the actual data of the record. This may be text, binary data, or any other content defined by the record type. For instance, for a text record this would contain the text string, while for a URI record it would contain the URI bytes.
The Id parameter is an optional identifier for the record. It may be specified to uniquely identify a record within an NDEF message, or left empty if not needed.
For common cases use AddTextRecord or AddURLRecord. Otherwise, use this method to add a custom record, for example:
do {
let recordTypeFormat: Int32 = 0x02
let recordType = "application/json".data(using: .ascii)!
let id = Data() // empty
// Prepare JSON
let jsonObject: [String: Any] = [
"name": "NFC Example",
"version": "1.0",
"data": "some_json_data"
]
let payload = try JSONSerialization.data(withJSONObject: jsonObject, options: [])
try nfc?.addRecord(recordTypeFormat: recordTypeFormat, recordType: recordType, payload: payload, id: id)
} catch {
print("Failed to add JSON MIME record: \(error)")
}
AddTextRecord Method (NFC Module)
Adds an NDEF Text record to the Records collection.
Syntax
public func addTextRecord(text: String, languageCode: String) throws -> Void
Remarks
This method adds an NDEF Text record to the Records collection with the specified parameters.
The Text parameter specifies the actual text content of the record.
The LanguageCode parameter specifies the language of the text, using a standard IANA language code (for example, "en" for English or "fr" for French).
Note that at least one record must be added before calling Write.
Example:
nfc?.addTextRecord(text: "Hello, World!", languageCode: "en")
nfc?.addTextRecord(text: "Visitez notre site web pour plus d'informations", languageCode: "fr")
AddURLRecord Method (NFC Module)
Adds an NDEF URI/URL record to the Records collection.
Syntax
public func addURLRecord(url: String) throws -> Void
Remarks
This method adds an NDEF URI record to the Records collection with the specified parameter.
The URL parameter specifies the URI/URL to store in the record. The URL should conform to a valid URI scheme, for example "https://", "mailto:", etc.
Note that at least one record must be added before calling Write.
Example:
nfc?.addURLRecord(url: "https://www.nsoftware.com")
nfc?.addURLRecord(url: "mailto:info@nsoftware.com")
Config Method (NFC Module)
Sets or retrieves a configuration setting.
Syntax
public func config(configurationString: String) throws -> String
Remarks
Config is a generic method available in every class. It is used to set and retrieve configuration settings for the class.
These settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these internal properties is provided through the Config method.
To set a configuration setting named PROPERTY, you must call Config("PROPERTY=VALUE"), where VALUE is the value of the setting expressed as a string. For boolean values, use the strings "True", "False", "0", "1", "Yes", or "No" (case does not matter).
To read (query) the value of a configuration setting, you must call Config("PROPERTY"). The value will be returned as a string.
Read Method (NFC Module)
Reads a presented NFC tag.
Syntax
public func read() throws -> Void
Remarks
This method attempts to read a presented NFC tag and blocks until either a tag is detected or the operation times out.
The Timeout property specifies the maximum time, in seconds, to wait for a tag before returning. If no tag is detected within the specified timeout, the method will return without reading.
The method may throw an exception if the operation is cancelled (for example, by calling Abort) or if another error occurs.
After a tag is successfully detected, the Tag and Record events will fire, containing details about the tag and records present on the tag, respectively. Additionally, the Tag property and Records collection will be populated with this same information. Please refer to the relevent event and property descriptions for additional details.
Example:
// Dispatch read on a background queue
DispatchQueue.global().async {
do {
try nfc?.read() // waits for tag or timeout
} catch let e {
print("Read error or aborted: \(e)")
}
}
Reset Method (NFC Module)
Resets the component to its initial state by clearing records and tag information.
Syntax
public func reset() throws -> Void
Remarks
Does not affect the Activity reference or foreground dispatch. Use Abort if there is a need to interrupt an ongoing Read or Write operation.
Example:
// After completing an operation
nfc.Write(); // Write some records
nfc.Reset(); // Clear everything for next operation
nfc.AddTextRecord("New message");
nfc.Write(); // Write new records
Write Method (NFC Module)
Writes the record(s) in the Records collection to a detected NFC tag.
Syntax
public func write() throws -> Void
Remarks
This method will attempt to write the record(s) in the Records collection to a detected NFC tag.
The Timeout property specifies the maximum time, in seconds, to wait for a tag before returning. If no tag is detected within the specified timeout, the method will return without writing.
The method may throw an exception if the operation is cancelled (for example, by calling Abort) or if another error occurs.
Before calling this method, at least one record must be added to Records (for example, using AddTextRecord, AddURLRecord, or AddRecord). After a successful write, the tag will contain the records from the Records collection.
Example:
// Dispatch write on a background queue
DispatchQueue.global().async {
do {
// Add one or more records
nfc?.addTextRecord(text: "Hello, World!", languageCode: "en")
try nfc?.write() // waits for tag and writes
} catch let e {
print("Write error or aborted: \(e)")
}
}
Error Event (NFC Module)
Fired when information is available about errors during data delivery.
Syntax
func onError(errorCode: Int32, description: String)
Remarks
The Error event is fired in case of exceptional conditions during message processing. Normally the class .
The ErrorCode parameter contains an error code, and the Description parameter contains a textual description of the error. For a list of valid error codes and their descriptions, please refer to the Error Codes section.
Log Event (NFC Module)
Fired once for each log message.
Syntax
func onLog(logLevel: Int32, message: String, logType: String)
Remarks
This event is fired once for each log message generated by the class. The verbosity is controlled by the LogLevel setting.
LogLevel indicates the level of message. Possible values are as follows:
0 (None) | No events are logged. |
1 (Info - default) | Informational events are logged. |
2 (Verbose) | Detailed data are logged. |
3 (Debug) | Debug data are logged. |
The value 1 (Info) logs basic information, including the URL, HTTP version, and status details.
The value 2 (Verbose) logs additional information about the request and response.
The value 3 (Debug) logs the headers and body for both the request and response, as well as additional debug information (if any).
Message is the log entry.
LogType identifies the type of log entry. Possible values are as follows:
- "Info"
- "RequestHeaders"
- "ResponseHeaders"
- "RequestBody"
- "ResponseBody"
- "ProxyRequest"
- "ProxyResponse"
- "FirewallRequest"
- "FirewallResponse"
Record Event (NFC Module)
Fires once for each NDEF Record discovered during a Read operation.
Syntax
func onRecord(id: Data, payload: Data, recordType: Data, recordTypeFormat: Int32)
Remarks
This event is triggered for each NDEF record detected on the tag. The event provides access to the following parameters:
The Id parameter is the identifier of the record, if one was specified when the record was created. This may be used to uniquely distinguish records within an NDEF message. This parameter is typically empty, as it is optional.
The Payload parameter contains the actual data stored in the record. This may be text, binary data, or any other content, depending on the record type.
The RecordType parameter specifies the type of the record, usually based on the RecordTypeFormat. For example, with a MIME media format (0x02), the RecordType might be "text/plain" or "application/json".
The RecordTypeFormat parameter specifies the Type Name Format (TNF) of the record. Possible values for this parameter are:
Value | Name | Description |
0x00 | Empty | Empty record (padding or placeholder) |
0x01 | Well-Known | Standard types like text (T) and URI (U) |
0x02 | MIME Media Type | Type is a MIME type (e.g., text/plain, image/jpeg) |
0x03 | Absolute URI | Type field contains a full URI |
0x04 | External Type | Namespaced external types (e.g., com.example:type) |
0x05 | Unknown | Type is not provided or known |
0x06 | Unchanged | Used for chunked data (not common) |
This event will fire once for each record present on the tag. For example, if a tag contains multiple text or URI records, the event will be raised separately for each record. In addition to this event, the record data will be present in the Records collection after the Read operation is successful.
Example:
func onRecord(id: Data, payload: Data, recordType: Data, recordTypeFormat: Int32) {
print("Record Detected.")
print("TNF: \\(recordTypeFormat)") // E.g., 0 -> 0x00 (Empty), 1 -> 0x01 (Well-known)
print("Record Type: \\(recordType)") // E.g., if TNF is 0x01 (Empty), this could be "T" (text record)
print("Record Payload: \\(payload)")
}
Tag Event (NFC Module)
Fires once when a tag is discovered during a Read operation.
Syntax
func onTag(forumType: Int32, maxSize: Int32, serialNumber: String, size: Int32, writable: Bool)
Remarks
This event is triggered when a tag is successfully detected. The event provides access to the following parameters:
The ForumType parameter specifies the type of the tag according to the NFC Forum specification.
The MaxSize parameter indicates the maximum storage size of the tag, in bytes.
The SerialNumber parameter contains the unique serial number of the tag as a string. This may be empty or unavailable on some tags.
The Size parameter specifies the current amount of used storage on the tag, in bytes.
The Writable parameter indicates whether the tag is currently writable (true) or read-only (false).
In addition to this event, the tag information will be available in the Tag property after a successful Read operation.
Example:
func onTag(forumType: Int32, maxSize: Int32, serialNumber: String, size: Int32, writable: Bool) {
print("Tag Detected. Details:")
print("Tag Type: \\(forumType)")
print("Serial Number: \\(serialNumber)")
print("Size: \\(size) / \\(maxSize) Bytes")
print("Writable: \\(writable)")
}
NDEFRecord Type
The NDEFRecord type represents a single NDEF Record.
Remarks
Each record consists of a type identifier, payload data, optional ID, and format information.
Fields
idB
Data
Default Value: ""
This optional field is for differentiating between multiple records in one message.
id
String
Default Value: ""
This optional field is for differentiating between multiple records in one message.
payloadB
Data
Default Value: ""
The field contains the record's data.
This field is interpreted according to the record type (e.g., Text, URI, MIME, or custom application formats).
payload
String
Default Value: ""
The field contains the record's data.
This field is interpreted according to the record type (e.g., Text, URI, MIME, or custom application formats).
recordTypeB
Data
Default Value: ""
The field defines the type of data contained in the record's .
This field defines the type of data contained in the field. The interpretation of this field depends on the (TNF) value.
recordType
String
Default Value: ""
The field defines the type of data contained in the record's .
This field defines the type of data contained in the field. The interpretation of this field depends on the (TNF) value.
recordTypeFormat
RecordTypeFormats
Default Value: 0
The field determines how the is interpreted.
The following values are acceptable:
rtfEmpty | Empty NDEF Record with no type, ID, or payload. |
rtfWellKnown | The record type follows the NFC Forum well-known type format. |
rtfMIMEMedia | The record type is a MIME media type as defined by RFC 2046. |
rtfAbsoluteURI | The record type is an absolute URI as defined by RFC 3986. |
rtfExternalType | The record type follows the NFC Forum external type format. |
rtfUnknown | The record type format is unknown or unsupported. |
rtfUnchanged | The record type format remains unchanged. |
rtfReserved | Reserved for future use by the NFC Forum. |
NFCTag Type
This type an represents an NFCTag with its properties and capabilities.
Remarks
Fields
forumType
Int32
Default Value: 0
The field represents the NFC Forum tag type classification of the detected tag.
This value is automatically determined during a Read operation.
maxSize
Int32
Default Value: 0
The maximum storage capacity of the NFCTag in bytes.
This read-only field indicates the total amount of data that can be stored on the NFC tag.
serialNumber
String
Default Value: ""
The unique identifier of the NFCTag.
This field contains the hexadecimal string representation of the tag's unique identifier (UID). It is determined during an Read operation, and it cannot be modified.
size
Int32
Default Value: 0
The current amount of data stored on the NFCTag in bytes.
This read-only field indicates how much of the tag's storage capacity is currently being used by NDEF message data.
writable
Bool
Default Value: False
True if the detected tag supports write operations. False if it is read-only or write-protected.
This field is populated during a read operation and reflects the state of the tag.
Config Settings (NFC Module)
The class accepts one or more of the following configuration settings. Configuration settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these internal properties is provided through the Config method.NFC Config Settings
- iso14443 - Tags adhering to ISO 14443 (enabled by default)
- iso15693 - Tags adhering to ISO 15693 (enabled by default)
- iso18092 - Tags adhering to ISO 18092 (FeliCa, disabled by default)
To enable support for FeliCa tags, you can specify the config like so:
try nfc!.config(configurationString: "iso14443,iso15693,iso18092")
Note that when specified, you must add the appropriate system codes to your projects Entitlements file:
<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
<array>
<string>12FC</string> <!-- example system codes to support -->
</array>
Base Config Settings
The following is a list of valid code page identifiers:
Identifier | Name |
037 | IBM EBCDIC - U.S./Canada |
437 | OEM - United States |
500 | IBM EBCDIC - International |
708 | Arabic - ASMO 708 |
709 | Arabic - ASMO 449+, BCON V4 |
710 | Arabic - Transparent Arabic |
720 | Arabic - Transparent ASMO |
737 | OEM - Greek (formerly 437G) |
775 | OEM - Baltic |
850 | OEM - Multilingual Latin I |
852 | OEM - Latin II |
855 | OEM - Cyrillic (primarily Russian) |
857 | OEM - Turkish |
858 | OEM - Multilingual Latin I + Euro symbol |
860 | OEM - Portuguese |
861 | OEM - Icelandic |
862 | OEM - Hebrew |
863 | OEM - Canadian-French |
864 | OEM - Arabic |
865 | OEM - Nordic |
866 | OEM - Russian |
869 | OEM - Modern Greek |
870 | IBM EBCDIC - Multilingual/ROECE (Latin-2) |
874 | ANSI/OEM - Thai (same as 28605, ISO 8859-15) |
875 | IBM EBCDIC - Modern Greek |
932 | ANSI/OEM - Japanese, Shift-JIS |
936 | ANSI/OEM - Simplified Chinese (PRC, Singapore) |
949 | ANSI/OEM - Korean (Unified Hangul Code) |
950 | ANSI/OEM - Traditional Chinese (Taiwan; Hong Kong SAR, PRC) |
1026 | IBM EBCDIC - Turkish (Latin-5) |
1047 | IBM EBCDIC - Latin 1/Open System |
1140 | IBM EBCDIC - U.S./Canada (037 + Euro symbol) |
1141 | IBM EBCDIC - Germany (20273 + Euro symbol) |
1142 | IBM EBCDIC - Denmark/Norway (20277 + Euro symbol) |
1143 | IBM EBCDIC - Finland/Sweden (20278 + Euro symbol) |
1144 | IBM EBCDIC - Italy (20280 + Euro symbol) |
1145 | IBM EBCDIC - Latin America/Spain (20284 + Euro symbol) |
1146 | IBM EBCDIC - United Kingdom (20285 + Euro symbol) |
1147 | IBM EBCDIC - France (20297 + Euro symbol) |
1148 | IBM EBCDIC - International (500 + Euro symbol) |
1149 | IBM EBCDIC - Icelandic (20871 + Euro symbol) |
1200 | Unicode UCS-2 Little-Endian (BMP of ISO 10646) |
1201 | Unicode UCS-2 Big-Endian |
1250 | ANSI - Central European |
1251 | ANSI - Cyrillic |
1252 | ANSI - Latin I |
1253 | ANSI - Greek |
1254 | ANSI - Turkish |
1255 | ANSI - Hebrew |
1256 | ANSI - Arabic |
1257 | ANSI - Baltic |
1258 | ANSI/OEM - Vietnamese |
1361 | Korean (Johab) |
10000 | MAC - Roman |
10001 | MAC - Japanese |
10002 | MAC - Traditional Chinese (Big5) |
10003 | MAC - Korean |
10004 | MAC - Arabic |
10005 | MAC - Hebrew |
10006 | MAC - Greek I |
10007 | MAC - Cyrillic |
10008 | MAC - Simplified Chinese (GB 2312) |
10010 | MAC - Romania |
10017 | MAC - Ukraine |
10021 | MAC - Thai |
10029 | MAC - Latin II |
10079 | MAC - Icelandic |
10081 | MAC - Turkish |
10082 | MAC - Croatia |
12000 | Unicode UCS-4 Little-Endian |
12001 | Unicode UCS-4 Big-Endian |
20000 | CNS - Taiwan |
20001 | TCA - Taiwan |
20002 | Eten - Taiwan |
20003 | IBM5550 - Taiwan |
20004 | TeleText - Taiwan |
20005 | Wang - Taiwan |
20105 | IA5 IRV International Alphabet No. 5 (7-bit) |
20106 | IA5 German (7-bit) |
20107 | IA5 Swedish (7-bit) |
20108 | IA5 Norwegian (7-bit) |
20127 | US-ASCII (7-bit) |
20261 | T.61 |
20269 | ISO 6937 Non-Spacing Accent |
20273 | IBM EBCDIC - Germany |
20277 | IBM EBCDIC - Denmark/Norway |
20278 | IBM EBCDIC - Finland/Sweden |
20280 | IBM EBCDIC - Italy |
20284 | IBM EBCDIC - Latin America/Spain |
20285 | IBM EBCDIC - United Kingdom |
20290 | IBM EBCDIC - Japanese Katakana Extended |
20297 | IBM EBCDIC - France |
20420 | IBM EBCDIC - Arabic |
20423 | IBM EBCDIC - Greek |
20424 | IBM EBCDIC - Hebrew |
20833 | IBM EBCDIC - Korean Extended |
20838 | IBM EBCDIC - Thai |
20866 | Russian - KOI8-R |
20871 | IBM EBCDIC - Icelandic |
20880 | IBM EBCDIC - Cyrillic (Russian) |
20905 | IBM EBCDIC - Turkish |
20924 | IBM EBCDIC - Latin-1/Open System (1047 + Euro symbol) |
20932 | JIS X 0208-1990 & 0121-1990 |
20936 | Simplified Chinese (GB2312) |
21025 | IBM EBCDIC - Cyrillic (Serbian, Bulgarian) |
21027 | Extended Alpha Lowercase |
21866 | Ukrainian (KOI8-U) |
28591 | ISO 8859-1 Latin I |
28592 | ISO 8859-2 Central Europe |
28593 | ISO 8859-3 Latin 3 |
28594 | ISO 8859-4 Baltic |
28595 | ISO 8859-5 Cyrillic |
28596 | ISO 8859-6 Arabic |
28597 | ISO 8859-7 Greek |
28598 | ISO 8859-8 Hebrew |
28599 | ISO 8859-9 Latin 5 |
28605 | ISO 8859-15 Latin 9 |
29001 | Europa 3 |
38598 | ISO 8859-8 Hebrew |
50220 | ISO 2022 Japanese with no halfwidth Katakana |
50221 | ISO 2022 Japanese with halfwidth Katakana |
50222 | ISO 2022 Japanese JIS X 0201-1989 |
50225 | ISO 2022 Korean |
50227 | ISO 2022 Simplified Chinese |
50229 | ISO 2022 Traditional Chinese |
50930 | Japanese (Katakana) Extended |
50931 | US/Canada and Japanese |
50933 | Korean Extended and Korean |
50935 | Simplified Chinese Extended and Simplified Chinese |
50936 | Simplified Chinese |
50937 | US/Canada and Traditional Chinese |
50939 | Japanese (Latin) Extended and Japanese |
51932 | EUC - Japanese |
51936 | EUC - Simplified Chinese |
51949 | EUC - Korean |
51950 | EUC - Traditional Chinese |
52936 | HZ-GB2312 Simplified Chinese |
54936 | Windows XP: GB18030 Simplified Chinese (4 Byte) |
57002 | ISCII Devanagari |
57003 | ISCII Bengali |
57004 | ISCII Tamil |
57005 | ISCII Telugu |
57006 | ISCII Assamese |
57007 | ISCII Oriya |
57008 | ISCII Kannada |
57009 | ISCII Malayalam |
57010 | ISCII Gujarati |
57011 | ISCII Punjabi |
65000 | Unicode UTF-7 |
65001 | Unicode UTF-8 |
Identifier | Name |
1 | ASCII |
2 | NEXTSTEP |
3 | JapaneseEUC |
4 | UTF8 |
5 | ISOLatin1 |
6 | Symbol |
7 | NonLossyASCII |
8 | ShiftJIS |
9 | ISOLatin2 |
10 | Unicode |
11 | WindowsCP1251 |
12 | WindowsCP1252 |
13 | WindowsCP1253 |
14 | WindowsCP1254 |
15 | WindowsCP1250 |
21 | ISO2022JP |
30 | MacOSRoman |
10 | UTF16String |
0x90000100 | UTF16BigEndian |
0x94000100 | UTF16LittleEndian |
0x8c000100 | UTF32String |
0x98000100 | UTF32BigEndian |
0x9c000100 | UTF32LittleEndian |
65536 | Proprietary |
- Product: The product the license is for.
- Product Key: The key the license was generated from.
- License Source: Where the license was found (e.g., RuntimeLicense, License File).
- License Type: The type of license installed (e.g., Royalty Free, Single Server).
- Last Valid Build: The last valid build number for which the license will work.
Setting this configuration setting to true tells the class to use the internal implementation instead of using the system security libraries.
This setting is set to false by default on all platforms.