首页 > 解决方案 > 如何在 SwiftUI case.success 上保存两个值

问题描述

我正在 SwiftUI 中执行 API 调用以登录我的用户并获取令牌。

如果成功,我需要保存令牌和客户端值以供其他未来调用。

我不确定如何在 case.success 函数中将两个单独的值保存到用户默认值。当我也尝试保存客户端信息时,我遇到了元组错误。如果我只是想捕获令牌,则此登录功能可以正常工作。

我不想将这些值保存到模型中,因为我认为这不是安全的最佳做法。

成功执行此登录功能后,如何将令牌和客户端都设置为用户默认值?

这是我的网络电话:

import Foundation
import SwiftUI

enum AuthenticationError: Error {
case invalidCredentials
case custom(errorMessage: String)
}

struct LoginRequestBody: Codable {
let email: String
let password: String
}

struct LoginResponse: Decodable {
let data: LoginValue?
let success: Bool?
let client: String?
}

struct LoginValue: Decodable {
let message: String?
let user: UserRole?
let success: Bool?
}

struct UserRole: Decodable {
let role: String?
}

class Sessionservice {
    
func login(email: String, password: String, completion: @escaping (Result<String, AuthenticationError>) -> Void){        

    guard let url = URL(string: "https://example.com/api/v1/auth/sign_in") else {
        completion(.failure(.custom(errorMessage:"Site is unavailable.  Try again later.")))
        return
    }
    
    let body = LoginRequestBody(email: email, password: password)
    
    
    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: "Accesstoken") else {
                        completion(.failure(.custom(errorMessage: "Missing Access Token")))
                        return
                    }
                    guard let client = response.value(forHTTPHeaderField: "client") else {
                        completion(.failure(.custom(errorMessage: "Missing Client")))
                        return
                    }
                    completion(.success(token))
                    completion(.success(client))
                }
                
                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}
                completion(.success(message))
                completion(.success(role))
               
            }.resume()
}
}

这是我的模型:

import Foundation

class LoginViewModel: ObservableObject {

var email: String = ""
var password: String = ""
@Published var isAuthenticated: Bool = false
@Published var authenticationDidFail: Bool = false
@Published var loginButtonClicked: Bool = false

func login() {
    
    let defaults = UserDefaults.standard
    
    self.loginButtonClicked = true
    
    Sessionservice().login(email: email, password: password) { result in
        switch result {
        case.success(let token, let client):
                defaults.setValue(token, forKey: "Accesstoken")
                defaults.setValue(self.email, forKey: "userEmail")
                defaults.setValue(client, forKey: "client")
                DispatchQueue.main.async {
                    self.isAuthenticated = true
                    self.authenticationDidFail = false
                    self.loginButtonClicked = false
                }
            case.failure(let error):
                DispatchQueue.main.async {
                    self.authenticationDidFail = true
                    self.isAuthenticated = false
                    self.loginButtonClicked = false
                }
        }
    }
}

func fetchProjects() {
    print("Fetching Projects")
}
}

标签: swiftswiftui

解决方案


推荐阅读