162 lines
4.6 KiB
Swift
162 lines
4.6 KiB
Swift
//
|
|
// LocalDataInterface.swift
|
|
// Nextcloud Cookbook iOS Client
|
|
//
|
|
// Created by Vincent Meilinger on 07.05.24.
|
|
//
|
|
|
|
import Foundation
|
|
import SwiftUI
|
|
|
|
|
|
class LocalDataInterface: CookbookInterface {
|
|
var id: String
|
|
|
|
init(id: String) {
|
|
self.id = id
|
|
}
|
|
|
|
enum LocalDataPath {
|
|
case recipeStubs(category: String),
|
|
recipe(id: String),
|
|
image(id: String, size: RecipeImage.RecipeImageSize),
|
|
categories,
|
|
keywords
|
|
|
|
var path: String {
|
|
switch self {
|
|
case .recipe(let id):
|
|
"recipe_\(id).data"
|
|
case .recipeStubs(let category):
|
|
"recipes_\(category).data"
|
|
case .image(let id, let size):
|
|
if size == .FULL {
|
|
"image_\(id).data"
|
|
} else {
|
|
"thumb_\(id).data"
|
|
}
|
|
case .categories:
|
|
"categories.data"
|
|
case .keywords:
|
|
"keywords.data"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Local Read Interface
|
|
|
|
extension LocalDataInterface: ReadInterface {
|
|
|
|
func getImage(id: String, size: RecipeImage.RecipeImageSize) async -> (UIImage?, (any UserAlert)?) {
|
|
guard let data: String = await load(path: .image(id: id, size: size)) else {
|
|
return (nil, PersistenceAlert.LOAD_FAILED)
|
|
}
|
|
guard let dataDecoded = Data(base64Encoded: data) else { return (nil, PersistenceAlert.DECODING_FAILED) }
|
|
if let image = UIImage(data: dataDecoded) {
|
|
return (image, nil)
|
|
}
|
|
return (nil, nil)
|
|
}
|
|
|
|
func getRecipeStubs() async -> ([RecipeStub]?, (any UserAlert)?) {
|
|
return (nil, PersistenceAlert.LOAD_FAILED)
|
|
}
|
|
|
|
func getRecipe(id: String) async -> (Recipe?, (any UserAlert)?) {
|
|
if let recipe: Recipe? = await load(path: LocalDataPath.recipe(id: id)) {
|
|
return (recipe, nil)
|
|
}
|
|
return (nil, nil)
|
|
}
|
|
|
|
func getCategories() async -> ([Category]?, (any UserAlert)?) {
|
|
return (await load(path: LocalDataPath.categories), nil)
|
|
}
|
|
|
|
func getRecipeStubsForCategory(named categoryName: String) async -> ([RecipeStub]?, (any UserAlert)?) {
|
|
if let stubs: [RecipeStub] = await load(path: .recipeStubs(category: categoryName)) {
|
|
return (stubs, nil)
|
|
}
|
|
return (nil, PersistenceAlert.LOAD_FAILED)
|
|
}
|
|
|
|
func getTags() async -> ([RecipeKeyword]?, (any UserAlert)?) {
|
|
if let keywords: [RecipeKeyword] = await load(path: .keywords) {
|
|
return (keywords, nil)
|
|
}
|
|
return (nil, PersistenceAlert.LOAD_FAILED)
|
|
}
|
|
|
|
func getRecipesTagged(keyword: String) async -> ([RecipeStub]?, (any UserAlert)?) {
|
|
return (nil, PersistenceAlert.LOAD_FAILED)
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Local Write Interface
|
|
|
|
extension LocalDataInterface: WriteInterface {
|
|
|
|
func postImage(id: String, image: UIImage, size: RecipeImage.RecipeImageSize) async -> ((any UserAlert)?) {
|
|
if let data = image.pngData() {
|
|
await save(
|
|
data,
|
|
path: LocalDataPath.image(id: id, size: size)
|
|
)
|
|
}
|
|
}
|
|
|
|
func postRecipe(recipe: Recipe) async -> ((any UserAlert)?) {
|
|
await save(recipe, path: LocalDataPath.recipe(id: recipe.id))
|
|
return nil
|
|
}
|
|
|
|
func updateRecipe(recipe: Recipe) async -> ((any UserAlert)?) {
|
|
return await postRecipe(recipe: recipe)
|
|
}
|
|
|
|
func deleteRecipe(id: String) async -> ((any UserAlert)?) {
|
|
await delete(path: .recipe(id: id))
|
|
return nil
|
|
}
|
|
|
|
func renameCategory(named categoryName: String, newName: String) async -> ((any UserAlert)?) {
|
|
guard let stubs: [RecipeStub] = await load(path: .recipeStubs(category: categoryName)) else {
|
|
return PersistenceAlert.LOAD_FAILED
|
|
}
|
|
await delete(path: .recipeStubs(category: categoryName))
|
|
await save(stubs, path: .recipeStubs(category: newName))
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Local Data Interface Utils
|
|
|
|
extension LocalDataInterface {
|
|
|
|
func load<T: Codable>(path ldPath: LocalDataPath) async -> T? {
|
|
do {
|
|
return try await DataStore.shared.load(fromPath: ldPath.path)
|
|
} catch (let error) {
|
|
print(error)
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func save<T: Codable>(_ object: T, path ldPath: LocalDataPath) async {
|
|
await DataStore.shared.save(data: object, toPath: ldPath.path)
|
|
}
|
|
|
|
func delete(path ldPath: LocalDataPath) async {
|
|
DataStore.shared.delete(path: ldPath.path)
|
|
}
|
|
|
|
}
|