Swift JSONDecode 解碼陣列在單個元素解碼失敗時也會失敗
在 Swift 中,使用 JSONDecoder 類處理 JSON 物件非常容易。始終需要使用 Codable 協議建立模型類或結構體。一個小的錯誤會導致無法解碼整個 JSON 物件。讓我們探索一些示例,以瞭解何時可能發生此錯誤以及如何在 Swift 中處理它。
什麼是 JSONDecoder 類?
然後使用 JSONDecoder 類將 JSON 資料從檔案解析為給定型別的例項,可以是類或結構體。decode(_:from:) 方法用於反序列化 JSON 資料,然後返回生成的 Type 物件以訪問 Type 物件的屬性。
我們嘗試使用 Codable 協議讀取上面給出的相同 JSON 作為示例。在準備好使用 JSONDecoder() 類解碼 JSON 資料之前,讓我們準備在解碼時提供的模型類。
這是一個建立此錯誤條件的示例
步驟 1 - 建立 JSON 檔案
在此步驟中,我們將建立一個示例 JSON 並將其另存為 Xcode 專案中的“.json”檔案。這是我們在此示例中將使用的 JSON:
[
{
"name": "Tom Cruise",
"age": 56,
"bornAt": "Syracuse, NY",
"birthdate": "July 3, 1962",
"photo": "https://jsonformatter.org/img/tom-cruise.jpg",
"topMovie": "Mission Impossible"
},
{
"name": "Robert Downey Jr.",
"age": 53,
"bornAt": "New York City, NY",
"birthdate": "April 4, 1965",
"photo": "https://jsonformatter.org/img/Robert-Downey-Jr.jpg"
}
]
我們將此 JSON 檔案命名為“sample.json”並儲存在專案目錄中。
步驟 2 - 建立模型結構
此步驟涉及建立名為“Actor”的結構體並符合 Decodable 協議。程式碼如下:
import Foundation
struct Actor: Decodable {
let name: String
let age: Int
let bornAt: String
let birthdate: String
let photo: String
let topMovie: String
}
步驟 3 - 將 JSON 解碼為 Actor 結構體
在此步驟中,我們將解碼 JSON 檔案並將資料儲存到 Actor 模型中。程式碼如下:
import UIKit
class CodableController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
decodeJSON()
}
func decodeJSON() {
do {
// creating path from the main bundle and getting data object from the path
if let bundlePath = Bundle.main.path(forResource: "sample", ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
let actors = try JSONDecoder().decode([Actor].self, from: jsonData)
print("Number of actors parsed: \(actors.count)")
}
} catch {
print(error)
}
}
}
在上面的示例中,我們建立了一個名為“CodableController”的檢視控制器以及一個方法。在此方法中,我們正在從主 bundle 讀取本地 JSON 檔案。之後,我們使用 JSONDecoder().decode() 方法解碼 JSON 資料。我們將型別“[Actor].self”傳遞給 decode 方法,如果成功解碼,則該方法將返回演員物件的陣列。
在此示例中,json 變數包含兩個物件的陣列,其中第二個物件無效(缺少必需的屬性)。JSONDecoder 用於解碼每個物件,並且在解碼過程中發生的任何錯誤都會被捕獲並列印到控制檯。成功解碼的物件將新增到名為 actors 的陣列中。示例的輸出將是:
keyNotFound(CodingKeys(stringValue: "topMovie", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 1", intValue: 1)], debugDescription: "No value associated with key CodingKeys(stringValue: "topMovie", intValue: nil) ("topMovie").", underlyingError: nil))
如您所見,由於 JSON 資料中缺少值,解碼過程失敗。可以清楚地說,鍵“topMovie”的值丟失了。
步驟 4 - 修復錯誤
在此步驟中,我們將嘗試修復上述錯誤。根據 JSON 檔案,第二個物件缺少“topMovie”鍵。如果您認為此值不需要在應用程式中執行進一步的操作,則可以將其設為可選,如下所示:
import Foundation
struct Actor: Decodable {
let name: String
let age: Int
let bornAt: String
let birthdate: String
let photo: String
let topMovie: String?
}
現在,您可以再次執行程式碼,您將在控制檯中看到列印的輸出:
Number of actors parsed: 2
如您所見,解碼過程已成功完成,沒有錯誤。
結論
Swift 提供了 JSONDecoder 類來將 JSON 物件編碼和解碼為 Swift 的模型物件,反之亦然。我們有責任仔細處理屬性宣告,否則會導致錯誤。
對於 JSON 物件中缺少的值,可以將這些變數設為可選。鑑於這些值可能不會出現在伺服器響應中,因此建議將它們設為可選。
另一種解決此問題的方法是使用另一種解碼技術,該技術分別解碼每個物件並丟棄任何解碼錯誤。即使無法解碼一個或多個元素,這也能使解碼繼續進行。
您可以透過呼叫 JSONDecoder 例項的 decode( :from:completionHandler:) 方法並向其傳遞一個接受 Result 物件作為引數的閉包來應用自定義解碼方法。Result 物件包含正確解碼的專案陣列或錯誤。
資料結構
網路
關係型資料庫管理系統
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP