diff --git a/.swiftpm/Networking.xctestplan b/.swiftpm/Networking.xctestplan
new file mode 100644
index 0000000..0f32567
--- /dev/null
+++ b/.swiftpm/Networking.xctestplan
@@ -0,0 +1,25 @@
+{
+ "configurations" : [
+ {
+ "id" : "1F7E75BB-2848-40A3-B102-03A60E30171E",
+ "name" : "Test Scheme Action",
+ "options" : {
+
+ }
+ }
+ ],
+ "defaultOptions" : {
+
+ },
+ "testTargets" : [
+ {
+ "parallelizable" : false,
+ "target" : {
+ "containerPath" : "container:",
+ "identifier" : "NetworkingTests",
+ "name" : "NetworkingTests"
+ }
+ }
+ ],
+ "version" : 1
+}
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
new file mode 100644
index 0000000..be718a8
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Package.swift b/Package.swift
index 4cbb066..b3c22ae 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,4 +1,4 @@
-// swift-tools-version:5.9
+// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
@@ -12,3 +12,10 @@ let package = Package(
.testTarget(name: "NetworkingTests", dependencies: ["Networking"])
]
)
+
+
+// TODO handle retries
+// Amy -> Use plain Sendable for json over JSON
+// Put back Combine tests
+// try out in real app (Swift 6)
+
diff --git a/Sources/Networking/Calls/JSON.swift b/Sources/Networking/Calls/JSON.swift
new file mode 100644
index 0000000..951ae32
--- /dev/null
+++ b/Sources/Networking/Calls/JSON.swift
@@ -0,0 +1,41 @@
+//
+// JSON.swift
+// Networking
+//
+// Created by Sacha Durand Saint Omer on 26/09/2024.
+//
+
+import Foundation
+
+public struct JSON: Sendable, CustomStringConvertible {
+
+ let array: [any Sendable]?
+ let dictionary: [String: any Sendable]?
+
+ init(jsonObject: Any) {
+ if let arr = jsonObject as? [Sendable] {
+ array = arr
+ dictionary = nil
+ } else if let dic = jsonObject as? [String: any Sendable] {
+ dictionary = dic
+ array = nil
+ } else {
+ array = nil
+ dictionary = nil
+ }
+ }
+
+ public var value: Any {
+ return array ?? dictionary ?? ""
+ }
+
+ public var description: String {
+ if let array = array {
+ return String(describing: array)
+ } else if let dictionary = dictionary {
+ return String(describing: dictionary)
+ }
+ return "empty"
+ }
+
+}
diff --git a/Sources/Networking/Calls/NetworkingClient+Data.swift b/Sources/Networking/Calls/NetworkingClient+Data.swift
index e912393..5154f97 100644
--- a/Sources/Networking/Calls/NetworkingClient+Data.swift
+++ b/Sources/Networking/Calls/NetworkingClient+Data.swift
@@ -6,62 +6,40 @@
//
import Foundation
-import Combine
-
-public extension NetworkingClient {
-
- func get(_ route: String, params: Params = Params()) -> AnyPublisher {
- request(.get, route, params: params).publisher()
- }
-
- func post(_ route: String, params: Params = Params()) -> AnyPublisher {
- request(.post, route, params: params).publisher()
- }
-
- func post(_ route: String, body: Encodable) -> AnyPublisher {
- request(.post, route, encodableBody: body).publisher()
- }
-
- func put(_ route: String, params: Params = Params()) -> AnyPublisher {
- request(.put, route, params: params).publisher()
- }
-
- func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
- request(.patch, route, params: params).publisher()
- }
-
- func patch(_ route: String, body: Encodable) -> AnyPublisher {
- request(.patch, route, encodableBody: body).publisher()
- }
-
- func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
- request(.delete, route, params: params).publisher()
- }
-}
public extension NetworkingClient {
func get(_ route: String, params: Params = Params()) async throws -> Data {
- try await request(.get, route, params: params).execute()
+ try await request(.get, route: route, params: params)
}
func post(_ route: String, params: Params = Params()) async throws -> Data {
- try await request(.post, route, params: params).execute()
+ try await request(.post, route: route, params: params)
}
- func post(_ route: String, body: Encodable) async throws -> Data {
- try await request(.post, route, encodableBody: body).execute()
+ func post(_ route: String, body: Encodable & Sendable) async throws -> Data {
+ try await request(.post, route: route, body: body)
}
func put(_ route: String, params: Params = Params()) async throws -> Data {
- try await request(.put, route, params: params).execute()
+ try await request(.put, route: route, params: params)
}
func patch(_ route: String, params: Params = Params()) async throws -> Data {
- try await request(.patch, route, params: params).execute()
+ try await request(.patch, route: route, params: params)
}
func delete(_ route: String, params: Params = Params()) async throws -> Data {
- try await request(.delete, route, params: params).execute()
+ try await request(.delete, route: route, params: params)
+ }
+
+ func request(_ httpMethod: HTTPMethod, route: String, params: Params = Params(), body: (Encodable & Sendable)? = nil) async throws -> Data {
+ try await beforeRequest(self)
+ let request = createRequest(httpMethod, route, params: params, body: body)
+ do {
+ return try await execute(request: request)
+ } catch {
+ throw mapError(error)
+ }
}
}
diff --git a/Sources/Networking/Calls/NetworkingClient+Decodable.swift b/Sources/Networking/Calls/NetworkingClient+Decodable.swift
index e48ff5b..6f52d31 100644
--- a/Sources/Networking/Calls/NetworkingClient+Decodable.swift
+++ b/Sources/Networking/Calls/NetworkingClient+Decodable.swift
@@ -6,139 +6,13 @@
//
import Foundation
-import Combine
-
-public extension NetworkingClient {
-
- func get(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher {
- return get(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- // Array version
- func get(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher where T: Collection {
- let keypath = keypath ?? defaultCollectionParsingKeyPath
- return get(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- func post(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher {
- return post(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- func post(_ route: String,
- body: Encodable,
- keypath: String? = nil
- ) -> AnyPublisher {
- return post(route, body: body)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- // Array version
- func post(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher where T: Collection {
- let keypath = keypath ?? defaultCollectionParsingKeyPath
- return post(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- func put(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher {
- return put(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- // Array version
- func put(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher where T: Collection {
- let keypath = keypath ?? defaultCollectionParsingKeyPath
- return put(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- func patch(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher {
- return patch(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
-
- func patch(_ route: String,
- body: Encodable,
- keypath: String? = nil
- ) -> AnyPublisher {
- return patch(route, body: body)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- // Array version
- func patch(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher where T: Collection {
- let keypath = keypath ?? defaultCollectionParsingKeyPath
- return patch(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- func delete(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher {
- return delete(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-
- // Array version
- func delete(_ route: String,
- params: Params = Params(),
- keypath: String? = nil) -> AnyPublisher where T: Collection {
- let keypath = keypath ?? defaultCollectionParsingKeyPath
- return delete(route, params: params)
- .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
- .receive(on: DispatchQueue.main)
- .eraseToAnyPublisher()
- }
-}
-
public extension NetworkingClient {
func get(_ route: String,
params: Params = Params(),
keypath: String? = nil) async throws -> T {
- let json: Any = try await get(route, params: params)
+ let json: JSON = try await get(route, params: params)
let model:T = try self.toModel(json, keypath: keypath)
return model
}
@@ -147,22 +21,22 @@ public extension NetworkingClient {
params: Params = Params(),
keypath: String? = nil) async throws -> T where T: Collection {
let keypath = keypath ?? defaultCollectionParsingKeyPath
- let json: Any = try await get(route, params: params)
+ let json: JSON = try await get(route, params: params)
return try self.toModel(json, keypath: keypath)
}
func post(_ route: String,
params: Params = Params(),
keypath: String? = nil) async throws -> T {
- let json: Any = try await post(route, params: params)
+ let json: JSON = try await post(route, params: params)
return try self.toModel(json, keypath: keypath)
}
func post(_ route: String,
- body: Encodable,
+ body: Encodable & Sendable,
keypath: String? = nil
) async throws -> T {
- let json: Any = try await post(route, body: body)
+ let json: JSON = try await post(route, body: body)
return try self.toModel(json, keypath: keypath)
}
@@ -170,14 +44,14 @@ public extension NetworkingClient {
params: Params = Params(),
keypath: String? = nil) async throws -> T where T: Collection {
let keypath = keypath ?? defaultCollectionParsingKeyPath
- let json: Any = try await post(route, params: params)
+ let json: JSON = try await post(route, params: params)
return try self.toModel(json, keypath: keypath)
}
func put(_ route: String,
params: Params = Params(),
keypath: String? = nil) async throws -> T {
- let json: Any = try await put(route, params: params)
+ let json: JSON = try await put(route, params: params)
return try self.toModel(json, keypath: keypath)
}
@@ -185,14 +59,14 @@ public extension NetworkingClient {
params: Params = Params(),
keypath: String? = nil) async throws -> T where T: Collection {
let keypath = keypath ?? defaultCollectionParsingKeyPath
- let json: Any = try await put(route, params: params)
+ let json: JSON = try await put(route, params: params)
return try self.toModel(json, keypath: keypath)
}
func patch(_ route: String,
params: Params = Params(),
keypath: String? = nil) async throws -> T {
- let json: Any = try await patch(route, params: params)
+ let json: JSON = try await patch(route, params: params)
return try self.toModel(json, keypath: keypath)
}
@@ -200,22 +74,22 @@ public extension NetworkingClient {
params: Params = Params(),
keypath: String? = nil) async throws -> T where T: Collection {
let keypath = keypath ?? defaultCollectionParsingKeyPath
- let json: Any = try await patch(route, params: params)
+ let json: JSON = try await patch(route, params: params)
return try self.toModel(json, keypath: keypath)
}
func patch(_ route: String,
- body: Encodable,
+ body: Encodable & Sendable,
keypath: String? = nil
) async throws -> T {
- let json: Any = try await patch(route, body: body)
+ let json: JSON = try await patch(route, body: body)
return try self.toModel(json, keypath: keypath)
}
func delete(_ route: String,
params: Params = Params(),
keypath: String? = nil) async throws -> T {
- let json: Any = try await delete(route, params: params)
+ let json: JSON = try await delete(route, params: params)
return try self.toModel(json, keypath: keypath)
}
@@ -223,7 +97,7 @@ public extension NetworkingClient {
params: Params = Params(),
keypath: String? = nil) async throws -> T where T: Collection {
let keypath = keypath ?? defaultCollectionParsingKeyPath
- let json: Any = try await delete(route, params: params)
+ let json: JSON = try await delete(route, params: params)
return try self.toModel(json, keypath: keypath)
}
}
diff --git a/Sources/Networking/Calls/NetworkingClient+JSON.swift b/Sources/Networking/Calls/NetworkingClient+JSON.swift
index 677b6db..032c8a3 100644
--- a/Sources/Networking/Calls/NetworkingClient+JSON.swift
+++ b/Sources/Networking/Calls/NetworkingClient+JSON.swift
@@ -6,90 +6,57 @@
//
import Foundation
-import Combine
public extension NetworkingClient {
-
- func get(_ route: String, params: Params = Params()) -> AnyPublisher {
- get(route, params: params).toJSON()
- }
-
- func post(_ route: String, params: Params = Params()) -> AnyPublisher {
- post(route, params: params).toJSON()
- }
- func post(_ route: String, body: Encodable) -> AnyPublisher {
- post(route, body: body).toJSON()
- }
-
- func put(_ route: String, params: Params = Params()) -> AnyPublisher {
- put(route, params: params).toJSON()
+ func get(_ route: String, params: Params = Params()) async throws -> Any {
+ let data = try await request(.get, route: route, params: params)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return json
}
- func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
- patch(route, params: params).toJSON()
+ func get(_ route: String, params: Params = Params()) async throws -> JSON {
+ return JSON(jsonObject: try await get(route, params: params))
}
- func patch(_ route: String, body: Encodable) -> AnyPublisher {
- patch(route, body: body).toJSON()
- }
-
- func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
- delete(route, params: params).toJSON()
- }
-}
-
-public extension NetworkingClient {
-
- func get(_ route: String, params: Params = Params()) async throws -> Any {
- let req = request(.get, route, params: params)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func post(_ route: String, params: Params = Params()) async throws -> JSON {
+ let data = try await request(.post, route: route, params: params)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
}
- func post(_ route: String, params: Params = Params()) async throws -> Any {
- let req = request(.post, route, params: params)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func post(_ route: String, body: Encodable & Sendable) async throws -> JSON {
+ let data = try await request(.post, route: route, body: body)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
}
- func post(_ route: String, body: Encodable) async throws -> Any {
- let req = request(.post, route, encodableBody: body)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func put(_ route: String, params: Params = Params()) async throws -> JSON {
+ let data = try await request(.put, route: route, params: params)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
}
- func put(_ route: String, params: Params = Params()) async throws -> Any {
- let req = request(.put, route, params: params)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func patch(_ route: String, params: Params = Params()) async throws -> Any {
+ let data = try await request(.patch, route: route, params: params)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return json
}
- func patch(_ route: String, params: Params = Params()) async throws -> Any {
- let req = request(.patch, route, params: params)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func patch(_ route: String, params: Params = Params()) async throws -> JSON {
+ return JSON(jsonObject: try await patch(route, params: params))
}
- func patch(_ route: String, body: Encodable) async throws -> Any {
- let req = request(.patch, route, encodableBody: body)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func patch(_ route: String, body: Encodable & Sendable) async throws -> JSON {
+ let data = try await request(.patch, route: route, body: body)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
}
- func delete(_ route: String, params: Params = Params()) async throws -> Any {
- let req = request(.delete, route, params: params)
- let data = try await req.execute()
- return try JSONSerialization.jsonObject(with: data, options: [])
+ func delete(_ route: String, params: Params = Params()) async throws -> JSON {
+ let data = try await request(.delete, route: route, params: params)
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
}
}
-// Data to JSON
-extension Publisher where Output == Data {
-
- public func toJSON() -> AnyPublisher {
- tryMap { data -> Any in
- return try JSONSerialization.jsonObject(with: data, options: [])
- }.eraseToAnyPublisher()
- }
-}
diff --git a/Sources/Networking/Calls/NetworkingClient+Requests.swift b/Sources/Networking/Calls/NetworkingClient+Requests.swift
index e891f5d..3e72c92 100644
--- a/Sources/Networking/Calls/NetworkingClient+Requests.swift
+++ b/Sources/Networking/Calls/NetworkingClient+Requests.swift
@@ -6,87 +6,46 @@
//
import Foundation
-import Combine
public extension NetworkingClient {
func getRequest(_ route: String, params: Params = Params()) -> NetworkingRequest {
- request(.get, route, params: params)
+ createRequest(.get, route, params: params)
}
func postRequest(_ route: String, params: Params = Params()) -> NetworkingRequest {
- request(.post, route, params: params)
+ createRequest(.post, route, params: params)
}
func putRequest(_ route: String, params: Params = Params()) -> NetworkingRequest {
- request(.put, route, params: params)
+ createRequest(.put, route, params: params)
}
func patchRequest(_ route: String, params: Params = Params()) -> NetworkingRequest {
- request(.patch, route, params: params)
+ createRequest(.patch, route, params: params)
}
func deleteRequest(_ route: String, params: Params = Params()) -> NetworkingRequest {
- request(.delete, route, params: params)
- }
-
- internal func request(_ httpMethod: HTTPMethod,
- _ route: String,
- params: Params = Params()
- ) -> NetworkingRequest {
- let req = NetworkingRequest()
- req.httpMethod = httpMethod
- req.route = route
- req.params = params
-
- let updateRequest = { [weak req, weak self] in
- guard let self = self else { return }
- req?.baseURL = self.baseURL
- req?.logLevel = self.logLevel
- req?.headers = self.headers
- req?.parameterEncoding = self.parameterEncoding
- req?.sessionConfiguration = self.sessionConfiguration
- req?.timeout = self.timeout
- }
- updateRequest()
- req.requestRetrier = { [weak self] in
- self?.requestRetrier?($0, $1)?
- .handleEvents(receiveOutput: { _ in
- updateRequest()
- })
- .eraseToAnyPublisher()
- }
- return req
+ createRequest(.delete, route, params: params)
}
- internal func request(_ httpMethod: HTTPMethod,
+ internal func createRequest(_ httpMethod: HTTPMethod,
_ route: String,
params: Params = Params(),
- encodableBody: Encodable? = nil
+ body: (Encodable & Sendable)? = nil
) -> NetworkingRequest {
- let req = NetworkingRequest()
- req.httpMethod = httpMethod
- req.route = route
- req.params = Params()
- req.encodableBody = encodableBody
-
- let updateRequest = { [weak req, weak self] in
- guard let self = self else { return }
- req?.baseURL = self.baseURL
- req?.logLevel = self.logLevel
- req?.headers = self.headers
- req?.parameterEncoding = self.parameterEncoding
- req?.sessionConfiguration = self.sessionConfiguration
- req?.timeout = self.timeout
- }
- updateRequest()
- req.requestRetrier = { [weak self] in
- self?.requestRetrier?($0, $1)?
- .handleEvents(receiveOutput: { _ in
- updateRequest()
- })
- .eraseToAnyPublisher()
- }
+ let req = NetworkingRequest(
+ method: httpMethod,
+ url: baseURL + route,
+ parameterEncoding: parameterEncoding,
+ params: params,
+ encodableBody: body,
+ headers: headers,
+ multipartData: nil,
+ timeout: timeout)
return req
}
}
+
+
+
diff --git a/Sources/Networking/Calls/NetworkingClient+Void.swift b/Sources/Networking/Calls/NetworkingClient+Void.swift
index dea4a75..402de17 100644
--- a/Sources/Networking/Calls/NetworkingClient+Void.swift
+++ b/Sources/Networking/Calls/NetworkingClient+Void.swift
@@ -6,82 +6,30 @@
//
import Foundation
-import Combine
-
-public extension NetworkingClient {
-
- func get(_ route: String, params: Params = Params()) -> AnyPublisher {
- get(route, params: params)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func post(_ route: String, params: Params = Params()) -> AnyPublisher {
- post(route, params: params)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func post(_ route: String, body: Encodable) -> AnyPublisher {
- post(route, body: body)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func put(_ route: String, params: Params = Params()) -> AnyPublisher {
- put(route, params: params)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
- patch(route, params: params)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func patch(_ route: String, body: Encodable) -> AnyPublisher {
- patch(route, body: body)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-
- func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
- delete(route, params: params)
- .map { (data: Data) -> Void in () }
- .eraseToAnyPublisher()
- }
-}
public extension NetworkingClient {
func get(_ route: String, params: Params = Params()) async throws {
- let req = request(.get, route, params: params)
- _ = try await req.execute()
+ _ = try await request(.get, route: route, params: params)
}
func post(_ route: String, params: Params = Params()) async throws {
- let req = request(.post, route, params: params)
- _ = try await req.execute()
+ _ = try await request(.post, route: route, params: params)
}
- func post(_ route: String, body: Encodable) async throws {
- let req = request(.post, route, encodableBody: body)
- _ = try await req.execute()
+ func post(_ route: String, body: Encodable & Sendable) async throws {
+ _ = try await request(.post, route: route, body: body)
}
func put(_ route: String, params: Params = Params()) async throws {
- let req = request(.put, route, params: params)
- _ = try await req.execute()
+ _ = try await request(.put, route: route, params: params)
}
func patch(_ route: String, params: Params = Params()) async throws {
- let req = request(.patch, route, params: params)
- _ = try await req.execute()
+ _ = try await request(.patch, route: route, params: params)
}
func delete(_ route: String, params: Params = Params()) async throws {
- let req = request(.delete, route, params: params)
- _ = try await req.execute()
+ _ = try await request(.delete, route: route, params: params)
}
}
diff --git a/Sources/Networking/Calls/NetworkingJSONDecodable.swift b/Sources/Networking/Calls/NetworkingJSONDecodable.swift
new file mode 100644
index 0000000..8cf0b1d
--- /dev/null
+++ b/Sources/Networking/Calls/NetworkingJSONDecodable.swift
@@ -0,0 +1,13 @@
+//
+// NetworkingJSONDecodable.swift
+// Networking
+//
+// Created by Sacha Durand Saint Omer on 26/09/2024.
+//
+
+import Foundation
+
+public protocol NetworkingJSONDecodable {
+ /// The method you declare your JSON mapping in.
+ static func decode(_ json: Any) throws -> Self
+}
diff --git a/Sources/Networking/Combine/NetworkingClient+Data+Combine.swift b/Sources/Networking/Combine/NetworkingClient+Data+Combine.swift
new file mode 100644
index 0000000..d8677cb
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingClient+Data+Combine.swift
@@ -0,0 +1,44 @@
+//
+// NetworkingClient+Data.swift
+//
+//
+// Created by Sacha on 13/03/2020.
+//
+
+import Foundation
+import Combine
+
+public extension NetworkingClient {
+
+ func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+ request(.get, route: route, params: params)
+ }
+
+ func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+ request(.post, route: route, params: params)
+ }
+
+ func post(_ route: String, body: Encodable & Sendable) -> AnyPublisher {
+ publisher(request: createRequest(.post, route, body: body))
+ }
+
+ func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+ request(.put, route: route, params: params)
+ }
+
+ func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+ request(.patch, route: route, params: params)
+ }
+
+ func patch(_ route: String, body: Encodable & Sendable) -> AnyPublisher {
+ publisher(request: createRequest(.patch, route, body: body))
+ }
+
+ func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+ request(.delete, route: route, params: params)
+ }
+
+ func request(_ httpMethod: HTTPMethod, route: String, params: Params = Params()) -> AnyPublisher {
+ publisher(request: createRequest(httpMethod, route, params: params))
+ }
+}
diff --git a/Sources/Networking/Combine/NetworkingClient+Decodable+Combine.swift b/Sources/Networking/Combine/NetworkingClient+Decodable+Combine.swift
new file mode 100644
index 0000000..b75610f
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingClient+Decodable+Combine.swift
@@ -0,0 +1,133 @@
+//
+// NetworkingClient+Decodable.swift
+//
+//
+// Created by Sacha DSO on 12/04/2022.
+//
+
+import Foundation
+import Combine
+
+public extension NetworkingClient {
+
+ func get(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher {
+ return get(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ // Array version
+ func get(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher where T: Collection {
+ let keypath = keypath ?? defaultCollectionParsingKeyPath
+ return get(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ func post(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher {
+ return post(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ func post(_ route: String,
+ body: Encodable,
+ keypath: String? = nil
+ ) -> AnyPublisher {
+ return post(route, body: body)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ // Array version
+ func post(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher where T: Collection {
+ let keypath = keypath ?? defaultCollectionParsingKeyPath
+ return post(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ func put(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher {
+ return put(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ // Array version
+ func put(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher where T: Collection {
+ let keypath = keypath ?? defaultCollectionParsingKeyPath
+ return put(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ func patch(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher {
+ return patch(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+
+ func patch(_ route: String,
+ body: Encodable,
+ keypath: String? = nil
+ ) -> AnyPublisher {
+ return patch(route, body: body)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ // Array version
+ func patch(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher where T: Collection {
+ let keypath = keypath ?? defaultCollectionParsingKeyPath
+ return patch(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ func delete(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher {
+ return delete(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+
+ // Array version
+ func delete(_ route: String,
+ params: Params = Params(),
+ keypath: String? = nil) -> AnyPublisher where T: Collection {
+ let keypath = keypath ?? defaultCollectionParsingKeyPath
+ return delete(route, params: params)
+ .tryMap { json -> T in try self.toModel(json, keypath: keypath) }
+ .receive(on: DispatchQueue.main)
+ .eraseToAnyPublisher()
+ }
+}
diff --git a/Sources/Networking/Combine/NetworkingClient+JSON+Combine.swift b/Sources/Networking/Combine/NetworkingClient+JSON+Combine.swift
new file mode 100644
index 0000000..b3987eb
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingClient+JSON+Combine.swift
@@ -0,0 +1,69 @@
+//
+// NetworkingClient+JSON.swift
+//
+//
+// Created by Sacha on 13/03/2020.
+//
+
+import Foundation
+import Combine
+
+public extension NetworkingClient {
+
+ func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+ get(route, params: params).toJSONSendable()
+ }
+
+ func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+ get(route, params: params).toJSON()
+ }
+
+ func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+ post(route, params: params).toJSON()
+ }
+
+ func post(_ route: String, body: Encodable) -> AnyPublisher {
+ post(route, body: body).toJSON()
+ }
+
+ func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+ put(route, params: params).toJSON()
+ }
+
+ func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+ patch(route, params: params).toJSON()
+ }
+
+ func patch(_ route: String, body: Encodable) -> AnyPublisher {
+ patch(route, body: body).toJSON()
+ }
+
+ func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+ delete(route, params: params).toJSONSendable()
+ }
+
+ func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+ delete(route, params: params).toJSON()
+ }
+}
+
+
+
+// Data to JSON
+extension Publisher where Output == Data {
+
+ public func toJSON() -> AnyPublisher {
+ tryMap { data -> JSON in
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return JSON(jsonObject: json)
+ }.eraseToAnyPublisher()
+ }
+
+ public func toJSONSendable() -> AnyPublisher {
+ tryMap { data -> Any in
+ let json = try JSONSerialization.jsonObject(with: data, options: [])
+ return json
+ }.eraseToAnyPublisher()
+ }
+}
+
diff --git a/Sources/Networking/Calls/NetworkingClient+Multipart.swift b/Sources/Networking/Combine/NetworkingClient+Multipart.swift
similarity index 57%
rename from Sources/Networking/Calls/NetworkingClient+Multipart.swift
rename to Sources/Networking/Combine/NetworkingClient+Multipart.swift
index 3207083..59f6e47 100644
--- a/Sources/Networking/Calls/NetworkingClient+Multipart.swift
+++ b/Sources/Networking/Combine/NetworkingClient+Multipart.swift
@@ -32,24 +32,45 @@ public extension NetworkingClient {
func post(_ route: String,
params: Params = Params(),
multipartData: [MultipartData]) -> AnyPublisher<(Data?, Progress), Error> {
- let req = request(.post, route, params: params)
- req.multipartData = multipartData
- return req.uploadPublisher()
+ let req = NetworkingRequest(
+ method: .post,
+ url: baseURL + route,
+ parameterEncoding: parameterEncoding,
+ params: params,
+ encodableBody: nil,
+ headers: headers,
+ multipartData: multipartData,
+ timeout: timeout)
+ return uploadPublisher(request: req)
}
func put(_ route: String,
params: Params = Params(),
multipartData: [MultipartData]) -> AnyPublisher<(Data?, Progress), Error> {
- let req = request(.put, route, params: params)
- req.multipartData = multipartData
- return req.uploadPublisher()
+ let req = NetworkingRequest(
+ method: .put,
+ url: baseURL + route,
+ parameterEncoding: parameterEncoding,
+ params: params,
+ encodableBody: nil,
+ headers: headers,
+ multipartData: multipartData,
+ timeout: timeout)
+ return uploadPublisher(request: req)
}
func patch(_ route: String,
params: Params = Params(),
multipartData: [MultipartData]) -> AnyPublisher<(Data?, Progress), Error> {
- let req = request(.patch, route, params: params)
- req.multipartData = multipartData
- return req.uploadPublisher()
+ let req = NetworkingRequest(
+ method: .patch,
+ url: baseURL + route,
+ parameterEncoding: parameterEncoding,
+ params: params,
+ encodableBody: nil,
+ headers: headers,
+ multipartData: multipartData,
+ timeout: timeout)
+ return uploadPublisher(request: req)
}
}
diff --git a/Sources/Networking/Calls/NetworkingClient+NetworkingJSONDecodable.swift b/Sources/Networking/Combine/NetworkingClient+NetworkingJSONDecodable.swift
similarity index 97%
rename from Sources/Networking/Calls/NetworkingClient+NetworkingJSONDecodable.swift
rename to Sources/Networking/Combine/NetworkingClient+NetworkingJSONDecodable.swift
index 68944be..e51f0b9 100644
--- a/Sources/Networking/Calls/NetworkingClient+NetworkingJSONDecodable.swift
+++ b/Sources/Networking/Combine/NetworkingClient+NetworkingJSONDecodable.swift
@@ -8,12 +8,6 @@
import Foundation
import Combine
-
-public protocol NetworkingJSONDecodable {
- /// The method you declare your JSON mapping in.
- static func decode(_ json: Any) throws -> Self
-}
-
public extension NetworkingClient {
func get(_ route: String,
diff --git a/Sources/Networking/Combine/NetworkingClient+Void+Combine.swift b/Sources/Networking/Combine/NetworkingClient+Void+Combine.swift
new file mode 100644
index 0000000..71d7ade
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingClient+Void+Combine.swift
@@ -0,0 +1,54 @@
+//
+// NetworkingClient+Void.swift
+//
+//
+// Created by Sacha on 13/03/2020.
+//
+
+import Foundation
+import Combine
+
+public extension NetworkingClient {
+
+ func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+ get(route, params: params)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+ post(route, params: params)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func post(_ route: String, body: Encodable) -> AnyPublisher {
+ post(route, body: body)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+ put(route, params: params)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+ patch(route, params: params)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func patch(_ route: String, body: Encodable) -> AnyPublisher {
+ patch(route, body: body)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+
+ func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+ delete(route, params: params)
+ .map { (data: Data) -> Void in () }
+ .eraseToAnyPublisher()
+ }
+}
diff --git a/Sources/Networking/Combine/NetworkingRequest+Publisher.swift b/Sources/Networking/Combine/NetworkingRequest+Publisher.swift
new file mode 100644
index 0000000..986368c
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingRequest+Publisher.swift
@@ -0,0 +1,101 @@
+//
+// NetworkingRequest+Execute.swift
+//
+//
+// Created by Sacha DSO on 26/09/2024.
+//
+
+import Foundation
+import Combine
+
+
+extension NetworkingClient {
+
+ public func uploadPublisher(request: NetworkingRequest) -> AnyPublisher<(Data?, Progress), Error> {
+
+ guard let urlRequest = request.buildURLRequest() else {
+ return Fail(error: NetworkingError.unableToParseRequest as Error)
+ .eraseToAnyPublisher()
+ }
+ logger.log(request: urlRequest, level: logLevel)
+
+ let urlSession = URLSession(configuration: sessionConfiguration, delegate: sessionDelegate, delegateQueue: nil)
+ let callPublisher: AnyPublisher<(Data?, Progress), Error> = urlSession.dataTaskPublisher(for: urlRequest)
+ .tryMap { (data: Data, response: URLResponse) -> Data in
+ self.logger.log(response: response, data: data, level: self.logLevel)
+ if let httpURLResponse = response as? HTTPURLResponse {
+ if !(200...299 ~= httpURLResponse.statusCode) {
+ var error = NetworkingError(errorCode: httpURLResponse.statusCode)
+ if let json = try? JSONSerialization.jsonObject(with: data, options: []) {
+ error.jsonPayload = JSON(jsonObject: json)
+ }
+ throw error
+ }
+ }
+ return data
+ }.mapError { error -> NetworkingError in
+ return NetworkingError(error: error)
+ }.map { data -> (Data?, Progress) in
+ return (data, Progress())
+ }.eraseToAnyPublisher()
+
+ return callPublisher
+ .eraseToAnyPublisher()
+ // Todo put back progress
+//
+// let progressPublisher2: AnyPublisher<(Data?, Progress), Error> = sessionDelegate.progressPublisher
+// .map { progress -> (Data?, Progress) in
+// return (nil, progress)
+// }.eraseToAnyPublisher()
+//
+// return Publishers.Merge(callPublisher, progressPublisher2)
+// .receive(on: DispatchQueue.main)
+// .eraseToAnyPublisher()
+ }
+
+ public func publisher(request: NetworkingRequest) -> AnyPublisher {
+ publisher(request: request, retryCount: request.maxRetryCount)
+ }
+
+ private func publisher(request: NetworkingRequest, retryCount: Int) -> AnyPublisher {
+ guard let urlRequest = request.buildURLRequest() else {
+ return Fail(error: NetworkingError.unableToParseRequest as Error)
+ .eraseToAnyPublisher()
+ }
+ logger.log(request: urlRequest, level: logLevel)
+
+ let urlSession = URLSession(configuration: sessionConfiguration, delegate: sessionDelegate, delegateQueue: nil)
+ return urlSession.dataTaskPublisher(for: urlRequest)
+ .tryMap { (data: Data, response: URLResponse) -> Data in
+ self.logger.log(response: response, data: data, level: self.logLevel)
+ if let httpURLResponse = response as? HTTPURLResponse {
+ if !(200...299 ~= httpURLResponse.statusCode) {
+ var error = NetworkingError(errorCode: httpURLResponse.statusCode)
+ if let json = try? JSONSerialization.jsonObject(with: data, options: []) {
+ error.jsonPayload = JSON(jsonObject: json)
+ }
+ throw error
+ }
+ }
+ return data
+ }
+ // TODO fix retry
+// .tryCatch({ [weak self, urlRequest] error -> AnyPublisher in
+// guard
+// let self = self,
+// retryCount > 1,
+// let retryPublisher = self.requestRetrier?(urlRequest, error)
+// else {
+// throw error
+// }
+// return retryPublisher
+// .flatMap { _ -> AnyPublisher in
+// self.publisher(request: request, retryCount: retryCount - 1)
+// }
+// .eraseToAnyPublisher()
+// })
+ .mapError { error -> NetworkingError in
+ return NetworkingError(error: error)
+ }.receive(on: DispatchQueue.main).eraseToAnyPublisher()
+ }
+}
diff --git a/Sources/Networking/Combine/NetworkingService+Combine.swift b/Sources/Networking/Combine/NetworkingService+Combine.swift
new file mode 100644
index 0000000..bedde3a
--- /dev/null
+++ b/Sources/Networking/Combine/NetworkingService+Combine.swift
@@ -0,0 +1,227 @@
+////
+//// NetworkingService.swift
+////
+////
+//// Created by Sacha on 13/03/2020.
+////
+//
+//import Foundation
+//import Combine
+//
+//// Sugar, just forward calls to underlying network client
+//
+//public extension NetworkingService {
+//
+// // Data
+//
+// func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.get(route, params: params)
+// }
+//
+// func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.post(route, params: params)
+// }
+//
+// func post(_ route: String, body: Encodable & Sendable) -> AnyPublisher {
+// network.post(route, body: body)
+// }
+//
+// func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.put(route, params: params)
+// }
+//
+// func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.patch(route, params: params)
+// }
+//
+// func patch(_ route: String, body: Encodable) -> AnyPublisher {
+// network.patch(route, body: body)
+// }
+//
+// func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.delete(route, params: params)
+// }
+//
+// // Void
+//
+// func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.get(route, params: params)
+// }
+//
+// func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.post(route, params: params)
+// }
+//
+// func post(_ route: String, body: Encodable) -> AnyPublisher {
+// network.post(route, body: body)
+// }
+//
+// func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.put(route, params: params)
+// }
+//
+// func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.patch(route, params: params)
+// }
+//
+// func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.delete(route, params: params)
+// }
+//
+// // JSON
+//
+// func get(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.get(route, params: params)
+// }
+//
+// func post(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.post(route, params: params)
+// }
+//
+// func post(_ route: String, body: Encodable) -> AnyPublisher {
+// network.post(route, body: body)
+// }
+//
+// func put(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.put(route, params: params)
+// }
+//
+// func patch(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.patch(route, params: params)
+// }
+//
+// func delete(_ route: String, params: Params = Params()) -> AnyPublisher {
+// network.delete(route, params: params)
+// }
+//
+// // Decodable
+//
+// func get(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.get(route, params: params, keypath: keypath)
+// }
+//
+// func post(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.post(route, params: params, keypath: keypath)
+// }
+//
+// func put(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.put(route, params: params, keypath: keypath)
+// }
+//
+// func patch(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.patch(route, params: params, keypath: keypath)
+// }
+//
+// func delete(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.delete(route, params: params, keypath: keypath)
+// }
+//
+// // Array Decodable
+//
+// func get(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher where T: Collection {
+// network.get(route, params: params, keypath: keypath)
+// }
+//
+// func post(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher where T: Collection {
+// network.post(route, params: params, keypath: keypath)
+// }
+//
+// func put(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher where T: Collection {
+// network.put(route, params: params, keypath: keypath)
+// }
+//
+// func patch(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher where T: Collection {
+// network.patch(route, params: params, keypath: keypath)
+// }
+//
+// func delete(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher where T: Collection {
+// network.delete(route, params: params, keypath: keypath)
+// }
+//
+// // NetworkingJSONDecodable
+//
+// func get(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.get(route, params: params, keypath: keypath)
+// }
+//
+// func post(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.post(route, params: params, keypath: keypath)
+// }
+//
+// func put(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.put(route, params: params, keypath: keypath)
+// }
+//
+// func patch(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.patch(route, params: params, keypath: keypath)
+// }
+//
+// func delete(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher {
+// network.delete(route, params: params, keypath: keypath)
+// }
+//
+//
+//
+// // Array NetworkingJSONDecodable
+//
+// func get(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher<[T], Error> {
+// network.get(route, params: params, keypath: keypath)
+// }
+//
+// func post(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher<[T], Error> {
+// network.post(route, params: params, keypath: keypath)
+// }
+//
+// func put(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher<[T], Error> {
+// network.put(route, params: params, keypath: keypath)
+// }
+//
+// func patch(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher<[T], Error> {
+// network.patch(route, params: params, keypath: keypath)
+// }
+//
+// func delete(_ route: String,
+// params: Params = Params(),
+// keypath: String? = nil) -> AnyPublisher<[T], Error> {
+// network.delete(route, params: params, keypath: keypath)
+// }
+//}
+//
diff --git a/Sources/Networking/HTTPMethod.swift b/Sources/Networking/HTTPMethod.swift
index 453abce..ad2d2b0 100644
--- a/Sources/Networking/HTTPMethod.swift
+++ b/Sources/Networking/HTTPMethod.swift
@@ -7,7 +7,7 @@
import Foundation
-public enum HTTPMethod: String {
+public enum HTTPMethod: String, Sendable {
case get = "GET"
case put = "PUT"
case patch = "PATCH"
diff --git a/Sources/Networking/Logging/NetworkingLogger.swift b/Sources/Networking/Logging/NetworkingLogger.swift
index 253707a..27cb64e 100644
--- a/Sources/Networking/Logging/NetworkingLogger.swift
+++ b/Sources/Networking/Logging/NetworkingLogger.swift
@@ -7,12 +7,10 @@
import Foundation
-class NetworkingLogger {
+struct NetworkingLogger {
- var logLevel = NetworkingLogLevel.off
-
- func log(request: URLRequest) {
- guard logLevel != .off else {
+ func log(request: URLRequest, level: NetworkingLogLevel) {
+ guard level != .off else {
return
}
if let method = request.httpMethod,
@@ -22,19 +20,19 @@ class NetworkingLogger {
logBody(request)
}
- if logLevel == .debug {
+ if level == .debug {
logCurl(request)
}
}
- func log(response: URLResponse, data: Data) {
- guard logLevel != .off else {
+ func log(response: URLResponse, data: Data, level: NetworkingLogLevel) {
+ guard level != .off else {
return
}
if let response = response as? HTTPURLResponse {
logStatusCodeAndURL(response)
}
- if logLevel == .debug {
+ if level == .debug {
print(String(decoding: data, as: UTF8.self))
}
}
diff --git a/Sources/Networking/Multipart/MultipartData.swift b/Sources/Networking/Multipart/MultipartData.swift
index e8e595a..2c5e8f4 100644
--- a/Sources/Networking/Multipart/MultipartData.swift
+++ b/Sources/Networking/Multipart/MultipartData.swift
@@ -7,7 +7,7 @@
import Foundation
-public struct MultipartData {
+public struct MultipartData: Sendable {
let name: String
let fileData: Data
let fileName: String
diff --git a/Sources/Networking/NetworkingClient.swift b/Sources/Networking/NetworkingClient.swift
index b3c9dfb..879e721 100644
--- a/Sources/Networking/NetworkingClient.swift
+++ b/Sources/Networking/NetworkingClient.swift
@@ -1,7 +1,24 @@
import Foundation
-import Combine
+//import Combine
-public class NetworkingClient {
+actor NetworkingClientURLSessionDelegate: NSObject, URLSessionDelegate {
+
+// let progressPublisher = PassthroughSubject