[英]Saving data in Documents Directory in iOS, SwiftUI
我不知道如何在 SwiftUI 的文檔目錄中保存數據(多個屬性)。我知道兩種變體,第一種 - 當你有一個數組屬性並且效果很好時,這里的問題 - 我不知道如何添加其他屬性給它。 或者,為一個項目的每個屬性創建大約 3 個這樣的 swift-files 是正常的。
1 個變體,保存在文檔目錄中:
class Stack: ObservableObject {
@Published var cards: [Card]
static let saveKey = "SavedCards"
init() {
self.cards = []
if let data = loadFile() {
if let decoded = try? JSONDecoder().decode([Card].self, from: data) {
self.cards = decoded
return
}
}
}
func add(card: Card) {
cards.insert(card, at: 0)
save()
}
func save() {
if let encoded = try? JSONEncoder().encode(cards) {
saveFile(data: encoded)
}
}
private func saveFile(data: Data) {
let url = getDocumentsDirectory().appendingPathComponent(Self.saveKey)
do {
try data.write(to: url, options: [.atomicWrite, .completeFileProtection])
} catch let error {
print("Could not write data: " + error.localizedDescription)
}
}
func loadFile() -> Data? {
let url = getDocumentsDirectory().appendingPathComponent(Self.saveKey)
if let data = try? Data(contentsOf: url) {
return data
}
return nil
}
private func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
}
第二種變體是為每個屬性使用 CodingKeys。 但是我無法弄清楚如何在此處添加方法並在其他視圖中使用它,例如通過按下按鈕來保存數據。 似乎我必須在每個視圖中為每次數據更改一遍又一遍地編碼和解碼。 這似乎是錯誤的。
2 種帶編碼鍵的變體
class Profile: Codable, ObservableObject {
enum CodingKeys: CodingKey {
case categories, playedCards, playedRounds
}
@Published var categories: [Category] = [Category.red, .green, .blue, .yellow, .pink, .gray]
@Published var playedCards = 0
@Published var playedRounds = 0
init() { }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
categories = try container.decode([Category].self, forKey: .categories)
playedCards = try container.decode(Int.self, forKey: .playedCards)
playedRounds = try container.decode(Int.self, forKey: .playedRounds)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(categories, forKey: .categories)
try container.encode(playedCards, forKey: .playedCards)
try container.encode(playedRounds, forKey: .playedRounds)
}
}
所以我的問題是如何將 1 個變體與多個變量一起使用。 或者如果我應該使用第二個變體,我怎樣才能“很好地”編碼和解碼來自其他視圖的變量。
目前,我對第二個變體的解決方案是在 ContentView 中編寫標准的 decode() / encode() 方法,並在onDismiss: of Sheet Views 中使用它來保存來自不同屏幕的數據而不重復。
func loadData() {
let filename = getDocumentsDiretory().appendingPathComponent("SavedData")
do {
let data = try Data(contentsOf: filename)
profile = try JSONDecoder().decode(Profile.self, from: data)
} catch {
print("Unable to load saved profile data")
}
}
func saveData() {
do {
let filename = getDocumentsDiretory().appendingPathComponent("SavedData")
let data = try JSONEncoder().encode(self.profile)
try data.write(to: filename, options: [.atomic, .completeFileProtection])
} catch {
print("Unable to save profile data")
}
}
func getDocumentsDiretory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
.sheet(isPresented: $showingSheet, onDismiss: saveData) {
ProfileView()
}
.onAppear(perform: loadData)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.