Ios 如何解析U类型的NFC数据

Ios 如何解析U类型的NFC数据,ios,swift,parsing,nfc,Ios,Swift,Parsing,Nfc,我正试图解析格式化的NFC芯片的有效负载,但在记录时遇到问题。type==U 我正在使用安卓手机和appNXP writer,来编写我的NFC芯片。 我得到了record.type==T的所有内容,但是当我得到record.type==U时,我遇到了一些困难 我在网上找到的想法是,将数据转换为hexString并检查前两个数字,然后您可以对URI可能具有的以下类别进行分类 示例: 0x00不适用。未进行任何预处理 0x01 0x02 0x03 http:// 0x04 https:// 0x0

我正试图解析格式化的
NFC芯片的有效负载,但在
记录时遇到问题。type==U

我正在使用安卓手机和app
NXP writer
,来编写我的NFC芯片。 我得到了
record.type==T
的所有内容,但是当我得到
record.type==U
时,我遇到了一些困难

我在网上找到的想法是,将
数据转换为hexString
检查前两个数字,然后您可以对URI可能具有的以下类别进行分类

示例:

  • 0x00不适用。未进行任何预处理
  • 0x01
  • 0x02
  • 0x03 http://
  • 0x04 https://
  • 0x05电话:
  • 0x06邮寄地址:
  • 0x07
  • 0x08
  • hexString=“02676f6f676c652e636f6d”

    substring=“02”

    然后我们有
    https://www
    我们从负载中添加字符串,然后打开safari(或者我们想做的任何事情)

    当我想读取一个NFC标签/芯片,其中包含到目前为止的Tel、mailto、geo和sms时,就会出现问题。

    代码是3位数
    006,而不是我在网上看到的2位数。不仅如此,如果我决定进行地理定位,
    我得到006,这与mailto code
    相同。当然,我可以用更多的代码来解决这个问题,但既然有解决方案,他们只检查那些代码,我能做些什么,还是我做错了什么

    问题:

  • NXP writer有问题吗?我正面临这个问题
  • NFC编码是否已更改
  • 我的逻辑正确吗
  • 这是我的密码:

        func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        session.invalidate()
    
    
        for message in messages{
    
            for record in message.records{
    
                guard record.payload.count > 0 else {
                    print("Record payload doesn't contain any data in the memory")
                    session.invalidate()
                    return
                }
    
                guard let NFCTypeFromTag = String(data: record.type, encoding: .utf8) else{
                    print("Unable to detect the Type")
                    session.invalidate()
                    return
                }
    
                guard let nfcTypeInput = NFCType(rawValue: NFCTypeFromTag) else {
                    print("nfc enum problem")
                    session.invalidate()
                    return
                }
    
                switch nfcTypeInput{
                case .T:
                    guard let NFCStringFromPayload = String(data: record.payload.advanced(by: 3), encoding: .utf8) else {
                        return
                    }
                    NFCString = NFCStringFromPayload
                case .U:
                    guard let NFCStringFromPayload = String(data: record.payload, encoding: .utf8) else{
                        print("Error: Unable to convert record.payload to String")
                        return
                    }
    
                    let hexString = record.payload.hexEncodedString()
                    let indexEndFromHexString = hexString.index(hexString.startIndex, offsetBy: 2)
    
                    let substring = hexString[hexString.startIndex ..< indexEndFromHexString]
    
                    print("NFCString : \(NFCStringFromPayload)")
                    print("HexString : \(hexString)")
                    print("Substring : \(substring)")
    
                    if substring == "00"{
                        let indexEndOfHexStringCase00 = hexString.index(hexString.startIndex, offsetBy: 3)
                        let substringCase00 = hexString[hexString.startIndex..<indexEndOfHexStringCase00]
                        if substringCase00 == "005" {
                            print("Tel:")
                        }else if substringCase00 == "006"{
                            print("mailto:")
                        }else if substringCase00 == "007" {
                            print("sms")
                        }
                    }else if substring == "01"{
                        print("http://www")
                    }else if substring == "02"{
                        print("https://www")
                    }
    
                    NFCString = NFCStringFromPayload
    
               case .Sp:
                    break
                }
                NFCArray.append(NFCString!)
                tableView.reloadData()
                print("NFC String : \(NFCString)")
    
            }
        }
    
    func readerSession(session:NFCNDEFReaderSession,didDetectDefs消息:[NFCNDEFMessage]){
    session.invalidate()
    对于消息中的消息{
    用于message.records中的记录{
    guard record.payload.count>0其他{
    打印(“记录有效负载在内存中不包含任何数据”)
    session.invalidate()
    返回
    }
    guard let NFCTypeFromTag=String(数据:record.type,编码:.utf8)else{
    打印(“无法检测类型”)
    session.invalidate()
    返回
    }
    guard let nfcTypeInput=NFCType(rawValue:NFCTypeFromTag)else{
    打印(“nfc枚举问题”)
    session.invalidate()
    返回
    }
    开关NFCTYPE输入{
    案例T:
    guard let NFCStringFromPayload=String(数据:record.payload.advanced(by:3),编码:.utf8)else{
    返回
    }
    NFCString=NFCStringFromPayload
    案例U:
    guard let NFCStringFromPayload=String(数据:record.payload,编码:.utf8)else{
    打印(“错误:无法将record.payload转换为字符串”)
    返回
    }
    让hexString=record.payload.hexEncodedString()
    让indexEndFromHexString=hexString.index(hexString.startIndex,偏移量:2)
    让substring=hexString[hexString.startIndex..让substringCase00=hexString[hexString.startIndex..您可以直接使用
    数据
    ,无需使用
    字符串
    十六进制转换

    func parseURINFC(_ data: Data) -> String? {
        let prefix = data.prefix(1)
        let rest = data.dropFirst(1)
    
        switch prefix {
        case Data(bytes: [0x00]):
            return nil
        case Data(bytes: [0x01]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "http://www." + restString
        case Data(bytes: [0x02]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "https://www." + restString
        case Data(bytes: [0x03]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "http://" + restString
        case Data(bytes: [0x04]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "https://" + restString
        case Data(bytes: [0x05]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "tel://" + restString
        case Data(bytes: [0x06]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "mailto://" + restString
        case Data(bytes: [0x07]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "ftp://anonymous:anonymous@" + restString
        case Data(bytes: [0x08]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "ftp://ftp." + restString
        default:
            return nil
        }
    }
    

    关于
    006-
    007-
    前缀,根据您提供的链接(),它是无效的。事件在尝试使用UTF8转换其余部分后(因为它是URI,所以应该是),它返回nil。

    您可以直接使用
    数据
    ,无需使用
    字符串
    十六进制转换

    func parseURINFC(_ data: Data) -> String? {
        let prefix = data.prefix(1)
        let rest = data.dropFirst(1)
    
        switch prefix {
        case Data(bytes: [0x00]):
            return nil
        case Data(bytes: [0x01]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "http://www." + restString
        case Data(bytes: [0x02]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "https://www." + restString
        case Data(bytes: [0x03]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "http://" + restString
        case Data(bytes: [0x04]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "https://" + restString
        case Data(bytes: [0x05]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "tel://" + restString
        case Data(bytes: [0x06]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "mailto://" + restString
        case Data(bytes: [0x07]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "ftp://anonymous:anonymous@" + restString
        case Data(bytes: [0x08]):
            guard let restString = String(data: rest, encoding: .utf8) else { return nil }
            return "ftp://ftp." + restString
        default:
            return nil
        }
    }
    

    关于
    006-
    007-
    前缀,根据您提供的链接(),它是无效的。事件尝试使用UTF8转换其余部分后(因为它是URI,所以应该是这样),它返回nil。

    我不理解“00”和“006”的情况,但不使用字符串转换,您可以执行以下操作:
    let prefix=record.payload.prefix(1);let rest=record.payload.dropFirst(1);开关前缀:案例数据(字节:[0x02]):如果let restString=String(数据:rest,编码:.utf8){let final=”https://www.“+restString}
    ,并添加所有的开关盒。首先感谢您的回答。盒00表示代码可能是3位数字而不是2位。
    hexString=00736d733a39303632363231343f626f64793d686920
    这意味着子串2给我们00,所以寻找额外的数字007。但我买了一部Android手机,下载了另一个应用程序,在那里它可以完美地工作它应该以子字符串2作为我从堆栈溢出中发布的答案。因此我相信这只是NXP Writer在这些情况下的问题。解决方案是使用一种方法来分析该字符串,如果它有前缀“00”,则删除第一个字符串,并称自己为(递归)。这是一个问题,因为如果它是“数据”,那么它必须是字符串长度中的“偶数”计数(0到255个值,0x00到0xFF,您不能将其切成两半,“结束”可能会导致问题)。而“00736D733A393632363231343F626F64793D686920”后面的值应该是什么?我是NFC新手,我相信它应该是0736D733A393303632363231343F626F64793D686920。前面的数字不到0。我正在使用其他应用程序编写标记,到目前为止,所有URI选项都可以按十六进制字符串的前2位进行分类。我将此作为指南,在这里您可以找到URI的所有不同选项。但我不是苏你百分之百肯定。到目前为止看起来是这样。你有经验吗?我没有