从documentDirectory

时间:2018-04-04 19:10:30

标签: json swift local

我对SWIFT很新,我正在尝试使用来自JSON文件(financetoday.json)的数据来填充表格,并让用户更新并将数据存储在设备上。该表具有折叠单元格(使用XIB),每个单元格都有一个嵌入式UISlider来更新值。在我最初的工作中,我让表从包中成功加载JSON文件,填充表,滑块更改每个值。现在困难的部分。为了保存/更改我需要将JSON文件移动到documentDirectory中的数据,然后对该文件中的数据进行任何更改。一旦用户第一次启动应用程序,我就不再需要在bundle中使用JSON文件,只需使用documentDirectory中的版本。我无法获取表来读取documentDirectory中的JSON文件。任何帮助,将不胜感激。 这是我在AppDelegate中添加一个方法来移动文档目录

中的JSON文件的地方

//将json文件从bundle移动到文档文件夹

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文件...而不是bundle。我所有尝试更改的结果都是一张空白表格。所以现在我指的是捆绑中的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
    }
}




2 个答案:

答案 0 :(得分:1)

这将在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)
    }

答案 1 :(得分:0)

不确定这是否相关,但可以尝试:

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上还有其他类似的例子