如何使JSON数据持久以供脱机使用(Swift 4)

时间:2018-06-11 04:51:50

标签: swift core-data

在我的应用中,我目前正在处理网站上托管的JSON文件。我想这样做,以便如果用户打开应用程序并且没有数据连接,它将使用上次下载的数据。我不完全确定如何解决这个问题。

我最初的想法是下载JSON本身,然后只是在加载时比较版本号,如果更新则下载它,然后编写应用程序以始终读取本地文件。但是,我认为我只是看看网站,在本地存储JSON内容,然后在后续打开时,只需比较版本并更新其本地数据,如果网站上的版本更新。

一种方法优于另一种方法有什么优势吗?

我应该从哪里开始查找有关使我从本地存储的JSON存储的JSON加载的数据和持久存储的信息?我认为CoreData最适合这种情况,但我的Google-fu并没有发现如何将JSON带入核心数据。

修改 根据Starksy的建议,我将以下内容添加到了我的应用中,但我在shopify_customer_id行收到了错误。

let jsonData = try ...

错误是

  

对成员' jsonObject的不明确引用(带:选项:)'

当我谷歌那个时,我看到另一个SO帖子说我应该使用func saveJSONFile() { let itemName = "myJSONFromWeb" let hostedJSONFile = "http://tourofhonor.com/BonusData.json" do { let directory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false) let fileURL = directory.appendingPathComponent(itemName) // let jsonData = try JSONDecoder().decode(hostedJSONFile.self, from: Data) let jsonData = try JSONSerialization.jsonObject(with: hostedJSONFile, options: .mutableContainers) try jsonData.write(to: fileURL, options: .atomic) //Save the location of your JSON file to UserDefaults defaults.set(fileURL, forKey: "pathForJSON") } catch { print(error) } } ,因为我使用的是Swift 4,但我不确定如何将上述代码转换为使用改为那种方法。

2 个答案:

答案 0 :(得分:5)

如果您需要本地存储,我建议您查看Realm。它是Core Data的替代品,但使用起来更简单: https://realm.io/docs/swift/latest/

具体来说,对于此任务,我不会保存到CoreData或Realm,而是直接保存到app目录,并将文件的版本和位置保存在UserDefaults中。

1)(更新的答案)

//Download the file from web and save it to the local directory on the device
let hostedJSONFile = "http://tourofhonor.com/BonusData.json"
let jsonURL = URL(string: hostedJSONFile)
let defaults = UserDefaults.standard
let itemName = "myJSONFromWeb"
do {
    let directory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let fileURL = directory.appendingPathComponent(itemName)
    let jsonData = try Data(contentsOf: jsonURL!)
    try jsonData.write(to: fileURL, options: .atomic)
    //Save the location of your JSON file to UserDefaults
    defaults.set(fileURL, forKey: "pathForJSON")
} catch {
    print(error)
}

2)将您的JSON版本(如果它有来自Web的版本)保存到UserDefaults:

defaults.set(1, forKey: "jsonVersion")

3)启动应用程序时,您需要将当前的jsonVersion验证为您在文档目录中保存的版本:

let currentVersion = //...get the current version from your JSON file from web.
let existingVersion = defaults.integer(forKey: "jsonVersion")
if currentVersion != existingVersion {
   //Download the newest JSON and save it again to documents directory for future use. Also, use it now for your needs.
} else {
   //Retrieve the existing JSON from documents directory
   let fileUrl = defaults.url(forKey: "pathForJSON")
   do {
       let jsonData2 = try Data(contentsOf: fileUrl!, options: [])
       let myJson = try JSONSerialization.jsonObject(with: jsonData2, options: .mutableContainers)
       //...do thing with you JSON file
       print("My JSON: ", myJson)
   } catch {
       print(error)
   }

答案 1 :(得分:0)

它不是最好的答案,但您可以做的是将其保存在用户默认值

UserDefaults.standard.set(data, forKey: "jsonData")

不保存对象,只保存从会话中获取的数据,然后创建一个prase方法

func parseJSON (dataRecieved : Data) -> [ItemsJSON] {
    var jsonArray = [ItemsJSON]()
    do {
    let decode = JSONDecoder()
    let json = try decode.decode(CustomJSONClass.self, from: dataRecieved)
        if json.error == true {
            print("error from server")
        }
        for index in json.data {
            jsonArray.append(index)
        }
    }
    catch {
        print("error in appending json")
    }
    return jsonArray
}