【问题标题】:How to Get Response from URLSession in SwiftUI如何在 SwiftUI 中从 URLSession 获取响应
【发布时间】:2021-07-30 07:14:17
【问题描述】:

我正在尝试在 SwiftUI 中构建一个 URLSession 来处理基于 API 令牌的身份验证以登录到 Web 应用程序。

我能够让 API 在 Postman 中正常工作,但无法在 SwiftUI 中获得任何类型的可读响应。我是 SwiftUI 和调试的新手。从处理授权的 Web 服务器日志来看,我的 Swift 代码的登录请求似乎是成功的,但我似乎无法解析出正文或标头。

我的画布中不断收到“LoginResponse(message: nil)”。

这是我的 SwiftUI 代码简化为仅尝试打印 URLSession 响应。

import Foundation

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

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

struct LoginResponse: Codable {
    let message: String?
}

class Sessionservice {
    
    func login(emailAddress: String, password: String, completion: @escaping (Result<String, AuthenticationError>) -> Void){
        
        guard let url = URL(string: "https://www.example.com/api/v1/auth/sign_in") else {
            completion(.failure(.custom(errorMessage:"Site is unavailable.  Try again later.")))
            return
        }
        
        let body = LoginRequestBody(email: "email@example.com", 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
                    
                    guard let data = data, error == nil else {
                        completion(.failure(.custom(errorMessage: "No data")))
                        return
                    }
                    
                    try! JSONDecoder().decode(LoginResponse.self, from: data)

                    guard let loginResponse = try? JSONDecoder().decode(LoginResponse.self, from: data) else {
                        completion(.failure(.custom(errorMessage: "loginResponse Failure")))
                        return
                    }
                    print(loginResponse)
                }.resume()
    }
}

【问题讨论】:

  • 不要在可解码环境中try?,永远不要try?。如果发生 DecodingError,您会丢弃重要信息。 catch errorprint 它。
  • @vadian 那么如何捕获错误并打印出来?
  • @JohnGerard `do { try JSONEncoder().encode(body) } catch let error { print(error) } `
  • @SergioBost 谢谢。我尝试了编码和解码,并且画布中没有错误。还是没有。
  • 代码与 SwiftUi 完全无关。调试代码、设置断点和观察变量或插入print 行。

标签: ios swift swiftui urlsession


【解决方案1】:
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 LoginToken: Decodable {
let token: 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://www.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
                    }
                    completion(.success(token))
                }
                
                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()
    
            
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2020-08-10
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多