簡體   English   中英

從 documentDirectory 本地編碼/解碼 JSON

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM