| 版本號(hào) | 時(shí)間 |
|---|---|
| V1.0 | 2020.06.07 星期日 |
前言
今天翻閱蘋果的API文檔,發(fā)現(xiàn)多了一個(gè)框架Core NFC,看了下才看見是iOS11.0新添加的框架,這里我們就一起來看一下框架Core NFC。感興趣的看下面幾篇文章。
1. Core NFC框架詳細(xì)解析 (一) —— 基本概覽(一)
開始
首先看下主要內(nèi)容:
在本教程中,您將學(xué)習(xí)如何使用CoreNFC無線連接到其他設(shè)備或
NFC標(biāo)簽。內(nèi)容來自翻譯。
下面看下寫作環(huán)境:
Swift 5, iOS 13, Xcode 11
Near Field Communication(NFC)是一種用于短距離無線設(shè)備與其他設(shè)備共享數(shù)據(jù)或觸發(fā)這些設(shè)備上的動(dòng)作的技術(shù)。它使用射頻場(chǎng)(radio frequency field)進(jìn)行構(gòu)建,它可以使沒有電源的設(shè)備存儲(chǔ)小塊數(shù)據(jù),同時(shí)還使其他有源設(shè)備可以讀取該數(shù)據(jù)。
iOS和watchOS設(shè)備已經(jīng)內(nèi)置了NFC硬件已有幾年了。實(shí)際上,Apple Pay使用此技術(shù)與商店中的支付終端進(jìn)行交互。但是,開發(fā)人員要到iOS 11才能使用NFC硬件。
蘋果通過引入Core NFC提升了iOS 13中的NFC游戲。借助這項(xiàng)新技術(shù),您可以對(duì)iOS設(shè)備進(jìn)行編程,使其以新方式與周圍的互聯(lián)世界互動(dòng)。本教程將向您展示一些使用該技術(shù)的方法。在此過程中,您將學(xué)習(xí)如何:
- 將標(biāo)準(zhǔn)信息寫入
NFC tag標(biāo)簽。 - 閱讀該信息。
- 將自定義信息保存到標(biāo)簽
tag。 - 修改標(biāo)簽上已經(jīng)找到的數(shù)據(jù)。
重要說明:要執(zhí)行本教程中的所有步驟,您需要滿足以下條件:
- 物理iOS設(shè)備
- 蘋果開發(fā)者帳戶
- 您可以讀取和寫入的NFC硬件。許多在線零售商都以合理的價(jià)格攜帶
NFC tag。通常,您可以以大約10美元的價(jià)格獲得一包NFC標(biāo)簽。在說明中尋找表明它是可編程的或列出其存儲(chǔ)容量(通常為300至500字節(jié))的內(nèi)容。具有該近似容量的任何設(shè)備都超出了本教程的范圍。
在starter文件夾中打開starter項(xiàng)目。 使用項(xiàng)目應(yīng)用程序,您將學(xué)習(xí)如何:
- 將
NFC tag設(shè)置為“l(fā)ocation”。 - 掃描
location tag以查看其名稱和訪客日志。 - 將訪問者
(visitor)添加到位置標(biāo)簽(location tag)。
構(gòu)建并運(yùn)行。 您會(huì)看到以下內(nèi)容:

Writing to Your First Tag
首先,在Project navigator中選擇NeatoCache項(xiàng)目。 然后,轉(zhuǎn)到Signing & Capability,然后選擇+ Capability。 從列表中選擇Near Field Communication Tag Reading。

