如何解决如何在 SwiftUI 中对 API 调用 JSON 进行故障排除
我正在对 Rails 服务器进行 API 调用以获取一组对象,然后在 SwiftUI 视图中显示这些对象。
当我在 Postman 中进行相同的 API 调用时,它工作正常。我收到了回复。
当我在我的 SwiftUI 项目中进行同样的调用时,我似乎没有正确地将该响应保存到我的模型中,否则我会遇到错误。我的服务器似乎可以正常发送数据。视图加载,但有一个空白列表和“你的项目”的导航标题
寻求有关如何检查我的响应数组是否正在存储数据以及如何进行故障排除的指导。视图从这个数组加载数据,它看起来是空的。
我使用 quicktype.io 从 Postman 中服务器提供的 JSON 映射出模型结构。
这是模型的相关部分:
import Foundation
struct ProjectFetchRequest: Decodable {
let request: [ProjectResponseObjectElement]
}
// MARK: - ProjectResponseObjectElement
struct ProjectResponseObjectElement: Codable,Identifiable {
let id = UUID()
let project: Project
let projectType: ProjectType
let inspirations: [JSONAny]
}
// MARK: - Project
struct Project: Codable {
let name: String
let id: Int
let projectType,timeframe,description: String
let currentProgress: Int
let zipcode,status,createdAt,visibility: String
let city,state: String
let title: String
let showURL: String
let thumbnailURL: String
let ownedByLoggedinUser,hasBids,isPublished: Bool
}
// MARK: - ProjectType
struct ProjectType: Codable {
let generalConstructions,landscapes: [GeneralConstruction]?
}
// MARK: - GeneralConstruction
struct GeneralConstruction: Codable {
let id: Int
}
typealias ProjectResponseObject = [ProjectResponseObjectElement]
API 调用如下:
import Foundation
final class Projectservice {
static let shared = Projectservice()
private init() {}
func fetchProjects(completed: @escaping (Result<[ProjectResponseObjectElement],AuthenticationError>) -> Void) {
guard let url = URL(string: "https://example.com/api/v1/projects") else {
completed(.failure(.custom(errorMessage:"URL unavailable")))
return
}
guard let Accesstoken = UserDefaults.standard.string(forKey: "access-token") else { return }
guard let client = UserDefaults.standard.string(forKey: "client") else { return }
guard let uid = UserDefaults.standard.string(forKey: "userEmail") else { return }
print(Accesstoken)
print(client)
print(uid)
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue(Accesstoken,forHTTPHeaderField: "access-token")
request.addValue(client,forHTTPHeaderField: "client")
request.addValue(uid,forHTTPHeaderField: "uid")
request.addValue("Bearer",forHTTPHeaderField: "Tokentype")
URLSession.shared.dataTask(with: request) { (data,response,error) in
guard let data = data,error == nil else { return }
guard let projectResponse = try? JSONDecoder().decode(ProjectFetchRequest.self,from: data) else { return }
completed(.success(projectResponse.request))
print(projectResponse)
}.resume()
}
}
这是视图:
import SwiftUI
struct ProjectsView: View {
@State private var projectObjects: [ProjectResponseObjectElement] = []
var body: some View {
NavigationView{
List(projectObjects){ projectObject in
ProjectRowView(project: projectObject.project)
}
.navigationTitle("Your Projects")
.foregroundColor(.primary)
}.navigationViewStyle(StackNavigationViewStyle())
.onAppear {
fetchProjects()
}
}
func fetchProjects() {
Projectservice.shared.fetchProjects { result in
DispatchQueue.main.async {
switch result {
case .success(let projectObjects):
self.projectObjects = projectObjects
case .failure(let error):
print(error.localizedDescription)
}
}
}
}
}
解决方法
我需要在 URLSession 中声明顶级数组结构。
import Foundation
final class Projectservice {
static let shared = Projectservice()
private init() {}
func fetchProjects(completed: @escaping (Result<[ProjectResponseObjectElement],AuthenticationError>) -> Void) {
guard let url = URL(string: "https://example.com/api/v1/projects") else {
completed(.failure(.custom(errorMessage:"URL unavailable")))
return
}
guard let Accesstoken = UserDefaults.standard.string(forKey: "access-token") else { return }
guard let client = UserDefaults.standard.string(forKey: "client") else { return }
guard let uid = UserDefaults.standard.string(forKey: "userEmail") else { return }
print(Accesstoken)
print(client)
print(uid)
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("application/json",forHTTPHeaderField: "Content-Type")
request.addValue(Accesstoken,forHTTPHeaderField: "access-token")
request.addValue(client,forHTTPHeaderField: "client")
request.addValue(uid,forHTTPHeaderField: "uid")
request.addValue("Bearer",forHTTPHeaderField: "Tokentype")
URLSession.shared.dataTask(with: request) { (data,response,error) in
guard let data = data,error == nil else { return }
do {
let projectResponse = try JSONDecoder().decode([ProjectResponseObjectElement].self,from: data)
completed(.success(projectResponse))
} catch {
print(error)
}
}.resume()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。