SwiftUI學習100天(Day69 - 項目 14,第二部分)

原創(chuàng)鏈接:https://www.hackingwithswift.com/100/swiftui
以下內(nèi)容僅供學習參考:

在本項目技術(shù)概述的第二部分,我們將了解 iOS 上兩個非常重要的框架:用于在我們的應用程序中呈現(xiàn)地圖的 MapKit,以及用于使用 Touch ID 和 Face ID 的 LocalAuthentication。
知道位置、指紋和面部識別對用戶來說確實是個人的,你不會感到驚訝,這意味著我們需要始終尊重他們。請記住,用戶相信我們會始終以最大程度的謹慎和意圖來處理他們的數(shù)據(jù),因此讓我們認識到隱私、安全和信任是你的核心價值而不是可選的附加值是一件好事。
埃爾維斯·普雷斯利 (Elvis Presley) 曾說過:“價值觀就像指紋:每個人的價值觀都不相同,但你會在觸摸的所有事物上留下它們?!?好吧,這個項目位于價值和指紋維恩圖的中心,所以保持敏銳——這很重要。
今天你有兩個主題要完成,你將在其中學習如何將地圖嵌入到 SwiftUI 應用程序中,如何使用 Face ID 解鎖你的應用程序,等等。

將 MapKit 與 SwiftUI 集成
自從 2007 年首款設(shè)備問世以來,地圖一直是 iPhone 的核心功能,開發(fā)者可以使用底層框架的時間幾乎與 iPhone 一樣長。更好的是,Apple 提供了一個 SwiftUI?Map
視圖,它漂亮地包裝了底層地圖框架,讓我們可以將地圖、注釋等與我們的 SwiftUI 視圖層次結(jié)構(gòu)的其余部分放在一起。
讓我們從一些簡單的事情開始:顯示地圖意味著創(chuàng)建一些程序狀態(tài)來存儲地圖的當前中心坐標和縮放級別,這是通過稱為MKCoordinateRegion
.?該名稱中的“MK”表示它來自 Apple 的 MapKit 框架,因此我們的第一步是導入該框架:
現(xiàn)在我們可以創(chuàng)建一個這樣的屬性:
那以倫敦市為中心。兩組緯度和經(jīng)度均以度為單位,但實際上,當你遠離赤道時,經(jīng)度的基礎(chǔ)值會發(fā)生變化,因此可能需要進行一些實驗才能找到你喜歡的起始值。
最后,我們可以像這樣添加一個地圖視圖:
它具有與區(qū)域的雙向綁定,因此它可以隨著用戶在地圖上移動而更新,并且當應用程序運行時,你應該會在地圖上看到倫敦。
在創(chuàng)建地圖時,我們可以使用多種額外的選項,但到目前為止,最重要的是向地圖添加注釋的能力——代表我們選擇的不同地點的標記。
為此,根據(jù)你的目標至少需要三個步驟:定義包含你的位置的新數(shù)據(jù)類型,創(chuàng)建包含你所有位置的數(shù)據(jù)類型的數(shù)組,然后將它們作為注釋添加到地圖中。無論你創(chuàng)建什么新數(shù)據(jù)類型來存儲位置,它都必須符合Identifiable
協(xié)議,以便 SwiftUI 可以唯一地識別每個地圖標記。
例如,我們可以從這種Location
結(jié)構(gòu)開始:
現(xiàn)在我們可以繼續(xù)定義一個位置數(shù)組,無論我們希望地圖注釋出現(xiàn)在哪里:
第三步是重要的部分:我們可以將位置數(shù)組輸入Map
視圖,并提供將一個位置轉(zhuǎn)換為地圖上可見注釋的功能。SwiftUI 為我們提供了幾種不同的注釋類型,但最簡單的是MapMarker
:一個帶有緯度/經(jīng)度坐標的簡單氣球。
例如,我們可以像這樣在兩個位置放置標記:
當它運行時,你會在地圖上看到兩個紅色氣球,盡管它們沒有顯示任何有用的信息——例如,我們的位置的名稱不可見。要添加額外的信息,我們需要使用不同的注釋類型創(chuàng)建一個完全自定義的視圖,有用的只是稱為MapAnnotation
.?它接受與MapMarker
相同的坐標
,除了不只是顯示系統(tǒng)樣式的氣球,我們還可以傳入我們想要的任何自定義 SwiftUI 視圖。
所以,我們可以用這樣的描邊紅色圓圈替換氣球:
使用MapAnnotation
后,你可以傳入任何你想要的 SwiftUI 視圖——這是一個很好的自定義點,并且可以包含你想要的任何交互性。
例如,我們可以像這樣向我們的注釋添加點擊手勢:
我們甚至可以將 NavigationLink
放入我們的地圖注釋中,在點擊注釋時將用戶引導至不同的視圖:
關(guān)鍵是你可以決定是想要簡單的東西還是更高級的東西,然后使用你已經(jīng)知道的所有 SwiftUI 工具和技術(shù)添加任何交互性。