這將確保您的應(yīng)用程序的配置文件(provisioning profile)設(shè)置為使用NFC。
接下來,打開您的Info.plist并添加以下條目:
-
Key:
Privacy – NFC Scan Usage Description -
Value:使用
NFC讀取和寫入數(shù)據(jù)
您需要此條目來向用戶傳達(dá)您正在使用NFC功能的用途,并符合Apple關(guān)于在應(yīng)用程序中使用NFC的要求。
接下來,您將添加一個(gè)函數(shù),該函數(shù)可以執(zhí)行您的應(yīng)用將處理的各種NFC任務(wù)。 打開NFCUtility.swift并將以下導(dǎo)入和類型別名添加到文件頂部:
import CoreNFC
typealias NFCReadingCompletion = (Result<NFCNDEFMessage?, Error>) -> Void
typealias LocationReadingCompletion = (Result<Location, Error>) -> Void
您需要導(dǎo)入CoreNFC才能使用NFC。 類型別名(type aliases)提供以下功能:
- NFCReadingCompletion用于完成通用標(biāo)簽讀取任務(wù)。
- LocationReadingCompletion,用于讀取配置為位置的標(biāo)簽
接下來,將以下屬性和方法添加到NFCUtility:
// 1
private var session: NFCNDEFReaderSession?
private var completion: LocationReadingCompletion?
// 2
static func performAction(
_ action: NFCAction,
completion: LocationReadingCompletion? = nil
) {
// 3
guard NFCNDEFReaderSession.readingAvailable else {
completion?(.failure(NFCError.unavailable))
print("NFC is not available on this device")
return
}
shared.action = action
shared.completion = completion
// 4
shared.session = NFCNDEFReaderSession(
delegate: shared.self,
queue: nil,
invalidateAfterFirstRead: false)
// 5
shared.session?.alertMessage = action.alertMessage
// 6
shared.session?.begin()
}
如果您由于不符合NFCNDEFReaderSessionDelegate而此時(shí)遇到編譯錯(cuò)誤,請(qǐng)不要擔(dān)心,您將立即修復(fù)此問題。
這是您剛剛做的:
- 1) 您添加
session和completion屬性以存儲(chǔ)活動(dòng)的NFCreading session及其完成塊(completion block)。 - 2) 添加靜態(tài)函數(shù)作為NFC讀寫任務(wù)的入口點(diǎn)。通常,您將使用單例樣式訪問此函數(shù)和
NFCUtility。 - 3) 確保設(shè)備支持NFC讀取。否則,請(qǐng)返回
error的complete。 - 4) 創(chuàng)建一個(gè)
NFCNDEFReaderSession,它代表活動(dòng)的閱讀會(huì)話。您還可以設(shè)置代表以通知NFC閱讀會(huì)話的各種事件。 - 5) 您可以在會(huì)話上設(shè)置
alertMessage屬性,以使其在NFC模式下向用戶顯示該文本。 - 6) 開始閱讀會(huì)話。調(diào)用時(shí),模態(tài)將向用戶呈現(xiàn)您在上一步中設(shè)置的所有指令。
1. Understanding NDEF
請(qǐng)注意,上面的代碼引入了另一個(gè)首字母縮寫詞NDEF,代表NFC Data Exchange Format。這是用于寫入或讀取NFC設(shè)備的標(biāo)準(zhǔn)格式。您將使用兩種NDEF:
-
NDEF Record:其中包含您的有效載荷
(payload)值,例如字符串,URL或自定義數(shù)據(jù)。它還包含有關(guān)該有效負(fù)載值的信息,例如長度和類型。此信息是CoreNFC中的NFCNDEFPayload。 -
NDEF Message:這是保存
NDEF記錄的數(shù)據(jù)結(jié)構(gòu)。NDEF消息中可以有一個(gè)或多個(gè)NDEF記錄。
2. Detecting Tags
現(xiàn)在,您已經(jīng)設(shè)置了NFCReaderSession,現(xiàn)在遵循NFCUtility成為代理了,這樣就可以通知您在讀取會(huì)話期間發(fā)生的各種事件。
將以下代碼添加到NFCUtility.swift的底部:
// MARK: - NFC NDEF Reader Session Delegate
extension NFCUtility: NFCNDEFReaderSessionDelegate {
func readerSession(
_ session: NFCNDEFReaderSession,
didDetectNDEFs messages: [NFCNDEFMessage]
) {
// Not used
}
}
您將在一秒鐘內(nèi)向此擴(kuò)展添加更多內(nèi)容,但請(qǐng)注意,在本教程中,您將不會(huì)對(duì)readerSession(_:didDetectNDEFs :)進(jìn)行任何操作。 您僅在此處添加它,因?yàn)楸仨氉袷匚袇f(xié)議。
與NFC技術(shù)的互動(dòng)越多,您越會(huì)發(fā)現(xiàn)在讀寫過程的各個(gè)階段遇到錯(cuò)誤的可能性。 將以下方法添加到新擴(kuò)展中以捕獲這些錯(cuò)誤:
private func handleError(_ error: Error) {
session?.alertMessage = error.localizedDescription
session?.invalidate()
}
代碼的第一行應(yīng)該看起來很熟悉。 它將在NFC模式視圖中向用戶顯示錯(cuò)誤消息。 如果發(fā)生錯(cuò)誤,您還將使會(huì)話無效以終止會(huì)話并允許用戶再次與該應(yīng)用進(jìn)行交互。
接下來,將以下方法添加到擴(kuò)展中以處理NFC讀取會(huì)話中的錯(cuò)誤:
func readerSession(
_ session: NFCNDEFReaderSession,
didInvalidateWithError error: Error
) {
if let error = error as? NFCReaderError,
error.code != .readerSessionInvalidationErrorFirstNDEFTagRead &&
error.code != .readerSessionInvalidationErrorUserCanceled {
completion?(.failure(NFCError.invalidated(message:
error.localizedDescription)))
}
self.session = nil
completion = nil
}
添加此委托方法將清除到目前為止您遇到的所有編譯錯(cuò)誤。
最后,將最后一種方法添加到您的擴(kuò)展中,以處理可能的NFC標(biāo)簽檢測(cè):
func readerSession(
_ session: NFCNDEFReaderSession,
didDetect tags: [NFCNDEFTag]
) {
guard
let tag = tags.first,
tags.count == 1
else {
session.alertMessage = """
There are too many tags present. Remove all and then try again.
"""
DispatchQueue.global().asyncAfter(deadline: .now() + .milliseconds(500)) {
session.restartPolling()
}
return
}
}
在這里,您可以實(shí)現(xiàn)在會(huì)話檢測(cè)到您掃描標(biāo)簽時(shí)將調(diào)用的方法。
通常,您希望用戶只有一個(gè)標(biāo)簽離手機(jī)足夠近,但是您應(yīng)該考慮多個(gè)標(biāo)簽。 如果檢測(cè)到此情況,則將停止掃描并alert給用戶。 顯示該消息后,您將重新啟動(dòng)閱讀會(huì)話,并讓您的用戶再試一次。
3. Handling the Tag
知道有一個(gè)標(biāo)簽后,您可能想對(duì)它做些事情。 在readerSession(_:didDetect :)中的guard聲明之后添加以下代碼:
// 1
session.connect(to: tag) { error in
if let error = error {
self.handleError(error)
return
}
// 2
tag.queryNDEFStatus { status, _, error in
if let error = error {
self.handleError(error)
return
}
// 3
switch (status, self.action) {
case (.notSupported, _):
session.alertMessage = "Unsupported tag."
session.invalidate()
case (.readOnly, _):
session.alertMessage = "Unable to write to tag."
session.invalidate()
case (.readWrite, .setupLocation(let locationName)):
self.createLocation(name: locationName, with: tag)
case (.readWrite, .readLocation):
return
default:
return
}
}
}
您在上面的代碼中正在做的事情是:
- 1) 使用當(dāng)前的
NCFNDEFReaderSession連接到檢測(cè)到的標(biāo)簽。您需要執(zhí)行此步驟以執(zhí)行對(duì)標(biāo)簽的任何讀取或?qū)懭?。連接后,它將調(diào)用其完成處理程序,并可能發(fā)生任何錯(cuò)誤。 - 2) 在標(biāo)簽中查詢其
NDEF狀態(tài),以查看是否支持NFC設(shè)備。就您的NeatoCache應(yīng)用而言,狀態(tài)必須為readWrite。 - 3) 切換狀態(tài)和
NFC操作,并根據(jù)其值確定應(yīng)執(zhí)行的操作。在這里,您嘗試使用createLocation(name:with :)將標(biāo)簽設(shè)置為具有位置名稱,該名稱尚不存在,因此會(huì)遇到編譯錯(cuò)誤。不用擔(dān)心,您稍后會(huì)添加它。同樣,readLocation操作也尚未處理。
4. Creating the Payload
到目前為止,您已經(jīng)在尋找標(biāo)簽,連接標(biāo)簽并查詢其狀態(tài)。要完成對(duì)標(biāo)簽的寫入設(shè)置,請(qǐng)?jiān)?code>NFCUtility.swift的末尾添加以下代碼塊:
// MARK: - Utilities
extension NFCUtility {
func createLocation(name: String, with tag: NFCNDEFTag) {
// 1
guard let payload = NFCNDEFPayload
.wellKnownTypeTextPayload(string: name, locale: Locale.current)
else {
handleError(NFCError.invalidated(message: "Could not create payload"))
return
}
// 2
let message = NFCNDEFMessage(records: [payload])
// 3
tag.writeNDEF(message) { error in
if let error = error {
self.handleError(error)
return
}
self.session?.alertMessage = "Wrote location data."
self.session?.invalidate()
self.completion?(.success(Location(name: name)))
}
}
}
您在上面的代碼中正在做的事情是:
- 1) 創(chuàng)建文本
NFCNDEFPayload。如前所述,這類似于NDEF記錄。 - 2) 使用有效負(fù)載創(chuàng)建新的
NFCNDEFMessage,以便可以將其保存到NFC設(shè)備。 - 3) 最后,將消息寫入標(biāo)簽。
5. Using NDEF Payload Types
NFCNDEFPayload支持幾種不同類型的數(shù)據(jù)。在此示例中,您使用的是wellKnownTypeTextPayload(string:locale :)。這是一種非常簡單的數(shù)據(jù)類型,它使用字符串和設(shè)備的當(dāng)前語言環(huán)境。其他一些數(shù)據(jù)類型包含更復(fù)雜的信息。完整清單如下:
EmptyWell-KnownMIME media-typeAbsolute URIExternalUnknownUnchangedReserved
注意:本教程涵蓋了
Well-Known和Unknown。要了解其他類型,請(qǐng)查看本教程末尾列出的鏈接。另請(qǐng)注意,類型可以具有子類型。例如,
Well-known的具有Text和URI的子類型。
您真的很接近!剩下的就是將用戶界面連接到新代碼。轉(zhuǎn)到AdminView.swift并替換以下代碼:
Button(action: {
}) {
Text("Save Location…")
}
.disabled(locationName.isEmpty)
使用
Button(action: {
NFCUtility.performAction(.setupLocation(locationName: self.locationName)) { _ in
self.locationName = ""
}
}) {
Text("Save Location…")
}
.disabled(locationName.isEmpty)
這將進(jìn)行調(diào)用,以使用在text field中找到的文本來設(shè)置您的位置。
構(gòu)建并運(yùn)行,切換到應(yīng)用程序的Admin選項(xiàng)卡,輸入名稱并選擇Save Location…。
您會(huì)看到以下內(nèi)容:

