Networking rework: simplified API calls.
This commit is contained in:
@@ -15,6 +15,7 @@ import UIKit
|
||||
@Published var recipes: [String: [Recipe]] = [:]
|
||||
private var recipeDetails: [Int: RecipeDetail] = [:]
|
||||
private var imageCache: [Int: RecipeImage] = [:]
|
||||
private var requestQueue: [RequestWrapper] = []
|
||||
|
||||
let dataStore: DataStore
|
||||
var apiController: APIController? = nil
|
||||
@@ -206,17 +207,34 @@ import UIKit
|
||||
self.recipes = [:]
|
||||
self.imageCache = [:]
|
||||
self.recipeDetails = [:]
|
||||
self.requestQueue = []
|
||||
}
|
||||
}
|
||||
|
||||
func deleteRecipe(withId id: Int, categoryName: String) {
|
||||
func deleteRecipe(withId id: Int, categoryName: String) async -> RequestAlert {
|
||||
let request = RequestWrapper.customRequest(
|
||||
method: .DELETE,
|
||||
path: .RECIPE_DETAIL(recipeId: id),
|
||||
headerFields: [
|
||||
HeaderField.accept(value: .JSON),
|
||||
HeaderField.ocsRequest(value: true)
|
||||
]
|
||||
)
|
||||
|
||||
let path = "recipe\(id).data"
|
||||
dataStore.delete(path: path)
|
||||
guard recipes[categoryName] != nil else { return }
|
||||
recipes[categoryName]!.removeAll(where: { recipe in
|
||||
recipe.recipe_id == id ? true : false
|
||||
})
|
||||
recipeDetails.removeValue(forKey: id)
|
||||
if recipes[categoryName] != nil {
|
||||
recipes[categoryName]!.removeAll(where: { recipe in
|
||||
recipe.recipe_id == id ? true : false
|
||||
})
|
||||
recipeDetails.removeValue(forKey: id)
|
||||
}
|
||||
if await sendRequest(request) {
|
||||
return .REQUEST_SUCCESS
|
||||
} else {
|
||||
requestQueue.append(request)
|
||||
return .REQUEST_DELAYED
|
||||
}
|
||||
}
|
||||
|
||||
func checkServerConnection() async -> Bool {
|
||||
@@ -234,6 +252,54 @@ import UIKit
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func uploadRecipe(recipeDetail: RecipeDetail, createNew: Bool) async -> RequestAlert {
|
||||
var path: RequestPath? = nil
|
||||
if createNew {
|
||||
path = .NEW_RECIPE
|
||||
} else if let recipeId = Int(recipeDetail.id) {
|
||||
path = .RECIPE_DETAIL(recipeId: recipeId)
|
||||
}
|
||||
|
||||
guard let path = path else { return .REQUEST_DROPPED }
|
||||
|
||||
let request = RequestWrapper.customRequest(
|
||||
method: createNew ? .POST : .PUT,
|
||||
path: path,
|
||||
headerFields: [
|
||||
HeaderField.accept(value: .JSON),
|
||||
HeaderField.ocsRequest(value: true),
|
||||
HeaderField.contentType(value: .JSON)
|
||||
],
|
||||
body: JSONEncoder.safeEncode(recipeDetail)
|
||||
)
|
||||
|
||||
if await sendRequest(request) {
|
||||
return .REQUEST_SUCCESS
|
||||
} else {
|
||||
requestQueue.append(request)
|
||||
return .REQUEST_DELAYED
|
||||
}
|
||||
}
|
||||
|
||||
func sendRequest(_ request: RequestWrapper) async -> Bool {
|
||||
guard let apiController = apiController else { return false }
|
||||
let (data, _): (Data?, Error?) = await apiController.sendDataRequest(request)
|
||||
guard let data = data else { return false }
|
||||
do {
|
||||
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
|
||||
if let recipeId = json as? Int {
|
||||
return true
|
||||
} else if let message = json as? [String : Any] {
|
||||
print("Server message: ", message["msg"] ?? "-")
|
||||
return false
|
||||
}
|
||||
// TODO: Better error handling (Show error to user!)
|
||||
} catch {
|
||||
print("Could not decode server response")
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -82,74 +82,32 @@ import SwiftUI
|
||||
return true
|
||||
}
|
||||
|
||||
func uploadNewRecipe() {
|
||||
func uploadNewRecipe() async -> RequestAlert {
|
||||
print("Uploading new recipe.")
|
||||
waitingForUpload = true
|
||||
createRecipe()
|
||||
guard recipeValid() else { return }
|
||||
let request = RequestWrapper.customRequest(
|
||||
method: .POST,
|
||||
path: .NEW_RECIPE,
|
||||
headerFields: [
|
||||
HeaderField.accept(value: .JSON),
|
||||
HeaderField.ocsRequest(value: true),
|
||||
HeaderField.contentType(value: .JSON)
|
||||
],
|
||||
body: JSONEncoder.safeEncode(self.recipe)
|
||||
)
|
||||
sendRequest(request)
|
||||
dismissEditView()
|
||||
guard recipeValid() else { return .REQUEST_DROPPED }
|
||||
|
||||
return await mainViewModel.uploadRecipe(recipeDetail: self.recipe, createNew: true)
|
||||
}
|
||||
|
||||
func uploadEditedRecipe() {
|
||||
func uploadEditedRecipe() async -> RequestAlert {
|
||||
waitingForUpload = true
|
||||
print("Uploading changed recipe.")
|
||||
guard let recipeId = Int(recipe.id) else { return }
|
||||
guard let recipeId = Int(recipe.id) else { return .REQUEST_DROPPED }
|
||||
createRecipe()
|
||||
let request = RequestWrapper.customRequest(
|
||||
method: .PUT,
|
||||
path: .RECIPE_DETAIL(recipeId: recipeId),
|
||||
headerFields: [
|
||||
HeaderField.accept(value: .JSON),
|
||||
HeaderField.ocsRequest(value: true),
|
||||
HeaderField.contentType(value: .JSON)
|
||||
],
|
||||
body: JSONEncoder.safeEncode(self.recipe)
|
||||
)
|
||||
sendRequest(request)
|
||||
dismissEditView()
|
||||
|
||||
return await mainViewModel.uploadRecipe(recipeDetail: self.recipe, createNew: false)
|
||||
}
|
||||
|
||||
func deleteRecipe() {
|
||||
guard let recipeId = Int(recipe.id) else { return }
|
||||
let request = RequestWrapper.customRequest(
|
||||
method: .DELETE,
|
||||
path: .RECIPE_DETAIL(recipeId: recipeId),
|
||||
headerFields: [
|
||||
HeaderField.accept(value: .JSON),
|
||||
HeaderField.ocsRequest(value: true)
|
||||
]
|
||||
)
|
||||
sendRequest(request)
|
||||
if let recipeIdInt = Int(recipe.id) {
|
||||
mainViewModel.deleteRecipe(withId: recipeIdInt, categoryName: recipe.recipeCategory)
|
||||
func deleteRecipe() async -> RequestAlert {
|
||||
guard let id = Int(recipe.id) else {
|
||||
return .REQUEST_DROPPED
|
||||
}
|
||||
dismissEditView()
|
||||
return await mainViewModel.deleteRecipe(withId: id, categoryName: recipe.recipeCategory)
|
||||
}
|
||||
|
||||
func sendRequest(_ request: RequestWrapper) {
|
||||
Task {
|
||||
guard let apiController = mainViewModel.apiController else { return }
|
||||
let (data, _): (Data?, Error?) = await apiController.sendDataRequest(request)
|
||||
guard let data = data else { return }
|
||||
do {
|
||||
let error = try JSONDecoder().decode(ServerMessage.self, from: data)
|
||||
// TODO: Better error handling (Show error to user!)
|
||||
} catch {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func dismissEditView() {
|
||||
Task {
|
||||
|
||||
Reference in New Issue
Block a user