【问题标题】:iOS 11 Core NFC - any sample code?iOS 11 Core NFC - 任何示例代码?
【发布时间】:2017-11-06 21:32:43
【问题描述】:

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

【问题讨论】:

  • 我试过了,但总是返回 NFCReaderSessionInvalidationErrorSessionTerminatedUnexpectedly。
  • 在下面接受的答案中遵循鲍里斯的建议。确保您的 info.plist 和权利设置正确。
  • Apple 开发者网站上的 WWDC 视频中提供了良好的背景信息。它回答了大部分提出的问题:developer.apple.com/videos/play/wwdc2017/718
  • 这是我制作的,您仍然需要一个 Apple Dev 帐户并设置您的 App ID 以使其工作:github.com/x43x61x69/Core-NFC-Example

标签: ios nfc beta core-nfc


【解决方案1】:

在 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>

在相应的文件中应该是这样的:

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

目标-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 阅读器对话框,如下所示:

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

【讨论】:

  • 你成功了吗?我尝试它总是返回 NFCReaderSessionInvalidationErrorSessionTerminatedUnexpected‌​ly。
  • 用所需的 .plist 文件条目更新了答案
  • 鲍里斯——你太棒了!我能够让它工作。它只工作几分钟,然后提示消失,我必须重新启动应用程序。但至少这是一个开始。
  • NDEF 的第一个字节是 TNF(类型名称格式)字段。 ^C 是 URI 类型的 0x03。与 Android 不同,iOS 似乎没有自动为您确定 NDEF 记录类型的操作系统级解析器。你必须自己解析它,至少现在是这样。
  • 根据会话视频,会话在 60 秒后过期。您每次都需要停止并重新启动它们,或者构建一些方法来停止和重新启动。
【解决方案2】:

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

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

它对我有用。

【讨论】:

  • 谢谢!我不再遇到Error202。但现在该应用程序因CoreNFC__CRASHING_DUE_TO_PRIVACY_VIOLATION__ 而崩溃。您的 info.plist 中有使用说明吗?
  • 是的,我有描述。
  • 描述键。 NFCReaderUsageDescription
  • @Max 谢谢!我一直在寻找它,但文档太短了!你在哪里找到它?再次感谢
  • 完成了所有步骤(谢谢!)但是当我返回到 Capabilities 下进行验证时,我只看到了 2 个步骤 - 而不是将 NFC 添加到 info.plist 文件的第 3 个步骤。它在里面。在哪里重要吗?第二个问题:所以这意味着您只能在可以访问互联网的情况下创建新的 NFC 应用(因为您必须在开发者网站中注册应用并打开 NFC)?
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    更新了第二个 Xcode 测试版。

    从开发者中心为您的应用添加 NFC 功能。 Identifiers -> App IDs -> 启用“NFC 标签读取”。

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

    <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 的 documentation

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

    【讨论】:

    • 关于“没有这样的模块”错误的好注释。您也可以在编译时仅使用 Generic Device 选项绕过。你可以在任何东西上运行它,但至少可以让你编译一些东西以确保它可以工作。
    【解决方案5】:

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

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

    【讨论】:

      【解决方案6】:

      为了丰富以前的答案,请务必牢记这些注意事项,特别是 NFCNDEFReaderSession 类:

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

      【讨论】:

      • 我在 -readerSession:didInvalidateWithError 中不断收到“不支持功能”错误:是因为我在 iPhone SE 上进行测试吗?但 SE 有 NFC AFAIK
      • @jaytrixz 是的,目前仅在 iPhone 7 和 iPhone 7 Plus 上支持读取 NFC NDEF 标签。
      【解决方案7】:

      我的两分钱:

      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 回调中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 2020-11-22
        • 2016-04-11
        • 2010-10-10
        • 1970-01-01
        • 1970-01-01
        • 2014-06-14
        相关资源
        最近更新 更多