Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,36 @@ import Foundation
enum RumContactUsError: Error {
case networkError
case decodingError
case invalidResponse

var localizedDescription: String {
switch self {
case .networkError:
return "Erro de rede."
case .decodingError:
return "Falha ao decodificar os dados."
case .invalidResponse:
return "Resposta inválida."
}
}

var shouldDismiss: Bool {
switch self {
case .networkError, .decodingError:
return false
case .invalidResponse:
return true
}
}

var logMessage: String {
switch self {
case .networkError:
return "Network error: unable to reach the server."
return "Network error."
case .decodingError:
return "Decoding error: failed to parse the response data."
return "Decoding error: Failed to decode data."
case .invalidResponse:
return "Invalid response from server."
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,33 @@ protocol RumContactUsAPIServiceDelegate: AnyObject {
}

protocol RumContactAPIServicing {
func fetchContactUsData() async -> ContactUsModel
func sendMessage(parameters: [String: String]) async
func fetchContactUsData() async throws -> ContactUsModel
func sendMessage(parameters: [String: String]) async throws
}

final class RumContactUsAPIService: RumContactAPIServicing {
weak var delegate: RumContactUsAPIServiceDelegate?
private let network: Networking

func fetchContactUsData() async -> ContactUsModel {
init(delegate: RumContactUsAPIServiceDelegate? = nil, network: Networking = AF.shared) {
self.delegate = delegate
self.network = network
}

func fetchContactUsData() async throws -> ContactUsModel {
let url = Endpoints.contactUs
return await withCheckedContinuation { continuation in
AF.shared.request(url, method: .get, parameters: nil, headers: nil) { [weak self] response in
network.request(url, method: .get, parameters: nil, headers: nil) { [weak self] response in
guard let self = self else { return }
switch response {
case .success(let data):
guard let contactUsModel = self.decodeContactUsData(data) else { return }
continuation.resume(returning: contactUsModel)
if let contactUsModel = self.decodeContactUsData(data) {
continuation.resume(returning: contactUsModel)
} else {
self.handleError(.decodingError)
}
case .failure(_):
self.logError(error: .networkError)
self.delegate?.showAlertMessage(
title: "Ops..",
message: "Ocorreu algum erro",
shouldDismiss: true)
handleError(.networkError)
}
}
}
Expand All @@ -50,28 +55,47 @@ final class RumContactUsAPIService: RumContactAPIServicing {
}
}

func sendMessage(parameters: [String: String]) async {
func sendMessage(parameters: [String: String]) async throws {
let url = Endpoints.sendMessage
return await withCheckedContinuation { continuation in
AF.shared.request(url, method: .post, parameters: parameters, headers: nil) { response in
network.request(url, method: .post, parameters: parameters, headers: nil) { [weak self] response in
guard let self = self else { return }
switch response {
case .success:
self.delegate?.showAlertMessage(
title: "Sucesso..",
message: "Sua mensagem foi enviada",
shouldDismiss: true
)
self.handleSuccess()
case .failure(_):
self.logError(error: .networkError)
self.delegate?.showAlertMessage(
title: "Ops..",
message: "Ocorreu algum erro",
shouldDismiss: false)
self.handleError(.networkError)
}
}
}
}

private func handleError(_ error: RumContactUsError) {
logError(error: error)

let alertTitle = "Ops..."
let alertMessage = error.localizedDescription
let shouldDismiss = error.shouldDismiss

delegate?.showAlertMessage(
title: alertTitle,
message: alertMessage,
shouldDismiss: shouldDismiss
)
}

private func handleSuccess() {
let alertTitle = "Sucesso..."
let alertMessage = "Sua mensagem foi enviada"
let shouldDismiss = true

delegate?.showAlertMessage(
title: alertTitle,
message: alertMessage,
shouldDismiss: shouldDismiss
)
}

private func logError(error: RumContactUsError) {
print("Log error: \(error.logMessage)")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// RumContactUsFactory.swift
// CleanCode
//
// Created by Rayana Prata Neves on 22/02/25.
//

import UIKit

enum RumContactUsFactory {
static func make() -> UIViewController {
let service = RumContactUsAPIService()
let viewController = RumContactUsViewController(service: service)
service.delegate = viewController
viewController.modalPresentationStyle = .fullScreen
viewController.modalTransitionStyle = .coverVertical
return viewController
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,34 @@ final class RumContactUsViewController: LoadingInheritageController {
func fetchData() {
showLoadingView()
Task {
self.model = await contactUsService.fetchContactUsData()
self.model = try await contactUsService.fetchContactUsData()
removeLoadingView()
}
}

@objc func didTapSendMessageButton() {
view.endEditing(true)
let email = model?.mail ?? ""
if let message = contactUsView.textView.text, contactUsView.textView.text.count > 0 {
let parameters: [String: String] = [
"email": email,
"mensagem": message
]
sendMessage(parameters: parameters)
}
guard let message = validatedMessage() else { return }
let parameters = createMessageParameters(email: model?.mail ?? "", message: message)
sendMessage(parameters: parameters)
}

private func validatedMessage() -> String? {
guard let message = contactUsView.textView.text, !message.isEmpty else { return nil }
return message
}

private func createMessageParameters(email: String, message: String) -> [String: String] {
return [
"email": email,
"mensagem": message
]
}

private func sendMessage(parameters: [String: String]) {
showLoadingView()
Task {
await contactUsService.sendMessage(parameters: parameters)
try await contactUsService.sendMessage(parameters: parameters)
removeLoadingView()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,8 @@ class RumResetPasswordViewController: UIViewController {
}

@IBAction func helpButton(_ sender: Any) {
let service = RumContactUsAPIService()
let vc = RumContactUsViewController(service: service)
service.delegate = vc
vc.modalPresentationStyle = .fullScreen
vc.modalTransitionStyle = .coverVertical
self.present(vc, animated: true, completion: nil)
let contactUsViewController = RumContactUsFactory.make()
self.present(contactUsViewController, animated: true, completion: nil)
}

@IBAction func createAccountButton(_ sender: Any) {
Expand Down