Обновите Файл Json В Каталоге Документов

#json #swift

Вопрос:

У меня есть локальный файл Json в пакете приложений.

Существующий файл Json:

 [
    {
        "id": 1001,
        "key1": "key1Value",
        "key2": "key2Value",
    },
    {
        "id": 1002,
        "key1": "key1Value",
        "key2": "key2Value",
    },
    {
        "id": 1003,
        "key1": "key1Value",
        "key2": "key2Value",
    },
]
 

Я копирую этот Json в каталог документов со следующим кодом:

 let vehicleInfo: [Vehicle] = readJSON("vehicleInfo.json")
func readJSON<T: Codable>(_ named: String) -> T {
    if let resPath = Bundle.main.resourcePath {
        do {
            let dirContents = try FileManager.default.contentsOfDirectory(atPath: resPath)
            let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
            let filteredFiles = dirContents.filter{ $0.contains(".json")}
            for fileName in filteredFiles {
                if let documentsURL = documentsURL {
                    let sourceURL = Bundle.main.bundleURL.appendingPathComponent(fileName)
                    let destURL = documentsURL.appendingPathComponent(fileName)
                    do {
                        try FileManager.default.copyItem(at: sourceURL, to: destURL)
                        print("Save to documents")
                    } catch {
                        print("ERROR FileManager.default.copyItem:: ", error)
                    }
                }
            }
        }catch { print("ERRIR 2", error) }
    }
    let data: Data
    do {
        let fileURL = try FileManager.default
            .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent("vehicleInfo.json")
        
        data = try Data(contentsOf: fileURL)
        let foo = try JSONDecoder().decode(T.self, from: data)            
        return foo
    } catch {
        fatalError("Couldn't find  in main bundle.")
    }
}
 

Пользователь обновляет некоторые значения(только key2 значение может быть изменено пользователем) Json.

Обновленный пользователем файл Json:

 [
    {
        "id": 1001,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
    },
    {
        "id": 1002,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
    },
    {
        "id": 1003,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
    },
]
 

Json update code:

 do {
    let fileURL = try FileManager.default
        .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
        .appendingPathComponent("vehicleInfo.json")
    
    let jsonEncoder = JSONEncoder()
    let jsonData = try jsonEncoder.encode(self.userData.vehicles)
    
    try jsonData.write(to: fileURL)
} catch {
    print("an error happened while creating the file", error)
}
 

Теперь я обновлю свое приложение новым файлом Json, в котором есть несколько новых ключей и объектов.

У меня есть 2 цели:

1 — Скопируйте новый файл Json в папку документов с тем же именем.

2 — Скопируйте существующие key2 значения в новый файл Json key2 .

Когда пользователь обновляет приложение, папка документов должна содержать следующий файл Json:

 [
    {
        "id": 1001,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
        "key3": "key3Value",
    },
    {
        "id": 1002,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
        "key3": "key3Value",
    },
    {
        "id": 1003,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
        "key3": "key3Value",
    },
    {
        "id": 1004,
        "key1": "key1Value",
        "key2": "key2ValueChanged",
        "key3": "key3Value",
    }
]
 

Как я могу скопировать новый файл Json в каталог документов и скопировать значения существующего файла Json key2 в новый файл Json?

Комментарии:

1. Зачем вам нужно перечислять содержимое папки ресурсов вашего пакета? Нет никакой гарантии, что ваш файл будет там расположен. Что вам следует использовать, так это let vehicleInfoURL = Bundle.main.url(forResource: "vehicleInfo", withExtension: "json")!

2. Кстати, вы должны использовать ApplicationSupportDirectory вместо DocumentDirectory этого

3. @LeoDabus Я вижу, что ApplicationSupportDirectory пользователь не может смотреть. Как вы сказали, я считаю, что лучше использовать ApplicationSupportDirectory вместо DocumentDirectory этого .

4. Используйте этот каталог для хранения всех файлов данных приложения, за исключением файлов, связанных с документами пользователя. Например, вы можете использовать этот каталог для хранения файлов данных, созданных приложением, файлов конфигурации, шаблонов или других фиксированных или изменяемых ресурсов, которыми управляет приложение. Приложение может использовать этот каталог для хранения изменяемой копии ресурсов, изначально содержащихся в пакете приложения. Игра может использовать этот каталог для хранения новых уровней, приобретенных пользователем и загруженных с сервера.

5. Все содержимое в этом каталоге должно быть размещено в пользовательском подкаталоге, имя которого соответствует идентификатору пакета вашего приложения или вашей компании. В iOS содержимое этого каталога поддерживается iTunes и iCloud.