From 33f7d15e2590d4e0eea89a1a936515518824dd00 Mon Sep 17 00:00:00 2001 From: Jorge Leandro Perez Date: Thu, 25 Jul 2024 14:42:05 -0300 Subject: [PATCH] Drops duplicated code --- Simplenote/AccountRemote.swift | 57 --------------------- Simplenote/LoginRemote.swift | 46 ----------------- Simplenote/LoginRemoteProtocol.swift | 12 ----- Simplenote/Remote.swift | 75 ---------------------------- Simplenote/RemoteConstants.swift | 12 ----- Simplenote/RemoteError.swift | 42 ---------------- Simplenote/SignupRemote.swift | 27 ---------- Simplenote/URLSessionProtocol.swift | 9 ---- 8 files changed, 280 deletions(-) delete mode 100644 Simplenote/AccountRemote.swift delete mode 100644 Simplenote/LoginRemote.swift delete mode 100644 Simplenote/LoginRemoteProtocol.swift delete mode 100644 Simplenote/Remote.swift delete mode 100644 Simplenote/RemoteConstants.swift delete mode 100644 Simplenote/RemoteError.swift delete mode 100644 Simplenote/SignupRemote.swift delete mode 100644 Simplenote/URLSessionProtocol.swift diff --git a/Simplenote/AccountRemote.swift b/Simplenote/AccountRemote.swift deleted file mode 100644 index a908f0087..000000000 --- a/Simplenote/AccountRemote.swift +++ /dev/null @@ -1,57 +0,0 @@ -import Foundation - -// MARK: - AccountVerificationRemote -// -class AccountRemote: Remote { - // MARK: Performing tasks - - /// Send verification request for specified email address - /// - func verify(email: String, completion: @escaping (_ result: Result) -> Void) { - let request = verificationURLRequest(with: email)! - - performDataTask(with: request, completion: completion) - } - - /// Send account deletion request for user - /// - func requestDelete(_ user: SPUser, completion: @escaping (_ result: Result) -> Void) { - let request = deleteRequest(with: user)! - - performDataTask(with: request, completion: completion) - } - - // MARK: URL Requests - - private func verificationURLRequest(with email: String) -> URLRequest? { - guard let base64EncodedEmail = email.data(using: .utf8)?.base64EncodedString() else { - return nil - } - - let verificationURL = URL(string: SimplenoteConstants.simplenoteVerificationURL)! - var request = URLRequest(url: verificationURL.appendingPathComponent(base64EncodedEmail), - cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, - timeoutInterval: RemoteConstants.timeout) - request.httpMethod = RemoteConstants.Method.GET - - return request - } - - private func deleteRequest(with user: SPUser) -> URLRequest? { - let url = URL(string: SimplenoteConstants.accountDeletionURL)! - - var request = URLRequest(url: url, - cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, - timeoutInterval: RemoteConstants.timeout) - request.httpMethod = RemoteConstants.Method.POST - request.setValue("application/json", forHTTPHeaderField: "Content-Type") - - let body = [ - "username": user.email.lowercased(), - "token": user.authToken - ] - request.httpBody = try? JSONEncoder().encode(body) - - return request - } -} diff --git a/Simplenote/LoginRemote.swift b/Simplenote/LoginRemote.swift deleted file mode 100644 index bcbd5b0bf..000000000 --- a/Simplenote/LoginRemote.swift +++ /dev/null @@ -1,46 +0,0 @@ -import Foundation - -// MARK: - LoginRemote -// -class LoginRemote: Remote { - - func requestLoginEmail(email: String) async throws { - let request = requestForLoginRequest(email: email) - try await performDataTask(with: request) - } - - func requestLoginConfirmation(email: String, authCode: String) async throws -> LoginConfirmationResponse { - let request = requestForLoginCompletion(email: email, authCode: authCode) - return try await performDataTask(with: request, type: LoginConfirmationResponse.self) - } -} - - -// MARK: - LoginConfirmationResponse -// -struct LoginConfirmationResponse: Codable, Equatable { - let username: String - let syncToken: String -} - - -// MARK: - Private API(s) -// -private extension LoginRemote { - - func requestForLoginRequest(email: String) -> URLRequest { - let url = URL(string: SimplenoteConstants.loginRequestURL)! - return requestForURL(url, method: RemoteConstants.Method.POST, httpBody: [ - "request_source": SimplenoteConstants.simplenotePlatformName, - "username": email.lowercased() - ]) - } - - func requestForLoginCompletion(email: String, authCode: String) -> URLRequest { - let url = URL(string: SimplenoteConstants.loginCompletionURL)! - return requestForURL(url, method: RemoteConstants.Method.POST, httpBody: [ - "username": email, - "auth_code": authCode - ]) - } -} diff --git a/Simplenote/LoginRemoteProtocol.swift b/Simplenote/LoginRemoteProtocol.swift deleted file mode 100644 index 25da99396..000000000 --- a/Simplenote/LoginRemoteProtocol.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - - -// MARK: - LoginRemoteProtocol -// -protocol LoginRemoteProtocol { - func requestLoginEmail(email: String) async throws - func requestLoginConfirmation(email: String, authCode: String) async throws -> LoginConfirmationResponse -} - - -extension LoginRemote: LoginRemoteProtocol { } diff --git a/Simplenote/Remote.swift b/Simplenote/Remote.swift deleted file mode 100644 index ebbe09ec2..000000000 --- a/Simplenote/Remote.swift +++ /dev/null @@ -1,75 +0,0 @@ -import Foundation - - -class Remote { - private let urlSession: URLSessionProtocol - - init(urlSession: URLSessionProtocol = URLSession.shared) { - self.urlSession = urlSession - } - - /// Send task for remote - /// Sublcassing Notes: To be able to send a task it is required to first setup the URL request for the task to use - /// - func performDataTask(with request: URLRequest, completion: @escaping (_ result: Result) -> Void) { - let dataTask = urlSession.dataTask(with: request) { (data, response, dataTaskError) in - DispatchQueue.main.async { - - if let error = RemoteError(statusCode: response?.responseStatusCode ?? .zero, error: dataTaskError) { - completion(.failure(error)) - return - } - - completion(.success(data)) - } - } - - dataTask.resume() - } - - /// Performs a URLSession Data Task - /// - @discardableResult - func performDataTask(with request: URLRequest) async throws -> Data { - let (data, response) = try await urlSession.data(for: request, delegate: nil) - - if let error = RemoteError(statusCode: response.responseStatusCode) { - throw error - } - - return data - } - - /// Performs a URLSession Data Task, and decodes a given Type - /// - func performDataTask(with request: URLRequest, type: T.Type) async throws -> T { - let data = try await performDataTask(with: request) - - let decoder = JSONDecoder() - decoder.keyDecodingStrategy = .convertFromSnakeCase - return try decoder.decode(type, from: data) - } - - /// Builds a URLRequest for the specified URL / Method / params - /// - func requestForURL(_ url: URL, method: String, httpBody: [String: String]?) -> URLRequest { - var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: RemoteConstants.timeout) - - request.httpMethod = method - request.setValue("application/json", forHTTPHeaderField: "Content-Type") - - if let httpBody { - request.httpBody = try? JSONEncoder().encode(httpBody) - } - - return request - } -} - - -extension URLResponse { - - var responseStatusCode: Int { - (self as? HTTPURLResponse)?.statusCode ?? .zero - } -} diff --git a/Simplenote/RemoteConstants.swift b/Simplenote/RemoteConstants.swift deleted file mode 100644 index 4a081c0c2..000000000 --- a/Simplenote/RemoteConstants.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -// MARK: Remote Constants -// -struct RemoteConstants { - struct Method { - static let GET = "GET" - static let POST = "POST" - } - - static let timeout: TimeInterval = 30 -} diff --git a/Simplenote/RemoteError.swift b/Simplenote/RemoteError.swift deleted file mode 100644 index e0a6935b5..000000000 --- a/Simplenote/RemoteError.swift +++ /dev/null @@ -1,42 +0,0 @@ -import Foundation - -enum RemoteError: Error { - case network - case requestError(Int, Error?) -} - -extension RemoteError { - - init?(statusCode: Int, error: Error? = nil) { - if statusCode / 100 == 2 { - return nil - } - - self = statusCode > 0 ? .requestError(statusCode, error) : .network - } -} - - -extension RemoteError { - var statusCode: Int { - switch self { - case .requestError(let statusCode, _): - return statusCode - default: - return .zero - } - } -} - -extension RemoteError: Equatable { - static func == (lhs: RemoteError, rhs: RemoteError) -> Bool { - switch (lhs, rhs) { - case (.network, .network): - return true - case (.requestError(let lhsStatus, let lhsError), .requestError(let rhsStatus, let rhsError)): - return lhsStatus == rhsStatus && lhsError?.localizedDescription == rhsError?.localizedDescription - default: - return false - } - } -} diff --git a/Simplenote/SignupRemote.swift b/Simplenote/SignupRemote.swift deleted file mode 100644 index f41c5a2b2..000000000 --- a/Simplenote/SignupRemote.swift +++ /dev/null @@ -1,27 +0,0 @@ -import Foundation - -// MARK: - SignupRemote -// -class SignupRemote: Remote { - - /// Send signup request for specified email address - /// - func requestSignup(email: String, completion: @escaping (_ result: Result) -> Void) { - let requestURL = request(with: email)! - - performDataTask(with: requestURL, completion: completion) - } - - private func request(with email: String) -> URLRequest? { - let url = URL(string: SimplenoteConstants.simplenoteRequestSignupURL)! - - var request = URLRequest(url: url, - cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, - timeoutInterval: RemoteConstants.timeout) - request.httpMethod = RemoteConstants.Method.POST - request.setValue("application/json", forHTTPHeaderField: "Content-Type") - request.httpBody = try? JSONEncoder().encode(["username": email.lowercased()]) - - return request - } -} diff --git a/Simplenote/URLSessionProtocol.swift b/Simplenote/URLSessionProtocol.swift deleted file mode 100644 index 5e2af7b21..000000000 --- a/Simplenote/URLSessionProtocol.swift +++ /dev/null @@ -1,9 +0,0 @@ -import Foundation - - -protocol URLSessionProtocol { - func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionDataTask - func data(for request: URLRequest, delegate: (any URLSessionTaskDelegate)?) async throws -> (Data, URLResponse) -} - -extension URLSession: URLSessionProtocol { }