更新记录

1.0.0(2026-03-13)

  • iOS 扫描主路径切到 CoreNFC NFCTagReaderSession,补齐 transceive(options) 的部分能力对齐,支持 iso_dep / mifare_ultralight / nfc_fnfc_v 需 iOS 14+
  • iOS 扫描结果开始回传 platformExtras.techDetails / platformExtras.transceiveTechnologies,并补齐会话关闭原因映射
  • iOS 编译链已在 HBuilderX 4.87 + iOS Simulator 跑通,真实 NFC 验收仍需真机
  • Android 新增 transceive(options),支持 iso_dep / nfc_a / nfc_b / nfc_f / nfc_v / mifare_ultralight
  • Android 扫描结果补充 platformExtras.techDetails,暴露各 technology 的基础能力信息
  • Android ReaderMode 会在系统 NFC 被关闭或宿主 Activity 销毁时补发 onSessionClosed(system_interrupted)
  • Android 扫描结果补充 NdefFormatable 标签的可格式化写入提示
  • Android 原生回调统一切回主线程分发,减少 UTS 监听器线程不一致
  • 抽出 utssdk/runtime.uts,统一 listener、session state 与 log state 管理
  • 抽出 utssdk/platform-stub.uts,收敛 iOS / Harmony stub 重复代码
  • Android 入口新增宿主销毁清理,避免静态 session 状态和 native callback 残留
  • README 补齐导入方式、最小接入示例、iOS 进阶配置说明、完整错误码说明
  • package.json 版本与权限声明同步到 Android + iOS 当前事实
  • 重构公共 UTS 接口为 NFC 会话模型
  • 新增统一错误码与错误对象实现
  • Android 接入 ReaderMode 扫描与 NDEF text/uri 写入主路径
  • iOS 接入 CoreNFC 配置文件与 Swift service 骨架
  • Harmony 保持 stub only
  • playground 首页改为 NFC 调试台

平台兼容性

uni-app(4.87)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.87)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - -

hans-nfc

uni-app / uni-app x NFC 插件,提供扫描、NDEF 写入和 raw transceive 能力。

平台支持

平台 状态 能力
Android supported 扫描、NDEF 读取/写入、raw transceive
iOS supported 扫描、NDEF 读取/写入、raw transceive 子集
Harmony stub only 不提供 NFC 能力

版本要求

  • HBuilderX: ^4.87.0
  • uni-app: ^3.0.0
  • uni-app x: ^3.0.0
  • Android: minSdkVersion 21
  • iOS: deploymentTarget 13.0

导入

import {
  getNfcAvailability,
  onDiscovered,
  offDiscovered,
  onSessionClosed,
  offSessionClosed,
  startScan,
  stopScan,
  writeNdef,
  transceive,
  setLogEnabled
} from '@/uni_modules/hans-nfc'

快速开始

<script setup lang="uts">
import {
  NfcSessionClosedEvent,
  OnDiscoveredCallback,
  OnSessionClosedCallback,
  ScanResult,
  getNfcAvailability,
  offDiscovered,
  offSessionClosed,
  onDiscovered,
  onSessionClosed,
  setLogEnabled,
  startScan,
  stopScan,
  writeNdef
} from '@/uni_modules/hans-nfc'

const lastTag = ref<ScanResult | null>(null)

const discoveredHandler : OnDiscoveredCallback = (result : ScanResult) => {
  lastTag.value = result
  console.log('onDiscovered', JSON.stringify(result))
}

const closedHandler : OnSessionClosedCallback = (event : NfcSessionClosedEvent) => {
  console.log('onSessionClosed', JSON.stringify(event))
}

function queryAvailability() {
  getNfcAvailability({
    success: (result) => {
      console.log('availability', JSON.stringify(result))
    },
    fail: (err) => {
      console.error('availability failed', err.errCode, err.errMsg)
    }
  })
}

function beginScan() {
  startScan({
    alertMessage: '请将设备靠近 NFC 标签',
    success: () => {
      console.log('startScan success')
    },
    fail: (err) => {
      console.error('startScan failed', err.errCode, err.errMsg)
    }
  })
}

