iOS NFC Reader

Using NFC readers on iOS

Note that iOS NFC Tag Reader Session is supported in: iPhone XR, iPhone X, iPhone XS, iPhone XS Max, iPhone 11, iPhone 11 Pro. (iOS 13)

If the creation of the environment was successful (SCWS.createEnvironment()) and the device supports NFC Tag Reader Session, a Reader() named NFC Interface will be added to the list of the readers (SCWS.readers()).

To get the NFC (Reader()), call (SCWS.getReader()) by passing NFC Interface as parameter. For (Reader()) objects with Reader.requiresNfcTagReaderSession() returns true, you must use the functions below.

To start scanning for NFC Tags, call (SCWS.initNfcTagReaderSession()). iOS will display an alert action sheet waiting to detect tags. When a tag is detected, your app will receive a (SCWS.onreaderstatechanged()) event.

When your app is done communicating with the card or if an error occurred, call (SCWS.endNfcTagReaderSession()). It will end the NFC Tag Reader Session, dismiss the alert action sheet and display a message error or a positive check mark to the user.

SCWS.initNfcTagReaderSession(message)

Start scanning for NFC tags. After calling this function, iOS will display an alert action sheet wainting to detect tags.

Arguments
  • message – descriptive text message that is displayed on the alert action sheet once the scan is started. The string can be updated dynamically by calling SCWS.updateMessageNfcTagReaderSession().

Returns

A promised resolved when the operation completes. The resulting value is a string which can take the following values: - cancelled: The user cancelled the alert action sheet. - timeout: iOS cancelled the alert action sheet, because the user did not present a card within required time. - ok: The operation completed following a call to SCWS.endNfcTagReaderSession(). Note that before calling the following function, you need to check if the reader requires iOS NFC Tag Reader Session by calling Reader.requiresNfcTagReaderSession().

SCWS.endNfcTagReaderSession(message)

Closes the NFC Tag reader session and displays a feedback to the user. if the session was not successful, a message must be provided, which will be displayed to the user as an error. If the operation was successful, the message must be set to null and a positive check mark will be displaye to the user.

Arguments
  • messagenull if the session was successful, or a message error if the session was not successful. Note that before calling this function, you need to check if the reader requires iOS NFC Tag Reader Session by calling Reader.requiresNfcTagReaderSession().

SCWS.updateMessageNfcTagReaderSession(message)

Update the text message that was displayed on the alert action sheet of the NFC Tag Reader Session.

Arguments
  • message – the new text message to be displayed on the alert action sheet. Note that before calling this function, you need to check if the reader requires iOS NFC Tag Reader Session by calling Reader.requiresNfcTagReaderSession().

Android similar behavior example

To have a similar behavior on Android and iOS, a mechanism similar to the alert action sheet on iOS must be implemented. For each call of (SCWS.initNfcTagReaderSession()), (SCWS.endNfcTagReaderSession()) and (SCWS.updateMessageNfcTagReaderSession()) on iOS, an alert action sheet must be displayed on Android.

Here is an example of how it can be done.

Detecting when NfcTagReaderSession are required

The boolean Reader.requiresNfcTagReaderSession() can indicate if the iOS NFC Tag Reader Session functions are required:

function nfcTagReaderSessionRequired() {
    return (SCWS.getReader("NFC Interface") &&
        SCWS.getReader("NFC Interface").requiresNfcTagReaderSession);
    }
}

Initialization of the NFC session

To initialize the NFC session, an dialog overlay can be displayed to reproduce iOS behavior:

function initNfcSession(message) {
    window.scanning = true;
    if (nfcTagReaderSessionRequired()) // iOS
        SCWS.initNfcTagReaderSession(message);
    else // Android
        displayOverlay();
}

Where displayOverlay() shows a dialog that indicates that NFC scanning is on:

function displayOverlay() {
    document.getElementById("overlay").style.display = "block";
}

With overlay defined in the html body:

<div id="overlay">
    <div id="empty_block"></div>
    <div id="white_block">
        <div id="overlay_text_zone">
            <div id="overlay_text">Your device is ready<br> to scan for tokens</div>
            <br>
            <input type="button" class="overlay_button" onclick="endNfcSession()" value="Cancel"/>
        </div>
    </div>
</div>

And the overlay style defined in the associated CSS:

#overlay {
    position: fixed; /* Stays on top of the page content */
    top: 0;
    display: none; /* Hidden by default */
    width: 100%;
    height: 100%;
    background-color: rgba(0,0,0,0.5); /* Black background with transparency */
}

#empty_block {
    height: 50%;
}

#white_block {
    height: 50%;
    background-color: rgb(255, 255, 255);
}

#overlay_text_zone {
    font-size:20px;
    font-weight: bold;
    position: fixed;
    top: 55%;
    width: 100%;
    margin-top: 5%;
}

.overlay_button {
    background-color: #969696;
    border: none;
    padding: 15px 62px;
    font-size: 20px;
    margin-top: 5vh;
    cursor: pointer;
}

The boolean window.scanning can be used before the operations with the readers and tokens.

On iOS, the NFC events are only read between (SCWS.initNfcTagReaderSession()) and (SCWS.endNfcTagReaderSession()).

On Android, by default, SCWS will always send reader events such as (SCWS.onreaderstatechanged()) after a (SCWS.createEnvironment()).

By checking that window.scanning is true before reading a (Reader()), the app will behave the same on Android and iOS:

function checkReader(reader) {
    if (window.scanning) {
        // functions on readers and tokens
    }
}

Update NFC session message

The message displayed during the NFC session can be changed.

Note: async and await keywords are not necessary here, they ensure that the message will change before continuing the process.

async function updateNfcMessage(message) {
    if (nfcTagReaderSessionRequired()) // iOS
        await SCWS.updateMessageNfcTagReaderSession(message);
    else // Android
        changeOverlayText(message);
}

function changeOverlayText(message) {
    document.getElementById("overlay_text").innerHTML = message;
}

End NFC session

This function is called when the operations with the readers and tokens are finished.

Note: async and await keywords are not necessary here, they ensure that the dialog will show that the session ends before continuing the process.

Note: errorMessage must be empty if the operation succeeded.

async function endNfcSession(errorMessage) {
    window.scanning = false;

    if (nfcTagReaderSessionRequired()) // iOS
        await SCWS.endNfcTagReaderSession(errorMessage);
    else // Android
        hideOverlay();
}

function hideOverlay() {
    document.getElementById("overlay").style.display = "none";
}