Как сделать данные JSON постоянными для автономного использования (Swift 4) - PullRequest
0 голосов
/ 11 июня 2018

В моем приложении я сейчас обрабатываю файл JSON, размещенный на веб-сайте.Я хочу сделать так, чтобы, если пользователь открывает приложение и не имеет подключения к данным, он использовал последние загруженные данные.Я не совсем уверен, как это сделать.

Моя первоначальная мысль состояла в том, чтобы загрузить сам JSON, а затем просто сравнить номера версий при загрузке, загрузить его, если новее, и затем кодировать приложение, чтобы всегда читатьлокальный файл.Тем не менее, я думаю, что я бы предпочел просто посмотреть на веб-сайт, сохранить содержимое JSON локально, а затем при последующих открытиях просто сравнить версию и обновить ее локальные данные, если версия на сайте более новая.

Есть ли какое-либо преимущество одного метода перед другим?

С чего мне начать искать информацию о том, как данные, загружаемые с веб-сайта JSON, хранятся локально и постоянно?Я полагаю, что для этого лучше всего подойдет CoreData, но мой Google-фу не особо разбирается в том, как перенести JSON в Core Data.

РЕДАКТИРОВАТЬ: По предложению Старкси я добавил следующеев мое приложение, но я получаю сообщение об ошибке в строке let jsonData = try ....

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)
    }
}

Ошибка:

Неоднозначная ссылка на элемент jsonObject участника (с: options:) '

Когда я гуглю это, я вижу другой пост SO, в котором говорится, что я должен использовать JSONDecoder().decode вместо этого, так как я использую Swift 4, но я не уверен, как преобразовать вышеуказанный кодвместо этого использовать этот метод.

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

это не самый лучший ответ, но вы можете сохранить его по умолчанию для пользователя

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
}
0 голосов
/ 11 июня 2018

Я бы порекомендовал взглянуть на Realm, если вам когда-нибудь понадобится локальное хранилище.Это альтернатива Core Data, но ее проще использовать: https://realm.io/docs/swift/latest/

Специально для этой задачи я бы не сохранял в CoreData или Realm, а непосредственно в каталог приложения, а также сохранял версию ирасположение файла в 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 (если она имеет версию, поступающую из Интернета) в 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)
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...