我是 swift 的初学者。遵循在线教程后,我成功地向我的 API 服务发出了 POST 请求,但是,我现在希望将 LoginResponse
模型类的值返回到 SwiftUI View 结构,以便我可以更改状态变量的值。
模型类
// MARK: - LoginResponse
class LoginResponse: Codable {
let message, oauthToken, status: String
let userData: [UserDatum]
enum CodingKeys: String, CodingKey {
case message
case oauthToken = "oauth_token"
case status
case userData = "user_data"
}
init(message: String, oauthToken: String, status: String, userData: [UserDatum]) {
self.message = message
self.oauthToken = oauthToken
self.status = status
self.userData = userData
}
}
// MARK: - UserDatum
class UserDatum: Codable {
let emailAddress, firstName, lastName, phoneNumber: String
let userID: String
let userOnboardStage: Int
enum CodingKeys: String, CodingKey {
case emailAddress = "email_address"
case firstName = "first_name"
case lastName = "last_name"
case phoneNumber = "phone_number"
case userID = "user_id"
case userOnboardStage = "user_onboard_stage"
}
init(emailAddress: String, firstName: String, lastName: String, phoneNumber: String, userID: String, userOnboardStage: Int) {
self.emailAddress = emailAddress
self.firstName = firstName
self.lastName = lastName
self.phoneNumber = phoneNumber
self.userID = userID
self.userOnboardStage = userOnboardStage
}
}
网络服务类
enum APIError:Error{
case responseProblem
case decodingProblem
case encodingProblem
}
struct APIRequest {
let resourceURL: URL
let parameters: Dictionary<String, String>
init(endpoint: String, email: String, password: String){
let resourceString = "https://someurl/\(endpoint)"
guard let resourceURL = URL(string: resourceString) else {fatalError()}
self.resourceURL = resourceURL
var parameters = Dictionary<String, String>()
parameters = ["email_address":email,
"password":password,
"user_device_token":"",
"client_id":"",
"client_secret":""]
self.parameters = parameters
}
func save(_ loginResponseToSave:LoginResponse, completion: @escaping(Result<LoginResponse, APIError>) -> Void){
do {
var urlRequest = URLRequest(url : resourceURL)
urlRequest.httpMethod = "POST"
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = try JSONEncoder().encode(self.parameters)
let dataTask = URLSession.shared.dataTask(with: urlRequest){ data , response, _ in
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200, let jsonData = data else {
completion(.failure(.responseProblem))
return
}
do {
let loginData = try JSONDecoder().decode(LoginResponse.self, from: jsonData)
completion(.success(loginData))
}catch{
completion(.failure(.decodingProblem))
}
}
dataTask.resume()
}catch{
completion(.failure(.encodingProblem))
}
}
}
登录 Controller
class Login {
// This function is called from the view
func loginUser(email:String, password:String) -> Bool{
let loginRequest = LoginResponse(message: "", oauthToken: "", status: "", userData: [])
let postRequest = APIRequest(endpoint: "login_buyer", email: email, password: password)
postRequest.save(loginRequest, completion:{ result in
switch result{
case .success(let status):
print(status.status) < ---- I want to access this value outside of this scope
case .failure(let error):
print(error)
}
})
/// I want to return it here
return status.status <---- for example
}
}
我希望能够访问保存在 LoginResponse 模型中的值,但是当尝试访问它时,我得到了一个 nil
值??
最佳答案
当您调用您的 API 时,您正在执行一个异步请求,这将在后台运行并且该函数将在它完成之前返回,因此您需要像在其他地方一样使用完成处理程序......或者对数据返回并在范围内时。
您很可能只需像这样更新您的方法:
func loginUser(email:String, password:String, completion: (LoginResponse?) -> Void)
然后
switch result {
case .success(let loginResponse):
print(loginResponse)
completion(loginResponse)
case .failure(let error):
print(error)
completion(nil)
}
当您调用 loginUser 时:
loginUser(email: "email", password: "pwd") { response in
guard let loginResponse = response else { return }
// do something here with the response
}
关于json - POST 请求后在 swift 模型中访问值的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57111006/