在 SwiftUI 中使用 Touch ID 和 Face ID
絕大多數(shù) Apple 設(shè)備都標配生物識別身份驗證,這意味著它們使用指紋和面部識別來解鎖。我們也可以使用此功能,這意味著我們可以確保只有在有效用戶解鎖時才能讀取敏感數(shù)據(jù)。
這是另一個 Objective-C API,但與 SwiftUI 一起使用時有點不愉快,這比我們目前使用過的其他一些框架要好。
在我們編寫任何代碼之前,你需要在你的項目選項中添加一個新密鑰,向用戶解釋你為什么要訪問 Face ID。由于只有 Apple 知道的原因,我們在代碼中傳遞了 Touch ID 請求原因,在項目選項中傳遞了 Face ID 請求原因。
因此,選擇你當前的目標,轉(zhuǎn)到“信息”選項卡,右鍵單擊現(xiàn)有鍵,然后選擇“添加行”。滾動密鑰列表,直到找到“Privacy - Face ID Usage Description”并為其賦值“(We need to unlock your data.)我們需要解鎖你的數(shù)據(jù)”。
現(xiàn)在回到 ContentView.swift,并在文件頂部附近添加此導入:
這樣,我們就可以編寫一些生物識別代碼了。
我之前提到過這“只是有點不愉快”,這就是它的用武之地:Swift 開發(fā)人員使用Error
協(xié)議來表示運行時發(fā)生的錯誤,但 Objective-C 使用一個名為NSError
.?我們需要能夠?qū)⑺鼈鬟f到函數(shù)中并在函數(shù)內(nèi)部更改它而不是返回一個新值——盡管這是 Objective-C 中的標準,但它在 Swift 中是一種非常陌生的工作方式所以我們需要標記它行為特別是通過使用&
.
我們將編寫一種authenticate()
方法,將所有生物識別功能隔離在一個地方。要做到這一點需要四個步驟:
創(chuàng)建
LAContext
的實例
,它允許我們查詢生物識別狀態(tài)并執(zhí)行身份驗證檢查。詢問上下文是否能夠執(zhí)行生物識別身份驗證——這很重要,因為 iPod touch 既沒有 Touch ID 也沒有 Face ID。
如果生物識別是可能的,那么我們開始實際的身份驗證請求,傳遞一個閉包以在身份驗證完成時運行。
當用戶通過或未通過身份驗證時,我們的完成閉包將被調(diào)用并告訴我們它是否有效,如果沒有,錯誤是什么。
請繼續(xù)并將此方法添加到ContentView
:
該方法本身不會執(zhí)行任何操作,因為它根本沒有連接到 SwiftUI。為了解決這個問題,我們需要添加一些我們可以在身份驗證成功時進行調(diào)整的狀態(tài),以及一個onAppear()
觸發(fā)身份驗證的修飾符。
因此,首先將此屬性添加到ContentView
:
這個簡單的布爾值將存儲應用程序是否顯示其受保護的數(shù)據(jù),因此我們將在身份驗證成功時將其翻轉(zhuǎn)為真。將// authenticated successfully
評論替換為:
最后,我們可以顯示當前身份驗證狀態(tài)并在body
屬性內(nèi)開始身份驗證過程,如下所示:
如果你運行該應用程序,你很可能只會看到“已鎖定”而沒有其他任何內(nèi)容。這是因為默認情況下模擬器沒有選擇生物識別,而且我們沒有提供任何錯誤消息,所以它會默默地失敗。
要試用面容 ID,請轉(zhuǎn)到“功能”菜單并選擇“面容 ID”>“已注冊”,然后再次啟動該應用程序。這次你應該會看到 Face ID 提示出現(xiàn),你可以通過返回“功能”菜單并選擇“Face ID”>“匹配面部”或“非匹配面部”來觸發(fā)成功或失敗的身份驗證。
一切順利,你應該會看到 Face ID 提示消失,在它下面將是“解鎖”文本視圖——我們的應用程序已檢測到身份驗證,現(xiàn)在可以使用了。
重要提示:在使用生物識別身份驗證時,你應該始終尋找一個備份計劃,讓用戶無需生物識別即可進行身份驗證。想一想那些現(xiàn)在可能戴著口罩或可能戴著手套的人——如果你試圖強迫他們一直使用生物識別技術(shù),你只會激怒用戶。因此,考慮添加一個提示輸入密碼的屏幕,然后在生物識別失敗時將其作為備用。


