教程章节
在本教程的前一部分中,你创建了一个基于SwiftUI的iOS应用,该应用使用Auth0实现基本的登录和注销功能。在这一部分中,你将增强你的应用程序,让它能够读取用户的个人资料,在用户登录时显示其照片、姓名和电子邮件地址。
显示用户的资料信息
应用程序只 "知道 "用户在其当前状态下是登录还是注销。它还拥有关于用户身份的信息,这些信息在ID令牌中被编码。让我们提取这些用户信息--用户资料--并在用户登录时使用它来显示用户的姓名、电子邮件地址和图片。
当你完成这一部分后,应用程序的 "登录 "屏幕将看起来像这样。
为用户资料创建一个数据结构
在我们从ID令牌中提取用户的资料信息之前,我们需要建立一个数据结构来存储它。让我们为此目的创建一个struct
。
🛠 右键单击(或控制单击)项目资源管理器中的SwiftUI 登录演示文件夹,选择 "新文件",为struct
创建一个新的 Swift 文件...。
🛠 在出现的窗口中,确保选择iOS标签。选择Swift文件,然后点击下一步。
🛠 命名该文件 Profile.swift
并单击"创建"来创建文件。
现在有了一个Profile
struct
,让我们每次一点点地实现它。
🛠用以下内容替换Profile
的内容。
// 1
import JWTDecode
// 2
struct Profile {
let id: String
let name: String
let email: String
let emailVerified: String
let picture: String
let updatedAt: String
}
下面是对上面代码中的编号注释的解释。
-
ID令牌的格式是JWT,即JSON Web令牌。
JWTDecode
库允许你对令牌进行解码,以提取其包含的用户资料信息。 -
这段代码定义了
Profile
,这个struct
,它将解码并存储ID令牌中的用户资料信息。它有以下属性,所有这些都是字符串。id
:用户的唯一标识符name
:用户的全名email
:用户的电子邮件地址emailVerified
:true
如果用户向Auth0验证了他们的电子邮件地址。false
否则picture
:用户图片的URLupdatedAt
:用户资料最后更新的日期和时间
🛠 在Profile
的定义后添加以下内容。
extension Profile {
}
我们再一次使用extension
,将一个struct
分成更小的部分,以便于阅读和更新。这个扩展将包含方法和类似方法的变量。
🛠在新创建的extension
内添加以下变量声明。
static var empty: Self {
return Profile(
id: "",
name: "",
email: "",
emailVerified: "",
picture: "",
updatedAt: ""
)
}
这定义了empty
,一个静态变量,它的作用更像一个函数。它创建了一个新的Profile
实例,其属性都被设置为空字符串。
🛠 在empty
的声明之后,立即将此函数添加到extension
。
static func from(_ idToken: String) -> Self {
guard
let jwt = try? decode(jwt: idToken),
let id = jwt.subject,
let name = jwt.claim(name: "name").string,
let email = jwt.claim(name: "email").string,
let emailVerified = jwt.claim(name: "email_verified").boolean,
let picture = jwt.claim(name: "picture").string,
let updatedAt = jwt.claim(name: "updated_at").string
else {
return .empty
}
return Profile(
id: id,
name: name,
email: email,
emailVerified: String(describing: emailVerified),
picture: picture,
updatedAt: updatedAt
)
}
给出一个ID令牌字符串,该 from()
函数创建一个Profile
实例。如果 from()
能够从ID令牌中提取声称--关于用户身份的值,包括他们的名字、电子邮件地址和他们的照片的URL--它返回一个Profile
实例,其属性中包含这些信息。否则,它将返回一个空属性的Profile
实例。
更新用户界面
现在有了一种从ID标记中提取信息的方法,让我们把它用起来。在这一步,我们将对用户界面进行修改,使其能够显示登录用户的姓名、电子邮件地址和照片。
🛠 打开ContentView
,在isAuthenticated
,紧接着添加一个新属性。注意注释中告诉你要添加新代码的地方。
@State private var isAuthenticated = false
// 👇🏽👇🏽👇🏽 New line of code here!
@State var userProfile = Profile.empty
// 👆🏽👆🏽👆🏽
这就创建了userProfile
,这是一个Profile
的实例,当用户登录时,它将包含有关用户的信息。应用程序将使用其属性来显示用户的姓名、电子邮件地址和照片。
由于userProfile
是用@State
属性标记的,它定义了用户界面的状态。每当userProfile
或它的一个属性发生变化时,应用程序就会重新绘制用户界面以反映这一变化。
🛠 在body
属性中添加用户界面元素,以显示用户的信息。再一次,注释会告诉你在哪里添加新代码。
var body: some View {
if isAuthenticated {
// 3
VStack {
// 4
Text("Logged in")
.padding()
// 👇🏽👇🏽👇🏽 New lines of code here!
AsyncImage(url: URL(string: userProfile.picture)) { image in
image
.frame(maxWidth: 128)
} placeholder: {
Image(systemName: "photo.circle.fill")
.resizable()
.scaledToFit()
.frame(maxWidth: 128)
.foregroundColor(.gray)
.opacity(0.5)
}
.padding(40)
VStack {
Text("Name: \(userProfile.name)")
Text("Email: \(userProfile.email)")
}
.padding()
// 👆🏽👆🏽👆🏽
// 5
Button("Log out") {
logout()
}
.padding()
}
} else {
// The rest of the “body” property goes here...
新的代码在ContentView
中添加了两个新的视图。
- 一个
AsyncImage
,这个视图将异步下载用户的图片,并在下载完成后显示。它使用placeholder
选项,在下载用户图片的同时显示iOS内置图标集的相机图标。 - 一个
VStack
包含两个Text
视图:一个显示用户的姓名,一个显示用户的电子邮件地址。
🛠 滚动到定义了ContentView
方法的extension
,并更新 login()
来从ID标记中提取用户的资料信息。下面代码中的注释将告诉你在哪里添加新行。
func login() {
Auth0 // 1
.webAuth() // 2
.start { result in // 3
switch result {
// 4
case .failure(let error):
print("Failed with: \(error)")
// 5
case .success(let credentials):
self.isAuthenticated = true
// 👇🏽👇🏽👇🏽 New line of code here!
self.userProfile = Profile.from(credentials.idToken)
// 👆🏽👆🏽👆🏽
print("Credentials: \(credentials)")
print("ID token: \(credentials.idToken)")
}
}
}
新添加的这行代码在用户登录和应用程序收到ID令牌后运行。它从ID令牌中的数据创建一个新的Profile
实例,并将ContentView
'suserProfile
属性设置为该实例。
运行应用程序
运行应用程序,并确认所做的更改是否有效。当你登录时,你应该看到用户的姓名、电子邮件地址和照片。
接下来的步骤
在这个练习中,你已经覆盖了很多地方。你不仅使用SwiftUI框架建立了一个iOS应用程序,而且还让它具有用Auth0验证用户的能力。
你可以在Auth0博客样本GitHub账户的get-started-ios-authentication-swiftui仓库中下载一个完整的项目。
SwiftUI是一个广泛的话题,我们在本教程中只触及了它的表面。对于你下一步的探索,你可能想看看这些有用的资源。
这是关于使用Auth0进行iOS开发的新系列文章中的第二篇。未来的文章将深入探讨iOS和Auth0的认证和授权,以及标准用户名和密码的替代方法。请关注这个空间。