You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何将URL以正确格式写入NFC标签

NFC URL写入Payload格式错误修正方案

你遇到的问题来源于两个核心错误:

  • 错误混用了NDEF文本记录和URI记录的构造规则:最开始的\u{02}en是NDEF文本记录的固定前缀(状态字节+语言码),完全不适用于URI类型记录
  • 构造NFCNDEFPayload时type参数传空,导致系统无法正确识别为URI记录,payload长度解析错误出现内容截断。你之前仅去掉\u{02}en前缀仍然出现截断,就是因为这个参数错误导致的。

正确的URI类型NDEF记录构造规则

NFC Well Known类型的URI记录必须满足以下要求:

  • type参数必须传入Data("U".utf8),标识这是URI类型记录
  • payload的第一个字节为URI前缀压缩码,常用压缩码对应关系:
    • 0x00:无前缀,后续跟完整URI字符串
    • 0x01:http://www.
    • 0x02:https://www.
    • 0x03:http://
    • 0x04:https://
  • 第一个字节之后跟剩余URI内容的UTF8编码数据

修正后的完整代码

private func writeTag(_ tag: NFCNDEFTag, for session: NFCReaderSession?) {
    guard let rawUrl = self.url, !rawUrl.isEmpty else {
        session?.invalidate(errorMessage: "URL is empty")
        return
    }
    
    var payloadData = Data()
    // 可根据实际URL前缀匹配对应压缩码,也可直接用0x00加完整URL
    if rawUrl.hasPrefix("https://") {
        payloadData.append(0x04)
        let suffix = String(rawUrl.dropFirst(8))
        guard let suffixData = suffix.data(using: .utf8) else {
            session?.invalidate()
            return
        }
        payloadData.append(suffixData)
    } else if rawUrl.hasPrefix("http://") {
        payloadData.append(0x03)
        let suffix = String(rawUrl.dropFirst(7))
        guard let suffixData = suffix.data(using: .utf8) else {
            session?.invalidate()
            return
        }
        payloadData.append(suffixData)
    } else {
        payloadData.append(0x00)
        guard let fullData = rawUrl.data(using: .utf8) else {
            session?.invalidate()
            return
        }
        payloadData.append(fullData)
    }
    
    // 注意type参数传入"U"的UTF8数据
    let record = NFCNDEFPayload(
        format: .nfcWellKnown,
        type: Data("U".utf8),
        identifier: Data(),
        payload: payloadData
    )
    let myMessage = NFCNDEFMessage(records: [record])
    tag.writeNDEF(myMessage) { error in
        if let error = error {
            session?.invalidate(errorMessage: "Couldn't write tag: \(error.localizedDescription)")
        } else {
            session?.alertMessage = "Tag is written successfully"
            session?.invalidate()
        }
    }
}

内容的提问来源于stack exchange,提问作者MaryLitv21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:57:04