22

我刚刚在 iPhone 7 上安装了第一个 iOS 11 测试版,并且有兴趣尝试 NFC。设置里什么都没有。我想知道是否有任何示例代码显示如何读取标签。谁能在代码片段中展示如何使用 Core NFC SDK?

4

7 回答 7

37

在 Apple Developer 站点中,创建一个新的 App ID 并确保它NFC Tag Reading已启用。

开发门户功能

将以下行添加到您的 .plist 文件中:

<key>NFCReaderUsageDescription</key>
<string>NFC Tag!</string>

这些到权利文件:

<key>com.apple.developer.nfc.readersession.formats</key>
    <array>
        <string>NDEF</string>
    </array>

在相应的文件中它应该看起来像这样:

在此处输入图像描述

此外,可以通过 Xcode 中的 Capabilities 选项卡启用 Core NFC。

在此处输入图像描述

目标-c

进口CoreNFC

#import <CoreNFC/CoreNFC.h>

并设置委托:

@interface YourViewController : UIViewController <NFCNDEFReaderSessionDelegate>

在 viewDidLoad 中:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NFCNDEFReaderSession *session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT) invalidateAfterFirstRead:NO];
    [session beginSession];
}

在委托回调中:

- (void) readerSession:(nonnull NFCNDEFReaderSession *)session didDetectNDEFs:(nonnull NSArray<NFCNDEFMessage *> *)messages {

    for (NFCNDEFMessage *message in messages) {
        for (NFCNDEFPayload *payload in message.records) {
            NSLog(@"Payload data:%@",payload.payload);
        }
    }        
}

您还必须添加didInvalidateWithError委托回调,否则您将不符合协议:

- (void)readerSession:(nonnull NFCNDEFReaderSession *)session didInvalidateWithError:(nonnull NSError *)error {

}

您可以通过以下方式阻止读者:

[session invalidateSession];

斯威夫特 3/4

进口CoreNFC

import CoreNFC

并设置委托:

class YourViewController: UIViewController, NFCNDEFReaderSessionDelegate

在 viewDidLoad 中:

override func viewDidLoad() {
        super.viewDidLoad()

        let session = NFCNDEFReaderSession(delegate: self,
                      queue: DispatchQueue(label: "queueName", attributes: .concurrent), invalidateAfterFirstRead: false)  
        session?.begin()
    }

在委托回调中:

func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
  for message in messages {
    for record in message.records {
      print(record.payload)
    }
  }
}

您可以通过以下方式阻止读者:

session.invalidateSession

用法

启动视图后,您应该立即看到 iOS NFC 阅读器对话框,如下所示:

iOS NFC 阅读器对话框

出现此对话框后,您有大约一秒钟的时间将 iPhone 放在要读取的 NFC 标签附近。否则,该字段将被停用(这似乎是 Apple 的错误)。我经常需要取消并重试以获得一致的读数。更多细节在这里

于 2017-06-06T07:17:38.310 回答
5

要解决此问题,您可以将com.apple.developer.nfc.readersession.formats密钥添加到您的权利文件中。该键应与启用的 NFS 类型数组相关联。例如,您可以尝试以下操作:

<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>NDEF</string>
</array>

它对我有用。

于 2017-06-06T09:07:15.577 回答
4

更新了第二个 Xcode 测试版。

从开发者中心将 NFC 功能添加到您的应用程序。标识符-> 应用程序 ID -> 启用“NFC 标签读取”。

如果您的项目没有授权文件,让 Xcode 为您创建一个,只需激活然后停用 Xcode -> 项目目标 -> 功能中的任何功能。您将在项目导航器中找到一个新的 [AppName].entitlements 文件。右键单击该文件并选择“打开为 -> 源代码”。在 之间手动输入以下条目<dict></dict>

<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>NDEF</string>
</array>

一旦 Xcode 9 允许从 Capabilities 选项中启用 NFC 标签读取,这一步就过时了,因为您所要做的就是在那里启用它。当前(第一个)Beta 版本不支持此功能。

您还需要为 iOS 将向用户显示的隐私警告输入使用说明。(目前(beta 1)当设备准备好扫描时会显示此警告,并显示包含此消息的本机系统对话框。但是,这似乎是未开发的。)打开目标的 Info.plist 并开始输入“隐私”,您可以向下滚动到“隐私 - NFC 使用说明”,按回车键将其选中。在右栏中输入对您的用户有意义的解释。

