我是 swift 新手。我正在嘗試使用 swift 將 json 轉換為模型。我正在使用泛型函式來完成功能。這是 json 的結構。

這是我基于 jason 創建的模型。
import Foundation
// MARK: - Welcome
struct Welcome: Codable {
let photos: [Photo]
}
// MARK: - Photo
struct Photo: Codable {
let id, sol: Int
let camera: Camera
let imgSrc: String
let earthDate: String
let rover: Rover
enum CodingKeys: String, CodingKey {
case id, sol, camera
case imgSrc = "img_src"
case earthDate = "earth_date"
case rover
}
}
// MARK: - Camera
struct Camera: Codable {
let id: Int
let name: String
let roverID: Int
let fullName: String
enum CodingKeys: String, CodingKey {
case id, name
case roverID = "rover_id"
case fullName = "full_name"
}
}
// MARK: - Rover
struct Rover: Codable {
let id: Int
let name, landingDate, launchDate, status: String
enum CodingKeys: String, CodingKey {
case id, name
case landingDate = "landing_date"
case launchDate = "launch_date"
case status
}
}
這是通用函式中的代碼。
func getModel<Model: Codable>(_ type: Model.Type, from url: String, completion: @escaping (Result<Model, NetworkError>) -> ()) {
guard let url = URL(string: url) else {
completion(.failure(.badURL))
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
completion(.failure(.other(error)))
return
}
if let data = data {
do {
let response = try JSONDecoder().decode(type, from: data)
completion(.success(response))
} catch let error {
completion(.failure(.other(error)))
}
}
}
.resume()
}
我正在嘗試呼叫此函式表單控制器,但它顯示錯誤“帖子”型別的值沒有成員“資料”
這是呼叫該函式的代碼。
class ViewModel {
private let networkManager = NetworkManager()
private var rovers = [Post]()
func getStories (){
networkManager
.getModel(Post.self, from: NetworkURLs.baseURL) {[weak self]result in
switch result{
case .success(let response):
self?.rovers = response.data.camera.map{$0.data} **// error on this line**
case .failure( let error):
print( error.localizedDescription)
}
}
}
uj5u.com熱心網友回復:
你response的型別Post是沒有屬性的data。您需要從回應中提取照片陣列,然后映射到該陣列并rovers從中檢索屬性。
我想你的意思是寫
self?.rovers = response.photos.camera.map{$0.rover}
但是,即使這樣也行不通,因為您的資料結構與您的 JSON 不匹配。從中可以看出,rover是一個屬性 on photonot on camera。
您將需要驗證 JSON -> 模型映射
在下面的評論中鏈接 JSON 后進行編輯:
使用 API 中的 JSON,它確認camera并rover位于 JSON 中的同一級別:
{
"photos": [
{
"id": 102693,
"sol": 1000,
"camera": {
"id": 20,
"name": "FHAZ",
"rover_id": 5,
"full_name": "Front Hazard Avoidance Camera"
},
"img_src": "http://mars.jpl.nasa.gov/msl-raw-images/proj/msl/redops/ods/surface/sol/01000/opgs/edr/fcam/FLB_486265257EDR_F0481570FHAZ00323M_.JPG",
"earth_date": "2015-05-30",
"rover": {
"id": 5,
"name": "Curiosity",
"landing_date": "2012-08-06",
"launch_date": "2011-11-26",
"status": "active"
}
},
....
所以你需要改變你的資料模型:
struct Photo : Codable{
let id : Int
let sol : Int
let camera : Camera
let imgSrc: String
let earthDate: String
let rover: Rover
}
然后解碼它
self?.rovers = response.photos.map{$0.rover}
注意。在 Swift 中,所有結構型別都應該按照約定大寫。
uj5u.com熱心網友回復:
您的 Post 型別的結構確實沒有名為“資料”的成員。您似乎假設您的回應物件是 Photo 型別 - 但錯誤訊息告訴您,它是 Post 型別,它只包含 Photo 物件的陣列。
嘗試類似:
response.photos[0]從陣列中獲取第一個 Photo 物件 - 如果有的話。然后,假設您有一個response.photos[0].data已經為您提供了一個 Camera 物件-您似乎是通過型別而不是成員名稱進行呼叫的。因此,如果您想更進一步并訪問 Rover 物件,您需要執行以下操作:response.photos[0].data.data
我明白了,您想從每個 Post 中提取幾個 Rovers,假設是一個,但這將與您的初始 rovers 變數被分配一個型別的 Posts 陣列發生沖突——這意味著您必須將其更改為 [Rover]。我不確定 map-function 是否真的適合你想要在這里做的事情。使用回圈,遍歷 Posts 并將 Rover 物件附加到 Rover 陣列將是執行此操作的“手動”方式。
希望這可以幫助。
編輯:因為你已經在問題中編輯了你的模型,所以我現在看不到“帖子”去了哪里。我的回復可能只符合原始問題的發布方式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426113.html
上一篇:使用泛型的工廠模式
下一篇:表測驗Go泛型
