"Tag connection lost" 在 iOS 13 上读取 Mifare Ultralight NFC 标签时出错

"Tag connection lost" error when reading a Mifare Ultralight NFC tag on iOS 13

我正在尝试读取 Mifare Ultralight 标签的页面(更具体地说是 EnOcean PTM 215B) using NFCMifareTag.sendMifareCommand 方法,在它被发现并连接到它之后。问题是我尝试发送的所有命令都会导致"Tag connection lost" 错误,这很奇怪,因为我刚刚成功连接到它。

(简化的)代码如下所示:

// tag has been determined to be of type NFCMifareTag earlier
session.connect(to: tag) { (error: Error?) in
  if (error != nil) {
    return
  }

  print("Connected to the tag")

  let data: [UInt8] = [0x30, 0x04, 0xEE, 0x26] // READ page 4 + CRC
  let dataPacket = Data(bytes: data, count: data.count)

  tag.sendMifareCommand(
    commandPacket: dataPacket,
    completionHandler: { (response: Data?, error: Error?) in
      if nil != error {
        return // <-- "Tag connection lost" error
      }
      // Handle the data as the operation was successful
    }
  )
}

如果有任何关于此行为可能原因的建议 and/or,我将不胜感激。如前所述,我尝试过各种不同的数据包,但都完全一样。我还尝试了多种不同的手机来消除硬件问题。 iOS 13 中刚刚添加了支持,因此我无法在网上找到任何使用 sendMifareUltralight 命令的示例。

根据API (CoreNFC/NFCMiFareTag) CRC 将自动计算并插入。因此,在您的情况下,您只需要发送 [0x30, 0x04] 即可读取第 4 至 7 页,读取命令 0x30 将读取 4 页,您将获得 16 个字节。

 /**
 * @method sendMiFareCommand:completionHandler:
 *
 * @param command           The complete MiFare command.  CRC bytes are calculated and inserted automatically to the provided packet data frame.
 * @param completionHandler Completion handler called when the operation is completed.  error is nil if operation succeeds. A @link NFCErrorDomain @link/ error
 *                          is returned when there is a communication issue with the tag. Successfully read data blocks will be returned from the NSData object.
 *
 * @discussion              Send native MIFARE command to a tag.  Support MIFARE UltraLight, Plus, and DESFire products.
 *                          Crypto1 protocol is not supported.  Command chainning is handled internally by the method and the full response composed of the
 *                          individual fragment is returned in the completion handler.
 */
@available(iOS 13.0, *)
func sendMiFareCommand(commandPacket command: Data, completionHandler: @escaping (Data, Error?) -> Void)