既是记录也是分享!!!
关于NFC写入的那些东西。
这玩意儿在iOS实在太冷门了。
本文针对ISO14443标准的NFC Tag,其他芯片没测试
上代码 ==>
先搞个转换方法压压惊:
// 获得协议编码
+ (uint8_t)getProtocolCode:(NSString*)str {
if ([str isEqualToString:@"http://www."]) {
return 0x01;
} else if ([str isEqualToString:@"https://www."]) {
return 0x02;
} else if ([str isEqualToString:@"http://"]) {
return 0x03;
} else if ([str isEqualToString:@"https://"]) {
return 0x04;
} else if ([str isEqualToString:@"tel:"]) {
return 0x05;
} else if ([str isEqualToString:@"mailto:"]) {
return 0x06;
} else if ([str isEqualToString:@"ftp://anonymous:anonymous@"]) {
return 0x07;
} else if ([str isEqualToString:@"ftp://ftp."]) {
return 0x08;
} else if ([str isEqualToString:@"ftps://"]) {
return 0x09;
} else if ([str isEqualToString:@"sftp://"]) {
return 0x0A;
} else if ([str isEqualToString:@"smb://"]) {
return 0x0B;
} else if ([str isEqualToString:@"nfs://"]) {
return 0x0C;
} else if ([str isEqualToString:@"ftp://"]) {
return 0x0D;
} else if ([str isEqualToString:@"dav://"]) {
return 0x0E;
} else if ([str isEqualToString:@"news:"]) {
return 0x0F;
} else if ([str isEqualToString:@"telnet://"]) {
return 0x10;
} else if ([str isEqualToString:@"imap:"]) {
return 0x11;
} else if ([str isEqualToString:@"rtsp://"]) {
return 0x12;
} else if ([str isEqualToString:@"urn:"]) {
return 0x13;
} else if ([str isEqualToString:@"pop:"]) {
return 0x14;
} else if ([str isEqualToString:@"sip:"]) {
return 0x15;
} else if ([str isEqualToString:@"sips:"]) {
return 0x16;
} else if ([str isEqualToString:@"tftp:"]) {
return 0x17;
} else if ([str isEqualToString:@"btspp://"]) {
return 0x18;
} else if ([str isEqualToString:@"btl2cap://"]) {
return 0x19;
} else if ([str isEqualToString:@"btgoep://"]) {
return 0x1A;
} else if ([str isEqualToString:@"tcpobex://"]) {
return 0x1B;
} else if ([str isEqualToString:@"irdaobex://"]) {
return 0x1C;
} else if ([str isEqualToString:@"file://"]) {
return 0x1D;
} else if ([str isEqualToString:@"urn:epc:id:"]) {
return 0x1E;
} else if ([str isEqualToString:@"urn:epc:tag:"]) {
return 0x1F;
} else if ([str isEqualToString:@"urn:epc:pat:"]) {
return 0x20;
} else if ([str isEqualToString:@"urn:epc:raw:"]) {
return 0x21;
} else if ([str isEqualToString:@"urn:epc:"]) {
return 0x22;
} else if ([str isEqualToString:@"urn:nfc:"]) {
return 0x23;
} else {
return 0x00;
}
}
然后去创建消息对象:
// 生成消息内容
// 1
uint8_t byte = [HBNFCManager getProtocolCode:@"https://www."];
Byte bytes[] = {byte};
NSData *codeData = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
// 2
NSString *value = @"baidu.com";
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
// 1 + 2
NSMutableData *mData = [[NSMutableData alloc] init];
[mData appendData:codeData];
[mData appendData:valueData];
NSData *payloadData = [[NSData alloc] initWithData:mData];
// 生成消息类型
NSString *typeStr = @"U"; // U代表url T代表文本
NSData *typeData = [typeStr dataUsingEncoding:NSUTF8StringEncoding];
// 生成ID
NSString *identifierStr = @""; // 可写 可不写
NSData *identifierData = [identifierStr dataUsingEncoding:NSUTF8StringEncoding];
// 创建消息
NFCNDEFPayload *payload = [[NFCNDEFPayload alloc] initWithFormat:NFCTypeNameFormatNFCWellKnown type:typeData identifier:identifierData payload:payloadData];
// 最终生成
NFCNDEFMessage *message = [[NFCNDEFMessage alloc] initWithNDEFRecords:@[payload]];
最后,扫描 -> 写入:
[self.tagSession beginSession];
// 在这个方法里完成
- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags API_AVAILABLE(ios(13.0)) {}
加个文本消息添加:
// 生成消息内容
// 1
NSString *codeStr = @"\2"; // 固定就行 type必须是T 严谨一点就用 -> uint8_t byte = 0x02
NSData *codeData = [codeStr dataUsingEncoding:NSUTF8StringEncoding];
// 2
NSString *languageStr = @"en"; // en cn EN CN 都行 常用的固定 也可以通过代码判断
NSData *languageData = [languageStr dataUsingEncoding:NSUTF8StringEncoding];
// 3
NSString *value = @"This is a text";
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
// 1 + 2 + 3
NSMutableData *mData = [[NSMutableData alloc] init];
[mData appendData:codeData];
[mData appendData:languageData];
[mData appendData:valueData];
NSData *payloadData = [[NSData alloc] initWithData:mData];
// 生成消息类型
NSString *typeStr = @"T"; // U代表url T代表文本
NSData *typeData = [typeStr dataUsingEncoding:NSUTF8StringEncoding];
// 生成ID
NSString *identifierStr = @""; // 可写 可不写
NSData *identifierData = [identifierStr dataUsingEncoding:NSUTF8StringEncoding];
// 创建消息
NFCNDEFPayload *payload = [[NFCNDEFPayload alloc] initWithFormat:NFCTypeNameFormatNFCWellKnown type:typeData identifier:identifierData payload:payloadData];
// 最终生成
NFCNDEFMessage *message = [[NFCNDEFMessage alloc] initWithNDEFRecords:@[payload]];
排坑之路:
生成codeData时,一开始我用:
NSString *codeStr = @"\2"; // 0x02
NSData *codeData = [codeStr dataUsingEncoding:NSUTF8StringEncoding];
这里是好的 正常写入。
但是当使用:
NSString *codeStr = @"\1d"; // 0x1d
NSData *codeData = [codeStr dataUsingEncoding:NSUTF8StringEncoding];
输出后就会变成 http://www.dbaidu.com
如图所示:
看打印数据就明白了 length = 1 才是正确的写入,length = 2的那些,在真正写入时,只会读取0x31这个值 0x64就并入到payloadValue里了。
懂这些的大佬别笑我,以前接触这种数据太少,一开始也不懂,走了很多弯路。(尬笑~~)