обновить список в быстром пользовательском интерфейсе данными из локального файла json - PullRequest
0 голосов
/ 19 октября 2019

У меня есть функция, которая при выполнении цикла for сбрасывается в локальный json-файл с именем «data», берет некоторые данные и передает эти данные в массив «storage» типа «DataModel», и в конце все было сохранено (). с функцией save ()

пока здесь не будет выглядеть все работающее, потому что, если я распечатываю, сколько данных в моем хранилище, используя storage.count, количество данных увеличивается и больше, если я печатаю данные, считанные из файла jsonи передать в мой массив хранения все данные.

Я хочу, чтобы мой список обновлялся в swiftUI после нажатия кнопки и отображения всех данных, готовых из json

для отладки. Я пытаюсь создатьфункция, которая загружает данные через 2 текстовых поля и save () .. и это работает нормально, я добавляю новое значение, сохраняю и автоматическое обновление списка.

this my DataModel

import Foundation

class DataModel:Identifiable , Codable {

    var nameApt : String
    var icaoCode : String

init(nameApt: String, icaoCode: String) {
    self.nameApt = nameApt
    self.icaoCode = icaoCode
}
}

это мой DataManager

import UIKit
import Combine
class DataManager :ObservableObject {
let objectWillChange = PassthroughSubject<Void,Never>()

    var storage : [DataModel] = []
    typealias Storage = [DataModel]

    var filePath : String = ""

    init() { caricaDati() }
    func caricaDati() {
        // creiamo il percorso al file
        filePath = cartellaDocuments() + "\test.plist"

        // usiamo NSFileManager per sapere se esiste un file a quel percorso
        if FileManager.default.fileExists(atPath: filePath) {

            // se c'è de-archiviamo il file di testo nell'array
            // serve il blocco do try catch
            do {
                // proviamo a caricare il file dal percorso creato in precedenza
                let data = try Data(contentsOf: URL(fileURLWithPath: filePath))
                // creiamo il decoder
                let decoder = PropertyListDecoder()
                // proviamo a decodificare il file nell'array
                storage = try decoder.decode(Storage.self, from: data)
            } catch {
                // se non ce la fa scriviamo in console l'errore
                debugPrint(error.localizedDescription)
            }

        } else {
            let tem = DataModel(nameApt: "NewDasmi", icaoCode: "DAMI")
            storage = [tem]
            salva()
        }
    }

    func salva() {
        objectWillChange.send()
        let encoder = PropertyListEncoder()
        encoder.outputFormat = .xml // impostiamo l'output corretto
        // serve il blocco do try catch
        do {
            // proviamo a codificare l'array
            let data = try encoder.encode(storage)
            // proviamo a salvare l'array codificato nel file
            try data.write(to: URL(fileURLWithPath: filePath))
        } catch {
            // se non ce la fa scriviamo in console l'errore
            debugPrint(error.localizedDescription)
        }

    }

    // for debugging this function in order to see if my list update with manual insertion

    func creaData (nomeApt: String, icao: String) {
        let temporVar = DataModel(nameApt: nomeApt, icaoCode: icao)
        self.storage.append(temporVar)
        salva()
    }

    func open (fileName : String) {
        if let path = Bundle.main.path(forResource: fileName, ofType: "json") {
            do {
                let fileUrl = URL(fileURLWithPath: path)
                let datafile = try Data(contentsOf: fileUrl,options: .mappedIfSafe)
                let json = JSON(data:datafile)


                let caricaDati = DataModel(nameApt: "TEST", icaoCode: "TEST")
                var i =  0
                for _ in 0...json.count {
                    caricaDati.nameApt = json[i]["airportName"].stringValue
                    caricaDati.icaoCode = json[i]["airportCode"].stringValue
                    i=i+1
                    objectWillChange.send() 
                    self.storage.append(caricaDati)
                    print(caricaDati.nameApt)
                    print(caricaDati.icaoCode)
                }
                salva()
                print(storage.count) //  count of item in array storage


            }catch {
                print("erroree")
            }

        }
    }
    func cartellaDocuments() -> String {
        let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        //print(paths[0])
        return paths[0]
    }
}


и вот мой интерфейс в SwiftUI

import SwiftUI

struct ContentView: View {
    @ ObservedObject var dm : DataManager

    @State var nomeApt : String = ""
    @State var icaoApt : String = ""

    var body: some View {
        VStack {
            HStack {
                TextField("nome", text: $nomeApt)
                TextField("icao", text: $icaoApt)
                Button(action: {

                    // for debugging just to see if the list update automatically with new item manually inserted! and it works...
                    self.dm.creaData(nomeApt: self.nomeApt, icao: self.icaoApt)
                    // not updating with json file
                    self.dm.open(fileName: "data")
                }) {
                    Text(/*@START_MENU_TOKEN@*/"Button"/*@END_MENU_TOKEN@*/)
                }
            }
            List{
                ForEach (dm.storage) { item in
                    HStack {
                        Text(item.nameApt)
                        Spacer()
                        Text(item.icaoCode)
                    }

            }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(dm: DataManager())
    }
}

1 Ответ

0 голосов
/ 19 октября 2019

Я решил с помощью функции crea data внутри функции open

   func creaData (nomeApt: String, icao: String) {
        let temporVar = DataModel(nameApt: nomeApt, icaoCode: icao)
        self.storage.append(temporVar)
        salva()
    }

    func open (fileName : String) {
        if let path = Bundle.main.path(forResource: fileName, ofType: "json") {
            do {
                let fileUrl = URL(fileURLWithPath: path)
                let datafile = try Data(contentsOf: fileUrl,options: .mappedIfSafe)
                let json = JSON(data:datafile)
                var i = 0
                for _ in 0...json.count {
                    let caricaDati = DataModel(nameApt: "TEST", icaoCode: "TEST")
                    caricaDati.nameApt = json[i]["airportName"].stringValue
                    caricaDati.icaoCode = json[i]["airportCode"].stringValue
                    creaData(nomeApt: caricaDati.nameApt, icao: caricaDati.icaoCode)
                    i = i+1
                }
                salva()
                print(storage.count)



            }catch {
                print("erroree")
            }

        }
    }
...