Mobile Development 16 min read

Master NFC Integration Across Android, iOS, and WeChat Mini Programs

This comprehensive guide explains what NFC is, compares it with other short‑range wireless technologies, and provides step‑by‑step tutorials for implementing NFC on Android, iOS, and WeChat mini‑programs, covering chip data writing, NDEF formatting, App Clip integration, and universal link handling.

BaiPing Technology
BaiPing Technology
BaiPing Technology
Master NFC Integration Across Android, iOS, and WeChat Mini Programs

Introduction

Near Field Communication (NFC) operates at 13.56 MHz within a 10 cm range and supports three data rates: 106 kbit/s, 212 kbit/s, and 424 kbit/s. It evolved from RFID and combines a reader, a card, and peer‑to‑peer communication on a single chip, enabling devices such as smartphones to exchange data when brought close together.

Comparison with Other Short‑Range Technologies

Besides NFC, common short‑range wireless technologies include RFID, Bluetooth, ZigBee, infrared, and Wi‑Fi. NFC stands out for its high security, performance advantages in short‑range communication, and low cost, making it ideal for mobile payments, electronic tickets, identity verification, and anti‑counterfeiting (e.g., Maotai and Wuliangye bottles).

How to Use NFC

To achieve full‑scene NFC coverage across Android, iOS, and WeChat mini‑programs, the recommended approach is to use the NDEF (NFC Data Exchange Format) for all data exchange. NDEF ensures compatibility between platforms.

1. NFC Chip Data Writing

1.1 Understand NDEF

NFC communication follows the NDEF protocol, which consists of one or more Records. Each Record follows the RTD (Record Type Definition) specification. A typical RTD_URI record contains an identifier code (URI prefix) and a UTF‑8 string representing the rest of the URI.

1.2 Write Data Rules

The payload must follow the RTD_URI format, and the header’s Type field must be set to TNF_WELL_KNOWN. Two Records are required for cross‑platform compatibility:

HTTP Record (contains the URL to open)

Android Application Record (opens the app if installed)

1.3 Code Example (Android)

fun writeNfcData(intent: Intent) {
    val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
    val ndef = Ndef.get(tag)
    ndef.connect()
    // Add an HTTP Record
    val schemeRecord = NfcRecordUtils.getHttpRecord("https://example.com")
    // Add Android Application Record
    val appRecord = NdefRecord.createApplicationRecord("com.example.app")
    val maxSize = ndef.maxSize
    Log.e("NFC", "Maximum size: $maxSize")
    val ndefMessage = NdefMessage(arrayOf(schemeRecord, appRecord))
    ndef.writeNdefMessage(ndefMessage)
}

1.4 Utility Class (HttpRecordUtils)

@JvmStatic
fun getHttpRecord(url: String, id: String? = null): NdefRecord {
    var uri = Uri.parse(url).normalizeScheme()
    var uriString = uri.toString()
    require(uriString.isNotEmpty()) { "uri is empty" }
    var prefix: Byte = 0
    for (i in 1 until URI_PREFIX_MAP.size) {
        if (uriString.startsWith(URI_PREFIX_MAP[i])) {
            prefix = i.toByte()
            uriString = uriString.substring(URI_PREFIX_MAP[i].length)
            break
        }
    }
    val uriBytes = uriString.toByteArray(StandardCharsets.UTF_8)
    val recordBytes = ByteArray(uriBytes.size + 1)
    recordBytes[0] = prefix
    System.arraycopy(uriBytes, 0, recordBytes, 1, uriBytes.size)
    return NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, id?.toByteArray(Charsets.UTF_8) ?: ByteArray(0), recordBytes)
}

2. iOS Integration

Enable NFC capability in the Apple developer account, add Privacy - NFC Scan Usage Description to Info.plist, and implement NFCNDEFReaderSession to start scanning. The delegate methods provide the scanned NDEF messages, which can be converted to strings and processed.

