iOS 11,遲來的 NFC

01-24

前言

NFC 這個詞已經並不陌生瞭,前一段時間北京地鐵支持 NFC 支付一時成為霸占頭條的熱點。其實在 90 年代末到 2000 年初,二維碼和 NFC 就已經相繼誕生,由於二維碼成本低廉,技術門檻相對較低,因此,二維碼迅速搶占瞭移動支付的市場,但 NFC 的發展並未因此停止。在 Android 端的 NFC 發展已經非常迅猛瞭,可惜 Apple 遲遲未開放接口,在今年的 WWDC 上,蘋果宣佈開放其 NFC 接口 CoreNFC, 這為以後 NFC 的應用提供瞭更多的可能。

正文

如果你對 NFC 這項技術還比較陌生,那麼這裡科普一下,NFC(Near Field Communication)近場通信,當兩個設備相互靠近時能進行信息交流。許多企業講 NFC 芯片放到卡片裡,用帶有 NFC 芯片的卡片來授予權限將允許誰有權限,比如說進出入公司。Apple CoreNFC 目前支持的格式有限,NFC 數據交換格式或 NDEF(通常用於當今市場上的大多數平板電腦和手機),比如 Apple Pay 。

CoreNFC Demo

這裡我們通過一個簡單的實例程序來演示怎麼使用 CoreNFC,這個程序可以用來讀取存儲在卡片上 NDEF 格式的信息。

為此,我使用 Arduino Uno 與 Adafruit PN532 Shield 配對,將其發送到樣品 NDEF 格式的卡上。 如果你不具備這些東西,或者根本不想在這樣的硬件上投入時間和金錢,請嘗試找一張帶有信息的預格式化卡。 本文中,我不會演示 NFC 格式化以及如何把數據存儲到 NDEF 卡 中。

Getting Started

打開 Xcode 9 創建一個簡單的 Swift 工程。使用 Storyboard 創建簡單的頁面:

ViewController 如下:

import UIKit class ViewController: UIViewController { @IBOutlet weak var messageLabel: UILabel! override func viewDidLoad ( ) { super.viewDidLoad ( ) // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning ( ) { super.didReceiveMemoryWarning ( ) // Dispose of any resources that can be recreated. } @IBAction func scanPressed ( _ sender: Any ) { // this is our newly created IBAction } }

Entitlements & Privacy

我們的 app 要使用 NFC 必須進行應用授權:前提是你得有一個有效 Apple id (交過保護費的 ) . 進行應用程序授權和隱私設置,打開 developer.apple.com。 登錄你的帳戶,創建一個證書 —— 註冊一個新的 APP ID。應用說明應該要支持 NFC 點擊下一步,確保你的確認頁面如下圖:

然後再創建 provisioning profile :

這一步完成瞭,在我們剛創建的項目中導入 證書和描述文件,完成之後呢,我們還需進行 Info.plist 配置 Privacy:

至此,我們的開始工作就完成瞭。我們進入 coding 階段。

Core NFC

要實現 NFC 功能,我們得接入 Core NFC framework:

import CoreNFC

目前為止,iOS 模擬器尚未支持 CoreNFC。 這意味著如你嘗試導入 CoreNFC,會收到一條錯誤,表示沒有名為 CoreNFC 的模塊。 遇到這種情況,請選擇你的 iPhone 或 Generic iOS Device。接下來我們實現 NFCNDEFReaderSessionDelegate 協議:

import UIKitimport CoreNFC class ViewController: UIViewController, NFCNDEFReaderSessionDelegate { @IBOutlet weak var messageLabel: UILabel! var nfcSession: NFCNDEFReaderSession? override func viewDidLoad ( ) { super.viewDidLoad ( ) // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning ( ) { super.didReceiveMemoryWarning ( ) // Dispose of any resources that can be recreated. } @IBAction func scanPressed ( _ sender: Any ) { } func readerSession ( _ session: NFCNDEFReaderSession, didInvalidateWithError error: Error ) { print ( "The session was invalidated: ( error.localizedDescription ) " ) } func readerSession ( _ session: NFCNDEFReaderSession, didDetectNDEFs messages: [ NFCNDEFMessage ] ) { // Parse the card's information }}

其中兩個 readerSession 函數會分別告訴我們 NFC 會話成功或失敗,成功後則返回 NFCNDEFMessage 格式的通信數據,失敗後會返回 error 信息。

當然,我們首先還需要初始化 NFCNDEFReaderSession 並開啟 NFC 監聽。

@IBAction func scanPressed ( _ sender: Any ) { nfcSession = NFCNDEFReaderSession.init ( delegate: self, queue: nil, invalidateAfterFirstRead: true ) nfcSession?.begin ( ) }

然後運行程序,看看:

如果提示 Session is invalidated unexpectedly ,那麼請仔細核對 證書、描述文件以及 Privacy 設置是否正確。

這個過程並不難,簡單幾步就能搞定,下面我們來看看怎麼解析獲取到的 message 。

解析 Message

首先,讓我們來看一下這個函數:

func readerSession ( _ session: NFCNDEFReaderSession, didDetectNDEFs messages: [ NFCNDEFMessage ] )

讓我們來看看每一個 message 對象包含瞭哪些信息:

print ( messages [ 0 ] )

我們可以看到:

( // Payload one ( There's only one payload in this card ) "TNF=1, /* Type Name Format */ Payload Type=, Payload ID=, Payload=" /* What we're really interested in */ )

根據打印的結果我們可以看出:

. messages 是一個 NFCNDEFMessages 對象的數組。

. NFCNDEFMessage 有一個 NFCNDEFPayload 對象數組 records

然後我們再來看看每一個 payload 又包含瞭哪些信息:

identifier.

type.

typeNameFormat.

payload.

這裡其實我們隻關心 payload 。好瞭,看看如何解析 records 吧。

func readerSession ( _ session: NFCNDEFReaderSession, didDetectNDEFs messages: [ NFCNDEFMessage ] ) { var result = "" for payload in messages [ 0 ] .records { result += String.init ( data: payload.payload.advanced ( by: 3 ) , encoding: .utf8 ) ! // 1 } DispatchQueue.main.async { self.messageLabel.text = result }}

來看看最終的效果:

參考

Working with CoreNFC in iOS 11

作者:CNKCQ

鏈接:https://juejin.im/post/5a30c00e518825296421ad99

精彩圖片
文章評論 相關閱讀
© 2016 看看新聞 http://www.kankannews.cc/