[英]Encode/Decode JSON locally from documentDirectory
我對 SWIFT 還很陌生,我正在嘗試使用來自 JSON 文件 (financetoday.json) 的數據來填充表,並讓用戶更新並將數據存儲在設備上。 該表具有折疊單元格(使用 XIB)並且每個單元格都有一個嵌入式 UISlider 來更新值。 在我最初的工作中,我讓表成功地從包中加載了 JSON 文件,填充了表,並且滑塊更改了每個值。 現在是困難的部分。 為了保存/更改數據,我需要將 JSON 文件移動到 documentDirectory 中,然后對該文件中的數據進行任何更改。 一旦用戶第一次啟動應用程序,我就不再需要使用 bundle 中的 JSON 文件,只需要使用 documentDirectory 中的版本。 我一直無法獲取表來讀取 documentDirectory 中的 JSON 文件。 任何幫助將不勝感激。 這是我在 AppDelegate 中添加了一個方法來移動文檔目錄中的 JSON 文件的地方
// 將 json 文件從包移動到文檔文件夾
var finalDatabaseURL:String = String()
func copyDatabaseIfNeeded() {
let fileManager = FileManager.default
let documentsUrl = fileManager.urls(for: .documentDirectory,
in: .userDomainMask)
guard documentsUrl.count != 0 else {
return // Could not find documents URL
}
let finalDatabaseURL = documentsUrl.first!.appendingPathComponent("financetoday.json")
if !( (try? finalDatabaseURL.checkResourceIsReachable()) ?? false) {
print("DB does not exist in documents folder")
let documentsURL = Bundle.main.resourceURL?.appendingPathComponent("financetoday.json")
do {
try fileManager.copyItem(atPath: (documentsURL?.path)!, toPath: finalDatabaseURL.path)
} catch let error as NSError {
print("Couldn't copy file to final location! Error:\(error.description)")
}
} else {
print("Database file found at path: \(finalDatabaseURL.path)")
}
}
然后我添加到 applicationDidBecomeActive
self.copyDatabaseIfNeeded()
在我的數據模型中,這就是從包中加載 JSON 數據的樣子,但我需要更改方法 dataFromFile 中的代碼以使用 documentDirectory 中的 JSON 文件......而不是包。 我所有嘗試更改的結果都是空白表格。 所以現在我指向包中的 JSON。 任何幫助將不勝感激。
import Foundation public func dataFromFile(_ filename: String) -> Data? { @objc class TestClass: NSObject { } let bundle = Bundle(for: TestClass.self) if let path = bundle.path(forResource: filename, ofType: "json") { return (try? Data(contentsOf: URL(fileURLWithPath: path))) } return nil } class Plan { var yeardata: Int? var incomedata = [Income]() var expensedata = [Expense]() var assetdata = [Asset]() var liabilitydata = [Liability]() var profiledata = [Profile]() var assumptiondata = [Assumption]() init?(data: Data) { do { if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any], let myplan = json["data"] as? [String: Any] { if let incomedata = myplan["incomedata"] as? [[String: Any]] { self.incomedata = incomedata.map { Income(json: $0) } } if let expensedata = myplan["expensedata"] as? [[String: Any]] { self.expensedata = expensedata.map { Expense(json: $0) } } if let assetdata = myplan["assetdata"] as? [[String: Any]] { self.assetdata = assetdata.map { Asset(json: $0) } } if let liabilitydata = myplan["liabilitydata"] as? [[String: Any]] { self.liabilitydata = liabilitydata.map { Liability(json: $0) } } if let profiledata = myplan["profiledata"] as? [[String: Any]] { self.profiledata = profiledata.map { Profile(json: $0) } } if let assumptiondata = myplan["assumptiondata"] as? [[String: Any]] { self.assumptiondata = assumptiondata.map { Assumption(json: $0) } } } } catch { print("Error deserializing JSON: \\(error)") return nil } } } class Income { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } } class Expense { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } } class Asset { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } } class Liability { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } } class Profile { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } } class Assumption { var key: String? var value: Any? init(json: [String: Any]) { self.key = json["key"] as? String self.value = json["value"] as Any } }
這將在 json 中讀取。 我不太熟悉字典轉換,因為我已經開始使用我強烈推薦的Codable協議。
if let path = Bundle.main.path(forResource: "FileName", ofType: "json") {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped)
let jsonString = String(data: value, encoding: .utf8)
print("json as string: \(jsonString)")
let json = try JSONSerialization.data(withJSONObject: data, options: []) as? [String: Any]
print("json as dictionary: \(json)")
} catch let error {
print("parse error: \(error.localizedDescription)")
}
}
如何解碼可編碼數據:
let decoder = JSONDecoder()
do {
let decodableJSON = try decoder.decode(ObjectConformingToCodable.self, from: data)
print(decodableJSON)
} catch let error {
print(error.localizedDescription)
}
不確定這是否相關,但可以嘗試:
let documentsDirectoryPathString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let documentsDirectoryPath = NSURL(string: documentsDirectoryPathString)!
let jsonFilePath = documentsDirectoryPath.appendingPathComponent("test.json")
let fileManager = FileManager.default
var isDirectory: ObjCBool = false
// creating a .json file in the Documents folder
if fileManager.fileExists(atPath: (jsonFilePath?.absoluteString)!, isDirectory: &isDirectory) {
print("File exists")
}
我還發現:Gist 上的 JSONSaveLoad.swift:
https://gist.github.com/norsez/aa3f11c0e875526e5270e7791f3891fb
我確定 Github 上還有其他類似的例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.