使用Swift讀取JSON檔案
在本文中,我們將瞭解一些使用JSONSerialization和JSONDecoder類讀取JSON檔案的示例。如今,大多數iOS應用程式都使用這些類來處理JSON檔案。
您可以使用JSONSerialization類在Swift語言中讀取JSON檔案。為了讀取json檔案,首先需要將其轉換為字串或資料物件。之後,您可以將字串或資料物件傳遞給JSONSerialization類,將其轉換為字典或陣列物件。
JSONSerialization
iOS和macOS的Foundation框架預設包含JSONSerialization類。要建立Swift字典或陣列,此類需要字串或資料物件。使用相同的類,您還可以將字典或陣列轉換為JSON物件。JSONSerialization類處理序列化和反序列化過程。
此類的主要函式jsonObject(with:options:)用於反序列化,或將JSON資料轉換為Swift物件。此方法需要一個包含JSON資料的資料物件,以及一個名為options的引數,該引數控制方法的行為。此方法返回一個Swift物件,該物件可以是陣列或字典。JSON資料格式將決定返回型別。
以下是如何讀取JSON檔案並將其解析為字典的示例:
使用JSONSerialization類讀取JSON
這是一個JSON示例:
示例
{
"id": 1,
"title": "iPhone 12",
"price": 749,
"thumbnail": "https://i.dummyjson.com/data/products/1/thumbnail.jpg",
"manufacturedDetail": {
"company": {
"manufacturedBy": "Apple Inc."
}
}
}
我們將使用上面的JSON來讀取它。您可以透過為檔案命名,向Xcode專案新增一個副檔名為“.json”的新檔案。
讀取JSON檔案
func readJSONFile(forName name: String) {
do {
if let bundlePath = Bundle.main.path(forResource: name, ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
if let json = try JSONSerialization.jsonObject(with: jsonData, options: .mutableLeaves) as? [String: Any] {
print("JSON: \(json)")
} else {
print("Given JSON is not a valid dictionary object.")
}
}
} catch {
print(error)
}
}
輸出
JSON: ["title": iPhone 12, "price": 749, "thumbnail": https://i.dummyjson.com/data/products/1/thumbnail.jpg, "id": 1, "manufacturedDetail": {
company = {
manufacturedBy = "Apple Inc.";
};
}]
這將為您提供一個JSON物件,您可以在程式碼中將其用作字典。如果您的JSON檔案是物件的陣列,則可以使用mutableContainers選項而不是mutableLeaves。由於我們必須從JSON物件讀取字典,因此我們將使用mutableLeaves選項。
使用JSONDecoder()類讀取JSON
Swift的新版本引入了Codable協議,這使得使用起來更加容易和靈活。
然後使用JSONDecoder類將檔案中的JSON資料解析為給定型別的例項(類或結構)。decode(_:from:)方法用於反序列化JSON資料,然後返回生成的Type物件以訪問Type物件的屬性。
我們正在嘗試使用Codable協議讀取上面給出的相同JSON作為示例。在我們準備好使用JSONDecoder()類解碼JSON資料之前,讓我們準備在解碼時提供的模型類。
根據上面的JSON資料,這是模型類:
import Foundation
struct Product: Decodable {
let id: Int
let title: String
let price: Int
let thumbnail: String
let manufacturedBy: String
enum RootKeys: String, CodingKey {
case id, title, price, thumbnail, manufacturedDetail
}
enum ManufacturedKeys: String, CodingKey {
case company
}
enum CompanyKeys: String, CodingKey {
case manufacturedBy
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: RootKeys.self)
id = try values.decode(Int.self, forKey: .id)
title = try values.decode(String.self, forKey: .title)
price = try values.decode(Int.self, forKey: .price)
thumbnail = try values.decode(String.self, forKey: .thumbnail)
let manufacturedContainer = try values.nestedContainer(keyedBy: ManufacturedKeys.self, forKey: .manufacturedDetail)
let companyContainer = try manufacturedContainer.nestedContainer(keyedBy: CompanyKeys.self, forKey: .company)
self.manufacturedBy = try companyContainer.decode(String.self, forKey: .manufacturedBy)
}
}
如何解碼?
func readJSONFile(forName name: String) {
do {
// creating a path from the main bundle and getting data object from the path
if let bundlePath = Bundle.main.path(forResource: name, ofType: "json"),
let jsonData = try String(contentsOfFile: bundlePath).data(using: .utf8) {
// Decoding the Product type from JSON data using JSONDecoder() class.
let product = try JSONDecoder().decode(Product.self, from: jsonData)
print("Product name: \(product.title) and its price: \(product.price)")
}
} catch {
print(error)
}
}
輸出
Product name: iPhone 12 and its price: 749
結論
在Swift中,您可以透過低階API將原始JSON資料轉換為陣列或字典之類的集合。您可以使用JSONSerialization類將原始JSON物件轉換為有意義的物件。此類內置於Foundation框架中。您可以在任何平臺(例如iOS、macOS、watchOS等)上使用此類。此外,反過來,您可以使用反序列化過程將自定義物件轉換回原始JSON資料。
在Swift 4中,Apple引入了Codable協議,該協議使序列化和反序列化過程變得容易。此協議提供了一種靈活的方式來使用JSON資料來解析資料並將其儲存到模型類/結構中。此協議可用於輕鬆地將模型物件轉換為JSON資料。
Codable協議有助於減少程式碼並處理序列化和反序列化過程,使程式碼更簡潔易維護。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP