Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
04e8256
WIP - Migrates to Swift 6
s4cha Sep 25, 2024
38510c8
Migrates CurlLoggingTests to Testing
s4cha Sep 25, 2024
c378bf0
Removes legacy linux test conf files
s4cha Sep 25, 2024
e062cc4
Migrates ParamsTests to Testing
s4cha Sep 25, 2024
620b856
WIP - Migrate unit tests to Testing
s4cha Sep 25, 2024
632e4d0
Update GetRequestTests.swift
s4cha Sep 25, 2024
4ad06d2
WIP - Separate Combine Api from async await one
s4cha Sep 26, 2024
2295056
WIP separate Combine tests from others
s4cha Sep 27, 2024
6ff78a2
Adds xctestplan with "parallelizable: false"
s4cha Oct 2, 2024
cb9a42d
Migrates more tests to Swift Testing
s4cha Oct 2, 2024
578dff1
Adds example Swift 6 App
s4cha Oct 2, 2024
a9ba0b1
WIP - simplify code
s4cha Oct 3, 2024
5af7a97
WIP - put back combines unit tests
s4cha Oct 3, 2024
0aa5bd3
Update GetRequestTests+Combine.swift
s4cha Oct 3, 2024
0e74191
WIP - updates DeleteRequestCombineTests
s4cha Oct 3, 2024
d12fab3
Update DeleteRequestTests+Combine.swift
s4cha Oct 4, 2024
0c7033a
Update PutRequestTests+Combine.swift
s4cha Oct 6, 2024
e565a29
Update PostRequestTests+Combine.swift
s4cha Oct 6, 2024
d6080bc
Puts back PatchRequestCombineTests
s4cha Oct 6, 2024
3eb5e34
Puts back MultipartRequestTests
s4cha Oct 6, 2024
fd6ec93
Improves example app
s4cha Oct 7, 2024
09cd1b8
WIP - Swift 6 Migration
s4cha Oct 7, 2024
9b510f2
Adds beforeRequest & mapError hooks
s4cha Jul 1, 2025
e74b9e6
Make NetworkingClient thread safe via actor (aka Sendable)
s4cha Jul 2, 2025
e784970
Updates example project
s4cha Nov 3, 2025
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
25 changes: 25 additions & 0 deletions .swiftpm/Networking.xctestplan
Original file line number Diff line number Diff line change
@@ -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
}
84 changes: 84 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/Networking.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Networking"
BuildableName = "Networking"
BlueprintName = "Networking"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<TestPlans>
<TestPlanReference
reference = "container:.swiftpm/Networking.xctestplan"
default = "YES">
</TestPlanReference>
</TestPlans>
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "NetworkingTests"
BuildableName = "NetworkingTests"
BlueprintName = "NetworkingTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "Networking"
BuildableName = "Networking"
BlueprintName = "Networking"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
9 changes: 8 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)

41 changes: 41 additions & 0 deletions Sources/Networking/Calls/JSON.swift
Original file line number Diff line number Diff line change
@@ -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"
}

}
56 changes: 17 additions & 39 deletions Sources/Networking/Calls/NetworkingClient+Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,40 @@
//

import Foundation
import Combine

public extension NetworkingClient {

func get(_ route: String, params: Params = Params()) -> AnyPublisher<Data, Error> {
request(.get, route, params: params).publisher()
}

func post(_ route: String, params: Params = Params()) -> AnyPublisher<Data, Error> {
request(.post, route, params: params).publisher()
}

func post(_ route: String, body: Encodable) -> AnyPublisher<Data, Error> {
request(.post, route, encodableBody: body).publisher()
}

func put(_ route: String, params: Params = Params()) -> AnyPublisher<Data, Error> {
request(.put, route, params: params).publisher()
}

func patch(_ route: String, params: Params = Params()) -> AnyPublisher<Data, Error> {
request(.patch, route, params: params).publisher()
}

func patch(_ route: String, body: Encodable) -> AnyPublisher<Data, Error> {
request(.patch, route, encodableBody: body).publisher()
}

func delete(_ route: String, params: Params = Params()) -> AnyPublisher<Data, Error> {
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)
}
}
}
Loading
Loading