注意:請(qǐng)記住,您需要使用物理設(shè)備并具有支持寫入功能的
NFC標(biāo)簽。
將手機(jī)放在NFC標(biāo)簽上后,您會(huì)看到一條消息,說明您的位置已成功保存。

6. Reading the Tag
很好! 現(xiàn)在,您已經(jīng)有了一個(gè)可以在標(biāo)簽中寫入字符串的應(yīng)用程序,您就可以為讀取標(biāo)簽提供支持。 返回NFCUtility.swift并在readerSession(_:didDetect :)中找到以下代碼。
case (.readWrite, .readLocation):
return
現(xiàn)在,替換它使用下面:
case (.readWrite, .readLocation):
self.readLocation(from: tag)
是時(shí)候?qū)崿F(xiàn)該readLocation(from :)方法了。 將以下內(nèi)容添加到包含createLocation(name:with :)的Utilities擴(kuò)展中:
func readLocation(from tag: NFCNDEFTag) {
// 1
tag.readNDEF { message, error in
if let error = error {
self.handleError(error)
return
}
// 2
guard
let message = message,
let location = Location(message: message)
else {
self.session?.alertMessage = "Could not read tag data."
self.session?.invalidate()
return
}
self.completion?(.success(location))
self.session?.alertMessage = "Read tag."
self.session?.invalidate()
}
}
您對(duì)添加的內(nèi)容應(yīng)該有點(diǎn)熟悉,因?yàn)樗c您寫入標(biāo)簽的方式非常相似。
- 1) 首先,您開始讀取標(biāo)簽。 如果可以讀取,它將返回找到的所有消息。
- 2) 接下來,如果有,嘗試從消息數(shù)據(jù)中創(chuàng)建一個(gè)
Location。 這使用了一個(gè)接受NFCNDEFMessage并將其命名的自定義初始化程序。 如果您感到好奇,可以在LocationModel.swift中找到該初始化程序。
最后,打開VisitorView.swift,并在scanSection中,替換以下代碼:
Button(action: {
}) {
Text("Scan Location Tag…")
}
使用下面
Button(action: {
NFCUtility.performAction(.readLocation) { location in
self.locationModel = try? location.get()
}
}) {
Text("Scan Location Tag…")
}
您已經(jīng)準(zhǔn)備好從標(biāo)簽中讀取數(shù)據(jù)。 構(gòu)建并運(yùn)行。
在Visitors選項(xiàng)卡上,點(diǎn)擊Scan Location Tag…。 您會(huì)在用戶界面中看到以下內(nèi)容以及您的位置名稱:

