WIP - Complete App refactoring

This commit is contained in:
VincentMeilinger
2025-05-26 15:52:24 +02:00
parent 29fd3c668b
commit 5acf3b9c4f
49 changed files with 1996 additions and 543 deletions

View File

@@ -6,3 +6,40 @@
//
import Foundation
@Observable
class AccountManager {
var accounts: [any Account] = []
var authTokens: [String: String] = [:]
/// Save account as JSON.
func save(account: any Account, authToken: String?) async throws {
account.saveTokenToKeychain(authToken!)
let data = try JSONEncoder().encode(account)
let accountDir = account.accountType.rawValue + "/" + account.id.uuidString + "/account.json"
await DataStore.shared.save(data: data, toPath: accountDir)
}
/// Load accounts from JSON files.
func loadAccounts() async throws {
// Read data from file or user defaults
for accountType in AccountType.allCases {
// List all account UUIDs under the /accountType directory
let accountUUIDs = DataStore.shared.listAllFolders(dir: accountType.rawValue + "/")
// Decode each account and fetch the authToken
for accountUUID in accountUUIDs {
do {
guard let account = try await DataStore.shared.loadDynamic(fromPath: accountType.rawValue + "/" + accountUUID + "/account.json", type: accountType.accountType) else {
continue
}
authTokens[accountUUID] = (account as! any Account).getTokenFromKeychain() ?? ""
self.accounts.append(account as! (any Account))
} catch {
continue
}
}
}
}
}

View File

@@ -6,3 +6,44 @@
//
import Foundation
import SwiftUI
import KeychainSwift
enum AccountType: String, Codable, CaseIterable {
case cookbook = "cookbook"
case local = "local"
var accountType: any Decodable.Type {
switch self {
case .cookbook: return CookbookAccount.self
case .local: return LocalAccount.self
}
}
}
protocol Account: Codable, Identifiable {
/// A unique identifier for this account
var id: UUID { get }
/// A name for the account that can be displayed in the UI
var displayName: String { get }
/// For differentiating account types when decoding
var accountType: AccountType { get }
/// Base endpoint URL
var baseURL: URL { get }
/// Account username
var username: String { get }
/// For storing/retrieving tokens from Keychain
func saveTokenToKeychain(_ token: String)
func getTokenFromKeychain() -> String?
}

View File

@@ -1,5 +1,5 @@
//
// CookbookV1Account.swift
// CookbookAccount.swift
// Nextcloud Cookbook iOS Client
//
// Created by Vincent Meilinger on 24.01.25.
@@ -10,9 +10,10 @@ import KeychainSwift
struct CookbookAccount: Account {
let accountType: AccountType = .cookbook
let id: UUID
var displayName: String = "Nextcloud Cookbook Account"
let accountType: AccountType = .cookbook
let baseURL: URL
let username: String

View File

@@ -6,3 +6,23 @@
//
import Foundation
struct LocalAccount: Account {
let id: UUID
var displayName: String = "Local Account"
var accountType: AccountType = .local
let baseURL: URL = URL(filePath: "")!
let username: String = ""
/// Keychain convenience
func saveTokenToKeychain(_ token: String) {
return
}
func getTokenFromKeychain() -> String? {
return nil
}
}