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

使用CoreNFC写入iCode Slix2 NFC标签稳定性问题求助

iOS CoreNFC 写入iCode Slix2标签失败问题排查与解决

错误含义解析

  • Error Code 100(Tag connection lost):设备与标签的NFC连接中断,多因标签距离过远、位置移动,或连续指令发送间隔过短导致标签来不及响应。
  • Error Code 102(ISO15693TagResponseErrorCode=15):ISO 15693标准中,错误码15对应**"Write not allowed"**,说明目标块处于锁定状态,或标签写保护机制被触发,无法执行写入/擦除操作。
  • Error Code 401(Stack Error):底层NFC栈连接意外关闭,多由上层指令发送逻辑不合理导致连接不稳定。

代码问题与优化方案

1. 连续块写入无间隔导致标签过载

当前递归连续写入块的逻辑未给标签留出处理时间,高频指令会导致标签过载断开连接。

优化:每次写入后添加50-100ms延迟:

func write(data: Data, to tag: NFCISO15693Tag, at block: UInt8) async throws {
    print("🏷️", "Writing data:", data, data.hexEncodedString(.upperCase), "at block:", block)
    try await tag.writeSingleBlock(requestFlags: [.highDataRate], blockNumber: block, dataBlock: data)
    // 给标签预留处理时间
    try await Task.sleep(nanoseconds: 50_000_000)
}

2. 缺失块锁定状态检查

iCode Slix2部分系统块默认锁定,或之前操作设置了用户块锁定,直接写入会触发错误码15。

补充逻辑:先检查块锁定状态,跳过或解锁后再写入:

func getBlockLockStatus(from tag: NFCISO15693Tag, block: UInt8) async throws -> Bool {
    let blockData = try await tag.readSingleBlock(requestFlags: [], blockNumber: block)
    // 参考iCode Slix2手册解析锁定位,示例为第7位
    return blockData[0] & 0x80 != 0
}

// 修改erase函数中的writeNextBlock逻辑
func writeNextBlock() async throws {
    if blockNumber < totalBlocks {
        alertMessage = "ERASING TAG \(blockNumber)/\(totalBlocks)"
        
        let isLocked = try await getBlockLockStatus(from: tag, block: blockNumber)
        if isLocked {
            print("Block \(blockNumber) is locked, skipping...")
            blockNumber += 1
            try await writeNextBlock()
            return
        }
        
        let blankData = Data(repeating: 0x00, count: blockSize)
        try await write(data: blankData, to: tag, at: blockNumber)
        
        blockNumber += 1
        try await writeNextBlock()
    } else {
        alertMessage = "Tag erased successfully!"
    }
}

3. 请求标志位兼容性问题

.highDataRate标志可能导致部分标签兼容性差,可尝试使用默认速率:

try await tag.writeSingleBlock(requestFlags: [], blockNumber: block, dataBlock: data)

4. Session生命周期与连接校验

连接后需确认标签可用状态,避免无效操作:

Task {
    do {
        try await session.connect(to: currentTag)
        guard currentTag.isAvailable else {
            throw NSError(domain: "TagError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Tag unavailable after connection"])
        }
        print("Connected: ========\(currentTag.isAvailable)========")
        try await erase(tag: iso15693Tag)
        session.alertMessage = "Erase completed"
        session.invalidate()
    } catch {
        print("❗️", error)
        session.invalidate(errorMessage: error.localizedDescription)
    }
}

额外优化与注意事项

  • 批量写入减少通信次数:iCode Slix2支持多块写入,可减少指令发送频次提升稳定性:
func writeMultipleBlocks(data: [Data], to tag: NFCISO15693Tag, startingBlock: UInt8) async throws {
    try await tag.writeMultipleBlocks(requestFlags: [], startBlockNumber: startingBlock, dataBlocks: data)
    try await Task.sleep(nanoseconds: 100_000_000)
}

// 批量处理擦除逻辑
func erase(tag: NFCISO15693Tag) async throws {
    print("🏷️", "ERASING TAG")
    alertMessage = "ERASING TAG..."
    
    let sysInfo = try await getSystemInfo(from: tag)
    let totalBlocks = sysInfo.totalBlocks - 1
    let blockSize = sysInfo.blockSize
    var currentBlock: UInt8 = 0
    let batchSize: UInt8 = 4
    
    while currentBlock < totalBlocks {
        let endBlock = min(currentBlock + batchSize - 1, totalBlocks)
        alertMessage = "ERASING TAG \(currentBlock)/\(totalBlocks)"
        
        var batchData = [Data]()
        var skipBatch = false
        for block in currentBlock...endBlock {
            let isLocked = try await getBlockLockStatus(from: tag, block: block)
            if isLocked {
                print("Block \(block) is locked, skipping batch...")
                skipBatch = true
                break
            }
            batchData.append(Data(repeating: 0x00, count: blockSize))
        }
        
        if !skipBatch && !batchData.isEmpty {
            try await writeMultipleBlocks(data: batchData, to: tag, startingBlock: currentBlock)
        }
        
        currentBlock = endBlock + 1
    }
    
    alertMessage = "Tag erased successfully!"
}
  • 权限与设备要求:确保Info.plist配置NFCReaderUsageDescription,且设备运行iOS 13及以上版本。
  • 操作引导:提示用户将iPhone NFC感应区(顶部)对准标签中心,保持稳定直至操作完成。

ISO15693错误码查询方式

ISO15693错误码的官方定义可通过目标标签的数据手册查询,iCode Slix2手册中会明确每个错误码的触发原因;也可参考ISO 15693-3标准文档,其中规定了通用响应错误码的含义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:07:03