# useNFC

useNFC 是一个用于读写NFC功能的 Vue 3 Composition API Hook，支持 Android 设备和 微信小程序 NFC 操作。

## 功能特性

- 多平台支持: 安卓，微信

## 安装或引入

```js
import useNFC from 'uni-vite-dev-tool/dist/dev/v3/hooks/useNFC';
```

## 参数说明

callback (必需)

- 类型: (code) => void
- 说明: 扫码成功后的回调函数，接收扫码得到的字符串
  options (可选)
- 类型: Object

  | 属性                | 类型   | 必需 | 默认值 | 说明                        |
  | ------------------- | ------ | ---- | ------ | --------------------------- |
  | timeout             | number | 否   | -      | 连接超时事件，安卓无效      |
  | checkConnectedDelay | number | 否   | 500    | 检测连接状态 间隔，微信无效 |

## 示例代码

```ts
<template>
  <view class="content">
    <button @click="onTestStartHCE">开始HCE</button>
    <button @click="onStopHCE">停止HCE</button>
    <button @click="onTestConnect">链接</button>
    <button @click="onTestClose">断开</button>
    <button @click="onTestWrite">写入</button>

    <view>当前设备是否支持 NFC:{{ isSupportNFC }}</view>
    <view>当前 NFC 启用状态:{{ isListening }}</view>
    <view>当前 NFC 连接状态:{{ isConnected }}</view>

    <view>读取结果：</view>
    <JsonPretty
      :data="data"
      :nodeSelectable="() => {}"
      :pathCollapsible="() => {}"
    />
  </view>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import useNFC from '../../dev/v3/hooks/useNFC';
import JsonPretty from '../../dev/v3/JsonPretty/index.vue';

const data = ref({});

const {
  data: nfcData,
  isListening,
  isConnected,
  isSupportNFC,
  isNdef,
  startHCE,
  stopHCE,
  connect,
  close,
  write,
  writeNdf,
} = useNFC((res) => {
  data.value = res;
  console.log('res: ', res);
});

function onTestStartHCE() {
  startHCE();
}

function onStopHCE() {
  stopHCE();
}

function onTestConnect() {
  connect();
}

function onTestClose() {
  close();
}

/**
 * 写入流程
 * 初始化
 * 打开连接
 * 读取数据（id）
 * 写入前验证
 * 写入
 * 关闭连接
 *
 * TODO 缺一张可写入的 nfc 卡，暂时无法实现
 */

async function onTestWrite() {
  try {
    const arrayBuffer = nfcData.value?.hexNumberArray ?? [];
    const params = {
      cmd: 0x60, // 验证指令
      block: 0x03, // 扇区
      cardId: [arrayBuffer[0], arrayBuffer[1], arrayBuffer[2], arrayBuffer[3]], // 卡片id 获取从 NFCAdapter.onDiscovered((res)=>{ // res中含有卡片id });
      key: [0xff, 0xff, 0xff, 0xff, 0xff, 0xff], // 验证密钥
    };

    const arr = [params.cmd, params.block, ...params.cardId, ...params.key];

    const uArray = new Uint8Array(arr);

    console.log('uArray.length: ', uArray.length);
    console.log('nfcData: ', nfcData);

    // if (maxTransceiveLength.value < uArray.length) {
    //   uni.showToast({
    //     title: '数据长度超出限制',
    //   });
    //   return;
    // }

    const writeBuffer = new Uint8Array(arr).buffer;

    // const res = await write(writeBuffer);

    // console.log('res: ', res);
  } catch (error) {
    console.log('error: ', error);
  }
}
</script>

<style>
.content {
  padding: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

button {
  width: 100%;
}
</style>


```

## 读取结果

```json
{
  "id": [-91, -36, 74, -14],
  "techs": ["NFC-A", "MIFARE Classic", "Ndef Formatable"],
  "byteArray": [165, 220, 74, 242],
  "hexArray": ["A5", "DC", "4A", "F2"],
  "hexNumberArray": [],
  "hexString": "A5:DC:4A:F2",
  "uidType": 0,
  "storageSize": 0,
  "manufacturer": 4,
  "cardFeatures": 0,
  "reserved": 0,
  "sak": 8,
  "sakHex": "0x08",
  "sakType": "Mifare Classic 1K",
  "message": "",
  "maxTransceiveLength": 253,
  "readWriteStandard": ["ISO 14443-3A", "ISO 14443-3A", "NDEF Formatable"]
}
```