#import "ViewController.h"
#import <CoreNFC/CoreNFC.h>
@interface ViewController () <NFCNDEFReaderSessionDelegate>
@end
@implementation ViewController
- (void)startScan {
    NFCNDEFReaderSession *session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:nil invalidateAfterFirstRead:YES];
    [session beginSession];
}
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages {
    for (NFCNDEFMessage *message in messages) {
        for (NFCNDEFPayload *record in message.records) {
            NSString *dataStr = [[NSString alloc] initWithData:record.payload encoding:NSUTF8StringEncoding];
            NSLog(@"Scan result: %@", dataStr);
        }
    }
}
- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error {
    NSLog(@"Error callback: %@", error);
}
@end

iOS devices supporting NFC start from iPhone 7/7 Plus with iOS 11 or later. The app must run in the foreground; newer iPhone models support background scanning.

2.1 App Clip Integration

If the NFC tag contains a universal link, iOS can launch an App Clip. Configure associated domains, the apple-app-site-association file, and handle the URL in userActivity.

3. Android Integration

Declare NFC permissions and features in AndroidManifest.xml, add intent filters for ACTION_VIEW, ACTION_NDEF_DISCOVERED, and ACTION_TAG_DISCOVERED, then handle the intent data in the activity.

<uses-feature android:name="android.hardware.nfc" android:required="true"/>
<uses-permission android:name="android.permission.NFC"/>
<activity android:name=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:host="xxx.xxx.com" android:scheme="https" android:path="/nfc"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:host="xxx.xxx.com" android:scheme="https" android:path="/nfc"/>
    </intent-filter>
</activity>

In MainActivity, retrieve the NDEF messages from the intent, parse the payload, and extract query parameters.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        dispatchIntent(intent)
    }
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        dispatchIntent(intent)
    }
    private fun dispatchIntent(intent: Intent) {
        when (intent.action) {
            NfcAdapter.ACTION_NDEF_DISCOVERED -> dispatchNfcLink(intent.data)
        }
    }
    private fun dispatchNfcLink(data: Uri?) {
        data?.let {
            val param1 = it.getQueryParameter("param1")
            val param2 = it.getQueryParameter("param2")
        }
    }
}

3.1 Scan NFC Tags Within the App

Enable foreground dispatch with a PendingIntent, filter for NDEF, TECH, and TAG actions, and process the received NdefMessage objects.

class ScanNfcResultActivity : BaseActivity() {
    private var nfcAdapter: NfcAdapter? = null
    private lateinit var nfcFilter: Array<IntentFilter>
    private lateinit var techList: Array<Array<String>>
    private lateinit var pendingIntent: PendingIntent
    override fun onResume() {
        super.onResume()
        nfcAdapter?.enableForegroundDispatch(this, pendingIntent, nfcFilter, techList)
    }
    override fun onPause() {
        super.onPause()
        nfcAdapter?.disableForegroundDispatch(this)
    }
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
        rawMsgs?.let {
            val msg = it[0] as NdefMessage
            parseNFCData(msg.records)
        }
    }
    private fun parseNFCData(records: Array<NdefRecord>) {
        records.forEach { record ->
            val payload = String(record.payload)
            // handle payload according to record.id
        }
    }
}

4. WeChat Mini‑Program Integration

Use the WeChat NFC API to start discovery, handle the onDiscovered callback, decode the payload (Base64), and stop discovery when finished.

const NFCAdapter = wx.getNFCAdapter();
NFCAdapter.startDiscovery({
  success: () => wx.showToast({title: '请将设备靠近要识别的 NFC 芯片', icon: 'none', duration: 2000}),
  fail: () => console.error('刷新重试')
});
const discoveredCallBack = (callBack) => {
  wx.showToast({title: '已成功获取到信息', icon: 'none', duration: 500});
  const record = callBack.messages[0].records[0];
  const payload = Base64.decode(wx.arrayBufferToBase64(record.payload));
  // process payload
  NFCAdapter.offDiscovered(discoveredCallBack);
  NFCAdapter.stopDiscovery();
};
NFCAdapter.onDiscovered(discoveredCallBack);

Conclusion

By following the steps above you can integrate NFC functionality for most business scenarios, including offline promotion, anti‑counterfeiting, access control, and seamless app or App Clip launching. Experiment with the code, adapt it to your product, and unlock the full potential of NFC.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSAndroidWeChat Mini ProgramNFCNDEF
BaiPing Technology
Written by

BaiPing Technology

Official account of the BaiPing app technology team. Dedicated to enhancing human productivity through technology. | DRINK FOR FUN!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.