Add persistent storage
This commit is contained in:
parent
232d007686
commit
d218e9b600
@ -10,7 +10,9 @@ import CoreBluetooth
|
||||
|
||||
struct ContentView: View {
|
||||
@State var currentView = 0
|
||||
@StateObject var dataStore = DataStore()
|
||||
@EnvironmentObject var dataStore: DataStore
|
||||
@Environment(\.scenePhase) private var scenePhase
|
||||
let saveAction: ()->Void
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
@ -61,14 +63,16 @@ struct ContentView: View {
|
||||
}
|
||||
.frame(height: UIScreen.main.bounds.height * 0.05)
|
||||
}
|
||||
|
||||
.onChange(of: scenePhase) { phase in
|
||||
if phase == .inactive { saveAction() }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView()
|
||||
ContentView(saveAction: {})
|
||||
.environmentObject(DataStore())
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,16 +8,93 @@
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
@MainActor
|
||||
class DataStore: ObservableObject {
|
||||
@Published var personalID: String
|
||||
@Published var friends: [String]
|
||||
@Published var feeds: [Feed]
|
||||
@Published var friends: [String:Int]
|
||||
@Published var feedStores: [FeedStore]
|
||||
|
||||
init(personalID: String = "", friends: [String] = [], feeds: [Feed] = []) {
|
||||
init(personalID: String = "", friends: [String:Int] = [:], feedStores: [FeedStore] = []) {
|
||||
self.personalID = personalID
|
||||
self.friends = friends
|
||||
self.feeds = feeds
|
||||
self.feedStores = feedStores
|
||||
}
|
||||
|
||||
private func fileURL(for filename: String) throws -> URL {
|
||||
try FileManager.default.url(for: .documentDirectory,
|
||||
in: .userDomainMask,
|
||||
appropriateFor: nil,
|
||||
create: false)
|
||||
.appendingPathComponent("\(filename).json")
|
||||
}
|
||||
|
||||
func savePersonalID() async throws {
|
||||
let task = Task {
|
||||
let data = try JSONEncoder().encode(personalID)
|
||||
let outfile = try fileURL(for: "personalID")
|
||||
try data.write(to: outfile)
|
||||
}
|
||||
_ = try await task.value
|
||||
}
|
||||
|
||||
func saveFriends() async throws {
|
||||
let task = Task {
|
||||
let data = try JSONEncoder().encode(friends)
|
||||
let outfile = try fileURL(for: "friends")
|
||||
try data.write(to: outfile)
|
||||
}
|
||||
_ = try await task.value
|
||||
}
|
||||
|
||||
func loadPersonalID() async throws {
|
||||
let task = Task<String, Error> {
|
||||
let fileURL = try self.fileURL(for: "personalID")
|
||||
let data = try Data(contentsOf: fileURL)
|
||||
let personalID = try JSONDecoder().decode(String.self, from: data)
|
||||
return personalID
|
||||
}
|
||||
let personalID = try await task.value
|
||||
self.personalID = personalID
|
||||
}
|
||||
|
||||
func loadFriends() async throws {
|
||||
let task = Task<[String:Int], Error> {
|
||||
let fileURL = try self.fileURL(for: "friends")
|
||||
let data = try Data(contentsOf: fileURL)
|
||||
let friends = try JSONDecoder().decode([String:Int].self, from: data)
|
||||
return friends
|
||||
}
|
||||
let friends = try await task.value
|
||||
self.friends = friends
|
||||
}
|
||||
|
||||
func loadFeedStores() async throws {
|
||||
let task = Task<[FeedStore], Error> {
|
||||
var feedStores: [FeedStore] = []
|
||||
for feedStore in self.feedStores {
|
||||
try await feedStore.load()
|
||||
feedStores.append(feedStore)
|
||||
}
|
||||
return feedStores
|
||||
}
|
||||
let feedStores = try await task.value
|
||||
self.feedStores = feedStores
|
||||
}
|
||||
|
||||
func saveFeedStores() async throws {
|
||||
let task = Task {
|
||||
for feedStore in self.feedStores {
|
||||
try await feedStore.save(feed: feedStore.feed)
|
||||
}
|
||||
}
|
||||
_ = try await task.value
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension DataStore {
|
||||
static let sampleDataStore = DataStore(personalID: "BOB", friends: SettingsView_Previews.friends, feedStores: [FeedStore(feed: Feed.sampleFeed), FeedStore(feed: Feed.sampleFeed2)])
|
||||
}
|
||||
|
||||
@ -9,9 +9,32 @@ import SwiftUI
|
||||
|
||||
@main
|
||||
struct RippleChatApp: App {
|
||||
@StateObject private var dataStore = DataStore()
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
ContentView() {
|
||||
Task {
|
||||
do {
|
||||
try await dataStore.savePersonalID()
|
||||
try await dataStore.saveFriends()
|
||||
try await dataStore.saveFeedStores()
|
||||
} catch {
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
.environmentObject(dataStore)
|
||||
.task {
|
||||
do {
|
||||
try await dataStore.loadPersonalID()
|
||||
try await dataStore.loadFriends()
|
||||
try await dataStore.loadFeedStores()
|
||||
} catch {
|
||||
// Handle the error
|
||||
print("Error loading data: \(error)")
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,9 +22,9 @@ struct FeedListView: View {
|
||||
Button("Save Feed") {
|
||||
Task {
|
||||
do {
|
||||
for feed in feedStores {
|
||||
try await feed.save(feed: feed.feed)
|
||||
}
|
||||
try await DataStore.sampleDataStore.saveFriends()
|
||||
try await DataStore.sampleDataStore.savePersonalID()
|
||||
try await DataStore.sampleDataStore.saveFeedStores()
|
||||
} catch {
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
|
||||
@ -20,18 +20,24 @@ struct SettingsEditView: View {
|
||||
}
|
||||
}
|
||||
Section(header: Text("Friends")) {
|
||||
ForEach(dataStore.friends) { friend in
|
||||
Label(friend, systemImage: "person")
|
||||
ForEach(dataStore.friends.keys.sorted(), id: \.self) { friend in
|
||||
if let seq = dataStore.friends[friend] {
|
||||
Label("\(friend) - SEQ: \(seq)", systemImage: "person")
|
||||
}
|
||||
}
|
||||
.onDelete { indexSet in do {
|
||||
indexSet.forEach { index in
|
||||
let key = dataStore.friends.keys.sorted()[index]
|
||||
dataStore.friends.removeValue(forKey: key)
|
||||
}
|
||||
|
||||
}
|
||||
.onDelete {indices in
|
||||
dataStore.friends.remove(atOffsets: indices)
|
||||
}
|
||||
HStack {
|
||||
TextField("New Feed", text: $newFeedID)
|
||||
Button(action: {
|
||||
withAnimation {
|
||||
let feedid = newFeedID
|
||||
dataStore.friends.append(feedid)
|
||||
dataStore.friends[newFeedID] = 0
|
||||
newFeedID = ""
|
||||
}
|
||||
}) {
|
||||
|
||||
@ -22,8 +22,10 @@ struct SettingsView: View {
|
||||
Label(dataStore.personalID, systemImage: "person.crop.circle")
|
||||
}
|
||||
Section(header: Text("Friends")) {
|
||||
ForEach(dataStore.friends) { friend in
|
||||
Label(friend, systemImage: "person")
|
||||
ForEach(dataStore.friends.keys.sorted(), id: \.self) { friend in
|
||||
if let seq = dataStore.friends[friend] {
|
||||
Label("\(friend) - SEQ: \(seq)", systemImage: "person")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,9 +64,9 @@ struct SettingsView: View {
|
||||
|
||||
struct SettingsView_Previews: PreviewProvider {
|
||||
static var friends = [
|
||||
"BOS",
|
||||
"ALI",
|
||||
"CYN"
|
||||
"BOS":1,
|
||||
"ALI":2,
|
||||
"CYN":3
|
||||
]
|
||||
static var previews: some View {
|
||||
SettingsView()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user