现在你应该可以在 Swift 中导入 CoreNFC:

import CoreNFC

然后转到 Apple 的文档

重要提示:如果编译器返回错误并No such module 'CoreNFC'检查您是否选择了要构建的实际 iOS 11 设备,而不是模拟器。它还必须是 iPhone 7 或 7 plus。这可能会在未来的版本中发生变化,但测试 NFC 只能在实际硬件上完全工作。(cp。核心蓝牙,您可以在模拟器上运行但不测试实际功能。)Beta 2 不再有这个问题。但是,实际测试仍需要 iPhone 7/p 形式的实际硬件。

于 2017-06-07T16:40:31.777 回答
3

只是为了丰富以前的答案,重要的是要牢记这些特别针对NFCNDEFReaderSession班级的注意事项:

  • 用于处理 NFC 数据交换格式 (NDEF) 标签的读取器会话。此会话需要com.apple.developer.nfc.readersession.formats您的流程中的“ ”权利。此外,您的应用程序Info.plist必须包含一个非空的使用说明字符串。
  • NDEF 阅读器会话将自动扫描并检测包含有效 NDEF 消息的 NFC 论坛标签。 支持 NDEF 格式的 NFC 论坛标签类型 1 到 5。一个模态系统 UI 将出现一次-beginSession被调用以通知会话的开始;当会话被用户或调用-invalidateSession.
  • 已打开的会话在被调用后有60 秒的时限限制;达到时间限制时将返回错误。-beginSession-readerSession:didInvalidateWithError:NFCReaderSessionInvalidationErrorSessionTimeout
  • 系统中只允许 1 个活动的阅读器会话-readerSession:didInvalidateWithError:将在有活动的阅读器会话时NFCReaderSessionInvalidationErrorSystemIsBusy启动新的阅读器会话时返回-beginSession
  • -readerSession:didInvalidateWithError:NFCReaderSessionInvalidationErrorUserCanceled当用户单击 UI 上的完成按钮时将返回。
  • -readerSession:didInvalidateWithError:NFCReaderSessionInvalidationErrorSessionTerminatedUnexpectedly 在客户端应用程序进入后台状态时返回。 什么时候 -readerSession:didInvalidateWithError:回来NFCReaderErrorUnsupportedFeature
    1. 阅读器模式功能在硬件上不可用
    2. 客户端应用程序没有所需的权利。
于 2017-06-22T08:24:48.870 回答
1

您需要确保使用说明已经到位,并将功能添加到 Apple 开发人员中心内的应用程序中。我有一个基于我的经验的教程(基于 Swift 4)。可在此处获得:核心 NFC 教程

于 2017-06-06T16:06:56.273 回答
0

我使用这些答案中的资源将 Core NFC 添加到项目中。但是没有注意到的另一件事是,即使您通过权利手动添加功能,Xcode 似乎也不会查看文件,除非您打开了功能。这可能是由于 Xcode 9 Beta 1 没有将 Core NFC 作为许多人的示例项目的功能开关。因此,如果您仍然遇到问题,请务必打开至少一项其他功能!我看到一个意外的终止错误立即返回,直到我这样做。

我会将其保留为属于它的评论,但还没有足够的声誉来这样做。认为这很重要。

于 2017-06-16T15:49:53.133 回答
0

我的两分钱:

1)在xcode 9.0(beta 4 9M189t)下如果你已经添加了能力,不需要手动添加:

<key>com.apple.developer.nfc.readersession.formats</key>
    <array>
        <string>NDEF</string>
    </array>

它是自动完成的

2) 如果不使用 iPhone 7 或您在模拟器中,则不会崩溃:

您将被召唤:

func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        print(error.localizedDescription)
    }

它将显示:“不支持功能”

3)不要错过:

self.nfcSession?.begin() // will trigger callback

所以:

    final private func setup(){
    self.nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
    self.nfcSession?.alertMessage = "Put your NFC TAG over iPhone.."
    self.nfcSession?.begin() // will trigger callback

}

4)如果用户取消,您将获得:

“会话因用户取消而失效”

在 didInvalidateWithError 回调中。

于 2017-08-06T15:46:13.743 回答