Replace lazy AppStorage calls with AccountManager

This commit is contained in:
2025-04-25 14:26:05 +02:00
parent d3143915ea
commit 351f08e43e
16 changed files with 392 additions and 270 deletions
+84
View File
@@ -0,0 +1,84 @@
//
// AccountManager.swift
// meterios
//
// (c) 2025 Martin "maride" Dessauer
//
import Foundation
import SwiftUI
/// **AccountManager** stores connection details and the corresponding client
class AccountManager: ObservableObject {
// default contains a ready-to-use instance of AccountManager, read from AppStorage
static public var `default` = AccountManager()
// accounts holds all saved accounts
@Published private(set) var Accounts: Array<AccountManagerEntry> = []
// init creates a new AccountManager, reading saved account data from AppStorage
init() {
self.Accounts = AccountManager.readFromRaw()
}
// readFromRaw reads the current accounts from the stored data and transforms it to a handy Account Array
static private func readFromRaw() -> Array<AccountManagerEntry> {
@AppStorage("accounts") var rawAccs = Data()
do {
let simpleAccs = try JSONDecoder().decode([Account].self, from: rawAccs)
let richAccs = simpleAccs.map({ AccountManagerEntry($0) })
return richAccs
} catch {
print("Error parsing stored accounts from JSON: \(error)")
return []
}
}
// writeToRaw writes the current account data to the AppStorage
private func writeToRaw() {
@AppStorage("accounts") var rawAccs = Data()
do {
let simpleAccs = Accounts.map({ $0.GetAccount() })
rawAccs = try JSONEncoder().encode(simpleAccs)
} catch {
print("Error writing current accounts to JSON: \(error)")
}
}
// CurrentAccount returns the currently selected account if there is one
func CurrentAccount() -> AccountManagerEntry? {
if self.Accounts.count > 0 {
return self.Accounts.first
}
return nil
}
// AddAccount adds the given account if it doesn't exist yet
func AddAccount(_ account: Account) {
if IndexOfAccount(account) == nil {
Accounts.append(AccountManagerEntry(account))
writeToRaw()
}
}
// IndexOfAccount returns the index of the specified account identified by address and user ID
func IndexOfAccount(_ account: Account) -> Int? {
return Accounts.firstIndex(where: {
$0.GetAccount().GetAddress() == account.GetAddress() &&
$0.GetAccount().GetUserID() == account.GetUserID()
})
}
// RemoveAccount removes the account specified by address and user ID of the given Account, if present
func RemoveAccount(_ account: Account) {
if IndexOfAccount(account) != nil {
Accounts.remove(at: IndexOfAccount(account)!)
writeToRaw()
}
}
// RemoveAccount removes the account specified by address and user ID of the given AccountManagerEntry, if present
func RemoveAccount(_ account: AccountManagerEntry) {
RemoveAccount(account.GetAccount())
}
}