iOS 11 – 如何从CoreNFC读取/parsingNDEF消息?

我有一堆标签是URL标签的内容“ http://WEBSITE.com ”。 比方说,WEBSITE是youtube所以http://youtube.com 。 当我在Android等扫描他们,它保持http或https。

我试图用核心NFC框架来扫描这些相同的标签。 我扫描他们,我得到了一堆字节,我用UTF8编码使用NSString的initWithData转换。 我回到\ ^ Cyoutube.com。 我想获得http://youtube.com 。

我怎样才能有效载荷来获得我所需要的? 如果我假设在string前面的http,我该怎么知道它是http还是https甚至是ftp?

编辑1:

我在纯文本logging的下面的答案代码有问题。 当为“hello world”创build文本logging时,我从控制台得到以下输出:

2017-06-09 12:45:35.151806-0400 testNFC [2963:190724]有效负载string: https://www.hehello world

2017-06-09 12:45:35.154959-0400 testNFC [2963:190724]有效载荷数据: <02656e68 656c6c6f 20776f72 6c64>

获取我使用的string

NSString * nfcMessage = [nfcType stringByAppendingString:[[[NSString alloc] initWithData:payload.payload encoding:NSUTF8StringEncoding] substringFromIndex:1]];

nfcType是你函数的返回值,但是对于None情况,我返回@“”;

我期待着得到你好世界。

为此,您首先需要确保您已正确格式化NDEF标记。 您可以使用Android手机或其中一种阅读器配件以及NDEF写作应用程序 。

实现以下方法:

- (NSString *)getType:(NSData *)NDEFData { NSString *firstByte = [self getFirstByte:NDEFData]; if ([firstByte isEqualToString:@"00"]) { return @"None"; } else if ([firstByte isEqualToString:@"01"]) { return @"http://www."; } else if ([firstByte isEqualToString:@"02"]) { return @"https://www."; } else if ([firstByte isEqualToString:@"03"]) { return @"http://"; } else if ([firstByte isEqualToString:@"04"]) { return @"https://"; } else if ([firstByte isEqualToString:@"05"]) { return @"tel:"; } else if ([firstByte isEqualToString:@"06"]) { return @"mailto:"; } else if ([firstByte isEqualToString:@"07"]) { return @"ftp://anonymous:anonymous@"; } else if ([firstByte isEqualToString:@"08"]) { return @"ftp://ftp."; } else if ([firstByte isEqualToString:@"09"]) { return @"ftps://"; } else if ([firstByte isEqualToString:@"0A"]) { return @"sftp://"; } else if ([firstByte isEqualToString:@"0B"]) { return @"smb://"; } else if ([firstByte isEqualToString:@"0C"]) { return @"nfs://"; } else if ([firstByte isEqualToString:@"0D"]) { return @"ftp://"; } else if ([firstByte isEqualToString:@"0E"]) { return @"dav://"; } else if ([firstByte isEqualToString:@"0F"]) { return @"news:"; } else if ([firstByte isEqualToString:@"10"]) { return @"telnet://"; } else if ([firstByte isEqualToString:@"11"]) { return @"imap:"; } else if ([firstByte isEqualToString:@"12"]) { return @"rtsp://"; } else if ([firstByte isEqualToString:@"13"]) { return @"urn:"; } else if ([firstByte isEqualToString:@"14"]) { return @"pop:"; } else if ([firstByte isEqualToString:@"15"]) { return @"sip:"; } else if ([firstByte isEqualToString:@"16"]) { return @"sips:"; } else if ([firstByte isEqualToString:@"17"]) { return @"tftp:"; } else if ([firstByte isEqualToString:@"18"]) { return @"btspp://"; } else if ([firstByte isEqualToString:@"19"]) { return @"btl2cap://"; } else if ([firstByte isEqualToString:@"1A"]) { return @"btgoep://"; } else if ([firstByte isEqualToString:@"1B"]) { return @"tcpobex://"; } else if ([firstByte isEqualToString:@"1C"]) { return @"irdaobex://"; } else if ([firstByte isEqualToString:@"1D"]) { return @"file://"; } else if ([firstByte isEqualToString:@"1E"]) { return @"urn:epc:id:"; } else if ([firstByte isEqualToString:@"1F"]) { return @"urn:epc:tag:"; } else if ([firstByte isEqualToString:@"20"]) { return @"urn:epc:pat:"; } else if ([firstByte isEqualToString:@"21"]) { return @"urn:epc:raw:"; } else if ([firstByte isEqualToString:@"22"]) { return @"urn:epc:"; } else if ([firstByte isEqualToString:@"23"]) { return @"urn:nfc:"; } return @""; } /*! * gets the the NDEF content */ - (NSString *)getNDEFContent:(NSData *)data { NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return [dataString substringFromIndex:2]; } /*! * gets the first byte of the input NSData */ - (NSString *)getFirstByte:(NSData *)data { return [[self dataToHexString:data] substringToIndex:2]; } /*! * transforms NSData to NSString */ - (NSString *)dataToHexString:(NSData *)data; { // get the length of the data NSUInteger bytesCount = data.length; if (bytesCount) { // string with all the Hex characters const char *hexChars = "0123456789ABCDEF"; // put bytes into an array and initialize the response array const unsigned char *dataBuffer = data.bytes; char *chars = malloc(sizeof(char) * (bytesCount * 2 + 1)); char *s = chars; // go through data bytes making the transformations so a hex will literally translate to a string, so for example 0x0A will translate to "0A" for (unsigned i = 0; i < bytesCount; ++i) { // get hexChars character at binary AND between the current byte and 0xF0 bitwise to the right by 4 index and assign it to the current chars pointer *s++ = hexChars[((*dataBuffer & 0xF0) >> 4)]; // get hexChars character at binary AND between the current byte and 0x0F index and assign it to the current chars pointer *s++ = hexChars[(*dataBuffer & 0x0F)]; dataBuffer++; } *s = '\0'; // chars to string NSString *hexString = [NSString stringWithUTF8String:chars]; free(chars); return hexString; } return @""; } 

并调用getType方法:

 [self getType:yourNDEFPayloadNSData] 
  • 我假设所有的方法都在同一个类中,

  • 有效载荷NSData是NDEF兼容的,但是我基于NFCNDEFPayload payloadbuild模了代码

NFC NDEF消息的有效载荷要比你想象的复杂得多。 但CoreNFC不支持parsingNFC NDEF消息的有效载荷。 我创build了一个开源parsing器VYNFCKit来分析负载。 Objective-C和Swift都提供了示例项目。 检查我的教程https://medium.com/@vinceyuan/reading-and-parsing-nfc-tag-on-ios-11-60f4bc7a11ea

关于您的EDIT1:您正在使用错误的loggingtypes。 你需要写一个“文本logging”,而不是“URIlogging”。 如果您手边有Android手机,则可以使用“NFC NFC TagWriter”等工具来编写正确的logging。 这对您的使用情况可能并不重要,但考虑与Android手机的互操作性, 其他应用。 他们会尝试打开“ https://www.hehello world”,而不是显示“Hello World”,使用EN编码作为文本string。