使用本地 json 文件中的数据更新 swift UI 中的列表
Posted
技术标签:
【中文标题】使用本地 json 文件中的数据更新 swift UI 中的列表【英文标题】:update a list in swift UI with data from a local json file 【发布时间】:2019-10-19 12:23:43 【问题描述】:我有一个函数,使用 for 循环实现一个名为“data”的本地 json 文件获取一些数据并将这些数据传递给“DataModel”类型的数组“storage”,最后所有内容都已保存()使用函数 save()
直到这里看起来一切正常,因为如果我使用 storage.count 打印我的存储中有多少数据,如果我打印从 json 文件读取的数据并传递到我的存储数组,则数据量会增加,所有数据都是在那里。
一旦我按下按钮并显示所有从 json 准备好的数据,我希望在 swiftUI 中更新我的列表
为了调试,我尝试创建一个通过 2 个文本框和 save() 加载数据的函数 .. 这工作正常,我添加了我的新值,保存和列表自动更新。
这是我的数据模型
import Foundation
class DataModel:Identifiable , Codable
var nameApt : String
var icaoCode : String
init(nameApt: String, icaoCode: String)
self.nameApt = nameApt
self.icaoCode = icaoCode
这是我的数据管理器
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())
【问题讨论】:
我在open函数里面使用crea data函数解决了。 【参考方案1】:我通过在函数 open 中使用函数 crea data 解决了
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")
【讨论】:
以上是关于使用本地 json 文件中的数据更新 swift UI 中的列表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用从 Swift 3 中的滑块中选择的 JSON 数据更新 tableviewcell?
Swift .writeToFile 不会更新 mainBundle 中的 JSON 文件
iOS Swift - URLSessionDataTask 在刷新时没有得到更新的 JSON 数据