如何在 SwiftUI 中访问 json 响应?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中访问 json 响应?【英文标题】:How to access a json response in SwiftUI? 【发布时间】:2020-03-24 21:33:11 【问题描述】:

所以我发出一个 HTTP 请求,我得到一个如下所示的响应:


  "code": 200,
  "status": "success",
  "patients": 
    "bogdanp": 
      "_id": "5e77c7bbc7cbd30024f3eadb",
      "name": "Bogdan Patient",
      "phone": "0732958473"
    ,
    "robertp": 
      "_id": "5e77c982a2736a0024e895fa",
      "name": "Robert Patient",
      "phone": "0739284756"
    
  

如何将“bogdanp”作为字符串获取,以及如何访问对象属性?例如,如何访问“姓名”或“电话”等?

这是我的 HTTP 代码:

func getPatients(link: String, username: String)

    var code = 0 // this is the variable that stores the error code from the response, it is initially set to 0
    let parameters: [String : Any] = ["username": username]
    let url = URL(string: link)!
    let session = URLSession.shared
    var request = URLRequest(url: url)

    request.httpMethod = "POST"
    do 
        request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
     catch _ 
        

        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let task = session.dataTask(with: request as URLRequest, completionHandler:  data, response, error in
            guard error == nil else 
                return
            
            guard let data = data else 
                return
            
            do 
                if let jsonResponse = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] 
                        // Here I want to access the json response
                    
             catch _ 
            
        )
    task.resume()

【问题讨论】:

请删除 json 图像并将其粘贴为 code 文本。 【参考方案1】:

使用 SwiftUI 发出呼叫请求的最佳方式是使用 Combine。

您首先必须创建一个您想要返回的 JSON 对象的模型:

import Foundation

//MARK: - Your object to retrieve from JSON
struct Doctor: Codable, Identifiable 
  let id = UUID()
  let patients: [Patients]


struct Patients: Codable 
  let id: String
  let name: String
  let phone: String

然后您创建一个类,该类将使用 Combine 处理您的 JSON 请求(我添加了一个加号让您处理任何响应错误):

import Foundation
import Combine

class Network 

  // Handle your request errors
  enum Error: LocalizedError 
    case invalidResponse
    case addressUnreachable(URL)

    var errorDescription: String? 
      switch self 
      case .invalidResponse:
        return "The server responded with garbage."
      case .addressUnreachable(let url):
        return "\(url.absoluteString) is unreachable."
      
    
  

  // Add your url
  let urlRequest = URL(string: "your url")!

  // Networking on concurrent queue
  let networkQueue = DispatchQueue(label: "Networking",
                                   qos: .default,
                                   attributes: .concurrent)

  // Combine network call (This replace your previous code)
  func downloadPatients() -> AnyPublisher<Doctor, Error> 
    URLSession.shared
      .dataTaskPublisher(for: urlRequest)
      .receive(on: networkQueue)
      .map(\.data)
      .decode(type: Doctor.self, decoder: JSONDecoder())
      .mapError  (error) -> Network.Error in
        switch error 
        case is URLError:
          return Error.addressUnreachable(self.urlRequest)
        default:
          return Error.invalidResponse
        
    
    .eraseToAnyPublisher()
  

现在,在您需要这些值的 SwiftUI 文件中,您只需调用 downloadPatients() 函数并根据需要使用返回数据:

import SwiftUI

let networkRequest = Network()

//MARK: - Call this function where you want to make your call
func loadPatients() 
  _ = networkRequest.downloadPatients()
    .sink(
      receiveCompletion: 
        print("Received Completion: \($0)") ,
      receiveValue:  doctor in
        // doctor is your response and [0].name is your first patient name
        print(doctor.patients[0].name) 
  )

【讨论】:

你好@Roland 我使用你的答案,但有一个疑问 您有什么样的查询?承载?内容类型?认证?您能否在 *** 上发布带有您的 URLRequest 特性的问题并在对话中添加链接? 嘿,谢谢@Roland 的回复,我在这里发布我的问题,你能帮忙***.com/questions/66043573/…

以上是关于如何在 SwiftUI 中访问 json 响应?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 如何从响应 JSON API 中分离单个数据

iOS:如何从 REST SwiftUi 访问和使用 API 响应数据

SwiftUI:如何处理 BLE 响应并显示新值

如何在 Swift 中访问 JSON 响应中的特定数据

macOS 上的 SwiftUI:如何为 onDelete 启用 UI(从列表中删除)

如何在 NSDictionary 中访问本地 JSON 文件响应以在 UITableView 中显示?