function writeText() {
  writeNdef({
    type: 'text',
    text: 'Hello NFC',
    languageCode: 'en',
    success: () => {
      console.log('writeNdef success')
    },
    fail: (err) => {
      console.error('writeNdef failed', err.errCode, err.errMsg)
    }
  })
}

onMounted(() => {
  setLogEnabled({ enabled: true })
  onDiscovered(discoveredHandler)
  onSessionClosed(closedHandler)
  queryAvailability()
})

onUnmounted(() => {
  offDiscovered(discoveredHandler)
  offSessionClosed(closedHandler)
  stopScan({})
})
</script>

推荐流程:

  1. 调用 getNfcAvailability 检查设备状态。
  2. 注册 onDiscoveredonSessionClosed
  3. 调用 startScan 开始扫描。
  4. 收到标签后调用 writeNdeftransceive
  5. 页面销毁或业务结束时调用 stopScan 并移除监听器。

API

API 说明
getNfcAvailability(options) 查询 NFC 是否可用
startScan(options) 开始扫描
stopScan(options) 停止扫描
onDiscovered(callback) 监听标签发现事件
offDiscovered(callback?) 取消标签发现监听
onSessionClosed(callback) 监听会话关闭事件
offSessionClosed(callback?) 取消会话关闭监听
writeNdef(options) 写入 NDEF
transceive(options) 对当前标签发起 raw 指令
setLogEnabled(options) 打开或关闭插件日志

写入

writeNdef 当前仅支持:

  • type: 'text'
  • type: 'uri'

Raw Transceive

transceive(options) 只能对当前扫描会话里最近一次发现的标签调用。

支持的 technology

technology Android iOS
iso_dep supported supported
nfc_a supported not supported
nfc_b supported not supported
nfc_f supported supported
nfc_v supported supported with limits
mifare_ultralight supported supported with limits

说明:

  • iOS 的实际可用 technology 取决于当前标签、系统版本和宿主配置。
  • Android 的 timeoutMs 只对部分 technology 生效。
  • iOS 保留 timeoutMs 参数,但是否生效取决于系统实现。

权限与配置

Android

插件已包含 NFC 权限和 feature 声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-permission android:name="android.permission.NFC" />
  <uses-feature
    android:name="android.hardware.nfc"
    android:required="false" />
</manifest>

iOS

最小配置:

info.plist

<key>NFCReaderUsageDescription</key>
<string>需要使用 NFC 读取和写入 NDEF 标签。</string>

UTS.entitlements

<key>com.apple.developer.nfc.readersession.formats</key>
<array>
  <string>NDEF</string>
  <string>TAG</string>
</array>

如果业务要访问 ISO7816 或 FeliCa 标签,宿主还需要补充:

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
  <string>YOUR_ISO7816_AID</string>
</array>
<key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
<array>
  <string>YOUR_FELICA_SYSTEM_CODE</string>
</array>

使用限制

  • iOS 写入应在发现标签后尽快调用,不要等会话结束。
  • iOS 模拟器只能验证编译和页面启动,不能作为 NFC 功能验收环境。
  • 使用标准基座只能验证页面和编译链;实际 NFC 联调仍需自定义基座和真机。

常见错误码

errCode 含义
9010101 设备不支持 NFC
9010103 系统 NFC 开关关闭
9010201 session 已激活
9010302 当前标签不支持所选 technology
9010402 标签不可写
9010403 NDEF payload 不合法
9010501 当前构建不支持此平台
9010601 writeNdef 需要活跃 session
9010605 transceive 需要活跃 session 和已发现 tag

调试

  • 调用 setLogEnabled({ enabled: true }) 可打开插件日志。
  • 真机联调时建议同时观察原生日志。

更多说明

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android 需要 NFC 权限;iOS 需要 NFCReaderUsageDescription 与 CoreNFC capability;访问 ISO7816 或 FeliCa 标签时还需补充对应 reader session 配置。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件仅在运行时访问 NFC 标签内容,不内置远程数据采集逻辑。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无广告

暂无用户评论。