Files
RippleChat/RippleChat/DataStore.swift
2023-07-13 17:18:10 +02:00

136 lines
4.1 KiB
Swift

//
// DataStore.swift
// RippleChat
//
// Created by Severin Memmishofer on 11.07.23.
//
import SwiftUI
import Foundation
@MainActor
class DataStore: ObservableObject {
typealias FID = String
typealias SEQ = Int
@Published var personalID: String
@Published var personalFeed: Feed
@Published var friends: [FID:SEQ]
@Published var feedStores: [FeedStore]
init(personalID: String = "", personalFeed: Feed = Feed(), friends: [String:Int] = [:], feedStores: [FeedStore] = []) {
self.personalID = personalID
self.friends = friends
self.feedStores = feedStores
self.personalFeed = personalFeed
}
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")
guard let data = try? Data(contentsOf: fileURL) else {
return ""
}
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")
guard let data = try? Data(contentsOf: fileURL) else {
return [:]
}
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
}
func savePersonalFeed() async throws {
let task = Task {
let data = try JSONEncoder().encode(personalFeed)
let outfile = try fileURL(for: "personalFeed")
try data.write(to: outfile)
}
_ = try await task.value
}
func loadPersonalFeed() async throws {
let task = Task<Feed, Error> {
let fileURL = try self.fileURL(for: "personalFeed")
guard let data = try? Data(contentsOf: fileURL) else {
return Feed(feedID: self.personalID)
}
let personalFeed = try JSONDecoder().decode(Feed.self, from: data)
return personalFeed
}
let personalFeed = try await task.value
self.personalFeed = personalFeed
}
}
extension DataStore {
static let sampleDataStore = DataStore(personalID: "BOB", friends: SettingsView_Previews.friends, feedStores: [FeedStore(feed: Feed.sampleFeed), FeedStore(feed: Feed.sampleFeed2)])
}