【发布时间】:2023-04-09 20:10:02
【问题描述】:
我正在构建一个与 API 交互的 SwiftUI 应用。用户通过访问我的 Rails 服务器的注册表单创建一个帐户。可以正常工作,但我不知道如何显示来自服务器的错误消息。
例如,注册表单中的电子邮件地址和用户名需要是唯一的,并且与现有用户的不匹配。这可能是一个罕见的问题,但服务器实际上返回了一条 422 消息,表明用户创建失败,因为用户名或电子邮件或两者都已存在。
如何显示这些特定错误而不是典型的通用 URLSession 枚举错误?
另外,有没有办法在注册功能运行之前检查用户名和电子邮件地址是否已经存在,因为这是设置它的理想方式。它在网页版上就是这样工作的。
这是尝试失败后来自服务器的错误 JSON:
{
"status": "error",
"data": {
"id": null,
"email": "sampleuser3@example.com",
"created_at": null,
"updated_at": null,
"username": "SampleUser3"
},
"errors": {
"email": [
"has already been taken"
],
"username": [
"has already been taken"
],
"full_messages": [
"Email has already been taken",
"Username has already been taken"
]
}
}
这是我发出注册请求的注册服务:
import Foundation
struct SignUpRequestBody: Codable {
let email: String
let username: String
let firstName: String
let lastName: String
let phoneNumber: String
let password: String
let passwordConfirmation: String
let category: String
}
final class SignUpService {
static let shared = SignUpService()
func signUp(email: String, username: String, firstName: String, lastName: String, phoneNumber: String, password: String, passwordConfirmation: String, category: String, completed: @escaping (Result<SessionToken, AuthenticationError>) -> Void) {
guard let url = URL(string: "https://example.com/auth") else {
completed(.failure(.custom(errorMessage:"URL unavailable")))
return
}
let body = SignUpRequestBody(email: email.lowercased(), username: username, firstName: firstName, lastName: lastName, phoneNumber: phoneNumber, password: password, passwordConfirmation: passwordConfirmation, category: "consumer")
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONEncoder().encode(body)
URLSession.shared.dataTask(with: request) { (data, response, error) in
if let response = response as? HTTPURLResponse {
guard let token = response.value(forHTTPHeaderField: "access-token") else {
completed(.failure(.custom(errorMessage: "Missing Access Token")))
return
}
guard let client = response.value(forHTTPHeaderField: "client") else {
completed(.failure(.custom(errorMessage: "Missing Client")))
return
}
guard let data = data, error == nil else { return }
guard let loginResponse = try? JSONDecoder().decode(LoginResponse.self, from: data) else { return }
guard let messageData = loginResponse.data else {return}
guard let message = messageData.message else {return}
guard let userRole = messageData.user else {return}
guard let role = userRole.role else {return}
let sessionToken = SessionToken(accessToken: token, client: client, message: message, role: role)
completed(.success(sessionToken))
}
}.resume()
}
}
【问题讨论】:
-
如何将此代码与 SwiftUI 集成?你如何显示
Alert。 -
@loremipsum 目前我还没有设置警报。我有一个带有警报的枚举: enum AuthenticationError: Error { case invalidCredentials case custom(errorMessage: String) } 但我还没有将它们设置到视图中。
标签: json swift swiftui httpresponse urlsession