简体   繁体   English

如何从 SwiftUI 中的 URLSession 获取响应

[英]How to Get Response from URLSession in SwiftUI

I'm trying to build a URLSession in SwiftUI to handle API token based authentication for login to a web app.我正在尝试在 SwiftUI 中构建一个 URLSession 来处理基于 API 令牌的身份验证,以登录到 web 应用程序。

I'm able to get the API working fine in Postman, but unable to get any sort of readable response in SwiftUI.我能够让 API 在 Postman 中正常工作,但无法在 SwiftUI 中获得任何类型的可读响应。 I'm new to SwiftUI and debugging.我是 SwiftUI 和调试新手。 From my web server's logs, which handles the authorization, it appears as though the login request from my Swift code is successful, but I can't seem to parse out the body or headers.从我处理授权的 web 服务器的日志来看,似乎来自我的 Swift 代码的登录请求是成功的,但我似乎无法解析出正文或标题。

I keep getting "LoginResponse(message: nil)" in my canvas.我在 canvas 中不断收到“LoginResponse(消息:nil)”。

Here's my SwiftUI code reduced to just trying to print the URLSession response.这是我的 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()
    }
}
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()
    
            
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM