VYNFCKit
VYNFCKit是一个用于解析近场通信(NFC)NDEF消息有效负载的iOS库。
NDEF(NFC数据交换格式)是由NFC论坛制定的标准数据格式规范,用于描述将一系列操作编码到NFC标签上,或由两个活动NFC设备之间交换的操作。绝大多数支持NFC的设备(读卡器、手机、平板电脑等)都支持从NFC标签读取NDEF消息。在iPhone 7和iPhone 7 plus以及iOS 11上,第三方应用可以读取NFC标签。使用Core NFC,您可以读取包含NFC数据交换格式(NDEF)数据的类型1至5的NFC标签。使用Core NFC,您可以读取包含NFC数据交换格式(NDEF)数据的类型1至5的NFC标签。一个NDEF消息包括头部和有效负载。Core NFC解析消息头部,但不解析消息有效负载。这个库VYNFCKit为您解析NFC NDEF消息有效负载。它支持Objective-c和Swift。
支持的负载类型
已知类型
- 使用UTF-8或UTF-16编码的文本,例如你好世界。
- 统一资源标识符(URI)具有36个方案,例如http://,https://,tel:,mailto:,ftp://,file://,例如https://example.com,tel:5551236666
- 智能海报。智能海报是一种NDEF消息的特殊类型,它是其他消息类型的包装器。VYNFCKit支持
媒体类型
- TextXVCard,包含联系人信息。
- Wi-Fi简单配置。
如何使用
在Xcode中打开您的项目设置,确保在“通用”/“签名”中已选择一个团队
。启用“功能”/“近场通信标签读取”。在Info.plist文件中,添加带有字符串值NFC Tag
的Privacy - NFC Scan Usage Description
。
您可以使用cocoapods
安装VYNFCKit
。将pod 'VYNFCKit'
添加到您的Podfile中,然后运行pod install
。使用Xcode 9打开YourProject.xcworkspace。
您也可以使用Carthage
安装VYNFCKit
。将github "vinceyuan/VYNFCKit" ~> VERSION_NUMBER_HERE
添加到您的Cartfile中,然后运行carthage update
。
Swift代码
在YourViewController.swift中,添加
import CoreNFC
import VYNFCKit
使YourViewController类遵循NFCNDEFReaderSessionDelegate
。
class YourViewController: UIViewController, NFCNDEFReaderSessionDelegate {
启动NFCNDEFReaderSession。
let session = NFCNDEFReaderSession(delegate: self, queue: DispatchQueue.main, invalidateAfterFirstRead: false)
session.begin()
实现回调并使用VYNFCKit解析NFCNDEFPayload。
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
for message in messages {
for payload in message.records {
guard let parsedPayload = VYNFCNDEFPayloadParser.parse(payload) else {
continue
}
var text = ""
var urlString = ""
if let parsedPayload = parsedPayload as? VYNFCNDEFTextPayload {
text = "[Text payload]\n"
text = String(format: "%@%@", text, parsedPayload.text)
} else if let parsedPayload = parsedPayload as? VYNFCNDEFURIPayload {
text = "[URI payload]\n"
text = String(format: "%@%@", text, parsedPayload.uriString)
urlString = parsedPayload.uriString
} else if let parsedPayload = parsedPayload as? VYNFCNDEFTextXVCardPayload {
text = "[TextXVCard payload]\n"
text = String(format: "%@%@", text, parsedPayload.text)
} else if let sp = parsedPayload as? VYNFCNDEFSmartPosterPayload {
text = "[SmartPoster payload]\n"
for textPayload in sp.payloadTexts {
if let textPayload = textPayload as? VYNFCNDEFTextPayload {
text = String(format: "%@%@\n", text, textPayload.text)
}
}
text = String(format: "%@%@", text, sp.payloadURI.uriString)
urlString = sp.payloadURI.uriString
} else if let wifi = parsedPayload as? VYNFCNDEFWifiSimpleConfigPayload {
for case let credential as VYNFCNDEFWifiSimpleConfigCredential in wifi.credentials {
text = String(format: "%@SSID: %@\nPassword: %@\nMac Address: %@\nAuth Type: %@\nEncrypt Type: %@",
text, credential.ssid, credential.networkKey, credential.macAddress,
VYNFCNDEFWifiSimpleConfigCredential.authTypeString(credential.authType),
VYNFCNDEFWifiSimpleConfigCredential.encryptTypeString(credential.encryptType)
)
}
if let version2 = wifi.version2 {
text = String(format: "%@\nVersion2: %@", text, version2.version)
}
} else {
text = "Parsed but unhandled payload type"
}
NSLog("%@", text)
}
}
}
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
NSLog("%@", error.localizedDescription)
}
参见Swfit示例:Examples/VYNFCKitExampleSwift。
通常,您只需要VYNFCNDEFPayloadParser.parse()
。如果您需要解析您自己的智能海报消息负载,请使用VYNFCNDEFPayloadParser.parseMessageHeader()
来解析消息头。
Objective-C代码
在YourViewController.m中,添加
#import <CoreNFC/CoreNFC.h>
#import <VYNFCKit/VYNFCKit.h>
使YourViewController类遵循NFCNDEFReaderSessionDelegate
。
@interface YourViewController() <NFCNDEFReaderSessionDelegate> {
}
启动NFCNDEFReaderSession。
NFCNDEFReaderSession *session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:dispatch_get_main_queue() invalidateAfterFirstRead:NO];
[session beginSession];
实现回调并使用VYNFCKit解析NFCNDEFPayload。
#pragma mark - NFCNDEFReaderSessionDelegate
- (void)readerSession:(nonnull NFCNDEFReaderSession *)session didDetectNDEFs:(nonnull NSArray<NFCNDEFMessage *> *)messages {
for (NFCNDEFMessage *message in messages) {
for (NFCNDEFPayload *payload in message.records) {
id parsedPayload = [VYNFCNDEFPayloadParser parse:payload];
if (parsedPayload) {
NSString *text = @"";
NSString *urlString = nil;
if ([parsedPayload isKindOfClass:[VYNFCNDEFTextPayload class]]) {
text = @"[Text payload]\n";
text = [NSString stringWithFormat:@"%@%@", text, ((VYNFCNDEFTextPayload *)parsedPayload).text];
} else if ([parsedPayload isKindOfClass:[VYNFCNDEFURIPayload class]]) {
text = @"[URI payload]\n";
text = [NSString stringWithFormat:@"%@%@", text, ((VYNFCNDEFURIPayload *)parsedPayload).URIString];
urlString = ((VYNFCNDEFURIPayload *)parsedPayload).URIString;
} else if ([parsedPayload isKindOfClass:[VYNFCNDEFTextXVCardPayload class]]) {
text = @"[TextXVCard payload]\n";
text = [NSString stringWithFormat:@"%@%@", text, ((VYNFCNDEFTextXVCardPayload *)parsedPayload).text];
} else if ([parsedPayload isKindOfClass:[VYNFCNDEFSmartPosterPayload class]]) {
text = @"[SmartPoster payload]\n";
VYNFCNDEFSmartPosterPayload *sp = parsedPayload;
for (VYNFCNDEFTextPayload *textPayload in sp.payloadTexts) {
text = [NSString stringWithFormat:@"%@%@\n", text, textPayload.text];
}
text = [NSString stringWithFormat:@"%@%@", text, sp.payloadURI.URIString];
urlString = sp.payloadURI.URIString;
} else if ([parsedPayload isKindOfClass:[VYNFCNDEFWifiSimpleConfigPayload class]]) {
text = @"[WifiSimpleConfig payload]\n";
VYNFCNDEFWifiSimpleConfigPayload *wifi = parsedPayload;
for (VYNFCNDEFWifiSimpleConfigCredential *credential in wifi.credentials) {
text = [NSString stringWithFormat:@"%@SSID: %@\nPassword: %@\nMac Address: %@\nAuth Type: %@\nEncrypt Type: %@",
text, credential.ssid, credential.networkKey, credential.macAddress,
[VYNFCNDEFWifiSimpleConfigCredential authTypeString:credential.authType],
[VYNFCNDEFWifiSimpleConfigCredential encryptTypeString:credential.encryptType]];
}
if (wifi.version2) {
text = [NSString stringWithFormat:@"%@\nVersion2: %@",
text, wifi.version2.version];
}
} else {
text = @"Parsed but unhandled payload type";
}
NSLog(@"%@", text);
}
}
}
}
- (void)readerSession:(nonnull NFCNDEFReaderSession *)session didInvalidateWithError:(nonnull NSError *)error {
NSLog(@"%@", error);
}
参见Objective-C示例:Examples/VYNFCKitExampleObjc。
通常,您只需要[VYNFCNDEFPayloadParser parse:]
。如果您需要解析您自己的智能海报消息负载,请使用[VYNFCNDEFPayloadParser parseMessageHeader:length:]
来解析消息头。
如何贡献
- 星标此项目。
- 请向我发送pull requests,这是受欢迎的。如果您做了某些修改,不要忘记更新并运行(在Xcode中command+U)Objective-C和Swift中的单元测试。请确保示例也运行良好。
参考文献
- 这篇博文 NFC P2P NDEF 基础 包含了大量关于NFC NDEF的细节。我从中学到了很多东西。代码中的有些注释也来自那里。多谢作者 Austin Blackstone。
- Wi-Fi简单配置技术规范版本2.0.5
- 在iOS 11上读取和解析NFC标签 由Vince Yuan撰写
许可
MIT许可证(MIT)
版权所有(c)2017 Aijin Yuan(又称Vince Yuan)
以下是对任何获得本软件及其相关文档文件(“软件”)副本的任何人授予免费、不可撤销、全球的、永久性的许可,可以在不受限制的情况下处理该软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向软件提供者提供的人这么做,前提是满足以下条件
以上版权声明和本许可声明应包含在所有软件副本或重大部分中。
软件按“现状”提供,不提供任何形式的保证,明示或暗示,包括但不限于适销性、针对特定目的的适用性和非侵权的保证。在任何情况下,作者或版权所有者不应对任何索赔、损害或其他责任负责,无论这些索赔是由于合同、侵权或其他方式引起的,并源自、涉及或与软件或其使用或其它交易有关。