Writing Different Data Types
盡管在某些情況下寫字符串可能會(huì)完美地工作,但您可能會(huì)發(fā)現(xiàn)想要將其他類型的數(shù)據(jù)寫到標(biāo)簽中。
為此,請(qǐng)?jiān)?code>Utilities擴(kuò)展中的NFCUtility.swift中添加以下內(nèi)容:
private func read(
tag: NFCNDEFTag,
alertMessage: String = "Tag Read",
readCompletion: NFCReadingCompletion? = nil
) {
tag.readNDEF { message, error in
if let error = error {
self.handleError(error)
return
}
// 1
if let readCompletion = readCompletion,
let message = message {
readCompletion(.success(message))
} else if
let message = message,
let record = message.records.first,
let location = try? JSONDecoder()
.decode(Location.self, from: record.payload) {
// 2
self.completion?(.success(location))
self.session?.alertMessage = alertMessage
self.session?.invalidate()
} else {
self.session?.alertMessage = "Could not decode tag data."
self.session?.invalidate()
}
}
}
從現(xiàn)在開始,這種讀取標(biāo)簽的新方法將成為您大多數(shù)活動(dòng)的切入點(diǎn)。 如您所見,它仍然像以前一樣讀取標(biāo)簽。 但是,一旦讀取標(biāo)簽,它將執(zhí)行以下兩項(xiàng)操作之一:
- 1) 調(diào)用
completion handler并將消息傳遞給它。 這對(duì)于將多個(gè)NFC任務(wù)鏈接在一起非常有用。 - 2) 解碼有效負(fù)載
(payload),以便您可以解析標(biāo)簽的記錄。 您將稍后再講到這一點(diǎn)。
1. Writing Custom Data Instead of Strings
此時(shí),您已經(jīng)準(zhǔn)備好將應(yīng)用程序從編寫字符串到標(biāo)簽轉(zhuǎn)換為將自定義數(shù)據(jù)寫入標(biāo)簽。 將以下內(nèi)容添加到Utilities擴(kuò)展中:
private func createLocation(_ location: Location, tag: NFCNDEFTag) {
read(tag: tag) { _ in
self.updateLocation(location, tag: tag)
}
}
這是用于創(chuàng)建帶有位置標(biāo)簽的新函數(shù)。 您可以看到它使用新的read(tag:alsertMessage:readCompletion :)啟動(dòng)該過程,并調(diào)用了一個(gè)新函數(shù)來更新標(biāo)簽上的位置,還調(diào)用了一個(gè)新的暫時(shí)實(shí)施updateLocation(_:tag :)方法。
由于您要替換將位置信息寫入標(biāo)簽的方式,因此請(qǐng)刪除NFCUtility擴(kuò)展程序開頭的createLocation(name:with :),因?yàn)椴辉傩枰?另外,從以下代碼在readerSession(_:didDetect :)中更新代碼:
case (.readWrite, .setupLocation(let locationName)):
self.createLocation(name: locationName, with: tag)
到下面
case (.readWrite, .setupLocation(let locationName)):
self.createLocation(Location(name: locationName), tag: tag)
在createLocation(_:tag:)后面添加這個(gè)方法:
private func updateLocation(
_ location: Location,
withVisitor visitor: Visitor? = nil,
tag: NFCNDEFTag
) {
// 1
var alertMessage = "Successfully setup location."
var tempLocation = location
// 2
let jsonEncoder = JSONEncoder()
guard let customData = try? jsonEncoder.encode(tempLocation) else {
self.handleError(NFCError.invalidated(message: "Bad data"))
return
}
// 3
let payload = NFCNDEFPayload(
format: .unknown,
type: Data(),
identifier: Data(),
payload: customData)
// 4
let message = NFCNDEFMessage(records: [payload])
}
您在上面的代碼中正在做的事情是:
- 1) 創(chuàng)建默認(rèn)
alert消息和臨時(shí)位置。 稍后您將回到這些內(nèi)容。 - 2) 對(duì)傳遞給函數(shù)的
Location結(jié)構(gòu)進(jìn)行編碼。 這會(huì)將模型轉(zhuǎn)換為原始數(shù)據(jù)(Data)。 這很重要,因?yàn)檫@是將任何自定義類型寫入NFC標(biāo)簽的方式。 - 3) 創(chuàng)建可以處理數(shù)據(jù)的有效負(fù)載
(payload)。 但是,您現(xiàn)在使用unknown作為格式。 這樣做時(shí),必須將type和identifier設(shè)置為空數(shù)據(jù)Data,而有效負(fù)載(payload)參數(shù)將承載實(shí)際的解碼模型。 - 4) 將有效負(fù)載添加到新創(chuàng)建的消息中。
總體而言,這似乎與將字符串保存到標(biāo)簽中時(shí)沒什么不同,只是增加了一個(gè)步驟,將Swift數(shù)據(jù)類型轉(zhuǎn)換為標(biāo)簽可理解的內(nèi)容。
2. Checking Tag Capacity
要完成將數(shù)據(jù)寫入標(biāo)簽,請(qǐng)?jiān)?code>updateLocation(_:withVisitor:tag)中添加下一個(gè)代碼塊:
tag.queryNDEFStatus { _, capacity, _ in
// 1
guard message.length <= capacity else {
self.handleError(NFCError.invalidPayloadSize)
return
}
// 2
tag.writeNDEF(message) { error in
if let error = error {
self.handleError(error)
return
}
if self.completion != nil {
self.read(tag: tag, alertMessage: alertMessage)
}
}
}
上面的閉包嘗試查詢當(dāng)前NDEF狀態(tài),然后:
- 1) 確保設(shè)備有足夠的存儲(chǔ)空間來存儲(chǔ)位置。 請(qǐng)記住,與您可能熟悉的設(shè)備相比,NFC標(biāo)簽通常具有極其有限的存儲(chǔ)容量。
- 2) 將消息寫入標(biāo)簽。
與上面一樣,構(gòu)建并運(yùn)行并設(shè)置位置。 如果愿意,可以使用之前的相同標(biāo)簽,因?yàn)樾麓a將覆蓋以前保存的所有數(shù)據(jù)。
3. Reading Your Custom Data
此時(shí),如果您嘗試讀取標(biāo)簽,將會(huì)收到錯(cuò)誤消息。 保存的數(shù)據(jù)不再是眾所周知的類型。 要解決此問題,請(qǐng)?jiān)?code>readerSession(_:didDetect :)中替換以下代碼:
case (.readWrite, .readLocation):
self.readLocation(from: tag)
使用
case (.readWrite, .readLocation):
self.read(tag: tag)
構(gòu)建并運(yùn)行并掃描標(biāo)簽。 因?yàn)槟跊]有任何completion塊的情況下調(diào)用read(tag:alertMessage:readCompletion :),所以它將解碼消息的第一條記錄中找到的數(shù)據(jù)。
Modifying Content
此應(yīng)用程序的最后一項(xiàng)要求是保存訪問此位置的人員的日志。 您的應(yīng)用具有UI中已經(jīng)存在的未使用功能,該功能允許用戶輸入其名稱并將其添加到標(biāo)簽中。 到目前為止,您所做的工作將使其余的設(shè)置變得微不足道。 您已經(jīng)可以將數(shù)據(jù)讀取和寫入標(biāo)簽,因此對(duì)其進(jìn)行修改應(yīng)該很容易。
在創(chuàng)建tempLocation之后,在NFCUtility.swift中,將此代碼添加到updateLocation(_:withVisitor:tag :):
if let visitor = visitor {
tempLocation.visitors.append(visitor)
alertMessage = "Successfully added visitor."
}
在上面的代碼中,您檢查是否提供了visitor。 如果是這樣,則將其添加到該位置的Visitors數(shù)組中。
接下來,將以下方法添加到Utilities擴(kuò)展中:
private func addVisitor(_ visitor: Visitor, tag: NFCNDEFTag) {
read(tag: tag) { message in
guard
let message = try? message.get(),
let record = message.records.first,
let location = try? JSONDecoder()
.decode(Location.self, from: record.payload)
else {
return
}
self.updateLocation(location, withVisitor: visitor, tag: tag)
}
}
這個(gè)新方法將讀取一個(gè)標(biāo)簽,從中獲取消息,并嘗試對(duì)標(biāo)簽上的Location進(jìn)行解碼。
接下來,在readerSession(_:didDetect :)中,向switch語句添加新的case:
case (.readWrite, .addVisitor(let visitorName)):
self.addVisitor(Visitor(name: visitorName), tag: tag)
如果用戶明確想要添加visitor,則將調(diào)用在上一步中添加的函數(shù)。
剩下的就是更新VisitorView.swift。 在visitorSection中,替換以下代碼:
Button(action: {
}) {
Text("Add To Tag…")
}
.disabled(visitorName.isEmpty)
使用
Button(action: {
NFCUtility
.performAction(.addVisitor(visitorName: self.visitorName)) { location in
self.locationModel = try? location.get()
self.visitorName = ""
}
}) {
Text("Add To Tag…")
}
.disabled(visitorName.isEmpty)
Build并運(yùn)行,然后轉(zhuǎn)到Visitors選項(xiàng)卡。 輸入您的姓名,然后選擇Add To Tag…。 掃描后,您將看到更新的位置以及在標(biāo)記上找到的訪問者列表。

現(xiàn)在,您應(yīng)該熟悉Core NFC的基礎(chǔ)知識(shí)。 框架中還有很多事情沒有在本教程中提到。 例如,您可以添加標(biāo)簽的背景閱讀,這可以為用戶提供一種無需打開應(yīng)用即可與您的應(yīng)用進(jìn)行交互的方式。 如果您使用Apple的Shortcuts應(yīng)用程序來自動(dòng)化您的智能家居設(shè)備,這對(duì)您來說應(yīng)該很熟悉。 您可以在此處找到有關(guān)此操作的更多信息:Adding Support for Background Tag Reading。
要了解更多信息,請(qǐng)查看以下一些重要資源:
Apple's Core NFC Documentation是NFC規(guī)范中Apple支持的所有內(nèi)容的首選資源。
NFC Forum Homepage是放置有關(guān)NFC所需的所有一般信息及其定義的規(guī)范的地方。
后記
本篇主要講述了
CoreNFC使用簡單示例,感興趣的給個(gè)贊或者關(guān)注~~~
