iOS OC 新技能Get之NFC

既是记录也是分享!!!

关于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里了。

懂这些的大佬别笑我,以前接触这种数据太少,一开始也不懂,走了很多弯路。(尬笑~~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值