generic Request code WIP

This commit is contained in:
Wilhelm Oks 2024-12-10 12:05:03 +01:00
parent 0822514a71
commit 1b81ee972e
5 changed files with 79 additions and 1 deletions

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -15,7 +15,8 @@ let package = Package(
// Targets are the basic building blocks of a package, defining a module or a test suite. // Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies. // Targets can depend on other targets in this package and products from dependencies.
.target( .target(
name: "SwiftDevRant"), name: "SwiftDevRant"
),
.testTarget( .testTarget(
name: "SwiftDevRantTests", name: "SwiftDevRantTests",
dependencies: ["SwiftDevRant"] dependencies: ["SwiftDevRant"]

View File

@ -0,0 +1,3 @@
struct DevRantBackend: Backend {
let baseURL = "https://devrant.com/api/"
}

View File

@ -0,0 +1,3 @@
public protocol Backend {
var baseURL: String { get }
}

View File

@ -0,0 +1,64 @@
import Foundation
public struct Request {
public enum Error<ApiError: Decodable & Sendable>: Swift.Error, CustomStringConvertible {
case notHttpResponse
case notFound
case apiError(_ error: ApiError)
case generalError
public var description: String {
switch self {
case .notHttpResponse: "response is not HTTP"
case .notFound: "Not found"
case .apiError(error: let error): "\(error)"
case .generalError: "General error"
}
}
}
struct EmptyError: Decodable {
}
public enum Method: String {
case get = "GET"
case post = "POST"
case put = "PUT"
case delete = "DELETE"
case patch = "PATCH"
}
public struct Config {
let method: Method
let backend: Backend
let path: String
var urlParameters: [String: String] = [:]
var headers: [String: String] = [:]
}
var session = URLSession(configuration: .ephemeral)
func makeURLRequest(config: Config, body: Data?) -> URLRequest {
let urlQuery = urlEncodedQueryString(from: config.urlParameters)
guard let url = URL(string: config.backend.baseURL + config.path + urlQuery) else {
fatalError("Couldn't create a URL")
}
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData)
urlRequest.httpMethod = config.method.rawValue
urlRequest.httpBody = body
config.headers.forEach {
urlRequest.setValue($0.value, forHTTPHeaderField: $0.key)
}
return urlRequest
}
func urlEncodedQueryString(from query: [String: String]) -> String {
guard !query.isEmpty else { return "" }
var components = URLComponents()
components.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) }
let absoluteString = components.url?.absoluteString ?? ""
let plusCorrection = absoluteString.replacingOccurrences(of: "+", with: "%2b")
return plusCorrection
}
}