Skip to content

Commit 0c89db3

Browse files
authored
Merge pull request #108 from futuredapp/feature/Add-support-of-FTNetworkTracer
Add support of FTNetworkTracer
2 parents 13a6b68 + 3596d43 commit 0c89db3

16 files changed

Lines changed: 320 additions & 88 deletions
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: macOS 10.15
1+
name: macOS 14
22

33
on:
44
push:
@@ -10,10 +10,12 @@ on:
1010

1111
jobs:
1212
test:
13-
runs-on: macos-10.15
13+
runs-on: macos-14
1414

1515
steps:
16-
- uses: actions/checkout@v2
16+
- uses: actions/checkout@v4
17+
- name: Install SwiftLint
18+
run: brew install swiftlint
1719
- name: Lint
1820
run: |
1921
swiftlint --strict
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: macOS 11
1+
name: macOS 15
22

33
on:
44
push:
@@ -10,14 +10,12 @@ on:
1010

1111
jobs:
1212
test:
13-
runs-on: macos-11
13+
runs-on: macos-15
1414

1515
steps:
16-
- uses: actions/checkout@v2
17-
- name: Setup Xcode version
18-
uses: maxim-lobanov/setup-xcode@v1.4.0
19-
with:
20-
xcode-version: 13.1
16+
- uses: actions/checkout@v4
17+
- name: Install SwiftLint
18+
run: brew install swiftlint
2119
- name: Lint
2220
run: |
2321
swiftlint --strict

FTAPIKit.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ Pod::Spec.new do |s|
2121
s.weak_frameworks = ["Combine"]
2222

2323
s.swift_version = "5.1"
24-
s.ios.deployment_target = "9.0"
25-
s.osx.deployment_target = "10.10"
24+
s.ios.deployment_target = "12.0"
25+
s.osx.deployment_target = "10.13"
2626
s.watchos.deployment_target = "5.0"
2727
s.tvos.deployment_target = "12.0"
2828
end

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
source "https://rubygems.org"
44

5-
gem "cocoapods", "~> 1.11"
5+
gem "cocoapods", "~> 1.14"

Gemfile.lock

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,49 @@
11
GEM
22
remote: https://rubygems.org/
33
specs:
4-
CFPropertyList (3.0.4)
5-
rexml
6-
activesupport (6.1.4.1)
7-
concurrent-ruby (~> 1.0, >= 1.0.2)
4+
CFPropertyList (3.0.8)
5+
activesupport (7.2.3)
6+
base64
7+
benchmark (>= 0.3)
8+
bigdecimal
9+
concurrent-ruby (~> 1.0, >= 1.3.1)
10+
connection_pool (>= 2.2.5)
11+
drb
812
i18n (>= 1.6, < 2)
13+
logger (>= 1.4.2)
914
minitest (>= 5.1)
10-
tzinfo (~> 2.0)
11-
zeitwerk (~> 2.3)
12-
addressable (2.8.0)
13-
public_suffix (>= 2.0.2, < 5.0)
15+
securerandom (>= 0.3)
16+
tzinfo (~> 2.0, >= 2.0.5)
17+
addressable (2.8.8)
18+
public_suffix (>= 2.0.2, < 8.0)
1419
algoliasearch (1.27.5)
1520
httpclient (~> 2.8, >= 2.8.3)
1621
json (>= 1.5.1)
1722
atomos (0.1.3)
18-
claide (1.0.3)
19-
cocoapods (1.11.2)
23+
base64 (0.3.0)
24+
benchmark (0.5.0)
25+
bigdecimal (4.0.1)
26+
claide (1.1.0)
27+
cocoapods (1.16.2)
2028
addressable (~> 2.8)
2129
claide (>= 1.0.2, < 2.0)
22-
cocoapods-core (= 1.11.2)
30+
cocoapods-core (= 1.16.2)
2331
cocoapods-deintegrate (>= 1.0.3, < 2.0)
24-
cocoapods-downloader (>= 1.4.0, < 2.0)
32+
cocoapods-downloader (>= 2.1, < 3.0)
2533
cocoapods-plugins (>= 1.0.0, < 2.0)
2634
cocoapods-search (>= 1.0.0, < 2.0)
27-
cocoapods-trunk (>= 1.4.0, < 2.0)
35+
cocoapods-trunk (>= 1.6.0, < 2.0)
2836
cocoapods-try (>= 1.1.0, < 2.0)
2937
colored2 (~> 3.1)
3038
escape (~> 0.0.4)
3139
fourflusher (>= 2.3.0, < 3.0)
3240
gh_inspector (~> 1.0)
3341
molinillo (~> 0.8.0)
3442
nap (~> 1.0)
35-
ruby-macho (>= 1.0, < 3.0)
36-
xcodeproj (>= 1.21.0, < 2.0)
37-
cocoapods-core (1.11.2)
38-
activesupport (>= 5.0, < 7)
43+
ruby-macho (>= 2.3.0, < 3.0)
44+
xcodeproj (>= 1.27.0, < 2.0)
45+
cocoapods-core (1.16.2)
46+
activesupport (>= 5.0, < 8)
3947
addressable (~> 2.8)
4048
algoliasearch (~> 1.0)
4149
concurrent-ruby (~> 1.1)
@@ -45,7 +53,7 @@ GEM
4553
public_suffix (~> 4.0)
4654
typhoeus (~> 1.0)
4755
cocoapods-deintegrate (1.0.5)
48-
cocoapods-downloader (1.6.3)
56+
cocoapods-downloader (2.1)
4957
cocoapods-plugins (1.0.0)
5058
nap
5159
cocoapods-search (1.0.1)
@@ -54,44 +62,51 @@ GEM
5462
netrc (~> 0.11)
5563
cocoapods-try (1.2.0)
5664
colored2 (3.1.2)
57-
concurrent-ruby (1.1.9)
65+
concurrent-ruby (1.3.6)
66+
connection_pool (3.0.2)
67+
drb (2.2.3)
5868
escape (0.0.4)
5969
ethon (0.15.0)
6070
ffi (>= 1.15.0)
61-
ffi (1.15.4)
71+
ffi (1.17.3)
6272
fourflusher (2.3.1)
6373
fuzzy_match (2.0.4)
6474
gh_inspector (1.1.3)
65-
httpclient (2.8.3)
66-
i18n (1.8.10)
75+
httpclient (2.9.0)
76+
mutex_m
77+
i18n (1.14.8)
6778
concurrent-ruby (~> 1.0)
68-
json (2.6.1)
69-
minitest (5.14.4)
79+
json (2.18.0)
80+
logger (1.7.0)
81+
minitest (6.0.1)
82+
prism (~> 1.5)
7083
molinillo (0.8.0)
71-
nanaimo (0.3.0)
84+
mutex_m (0.3.0)
85+
nanaimo (0.4.0)
7286
nap (1.1.0)
7387
netrc (0.11.0)
74-
public_suffix (4.0.6)
75-
rexml (3.2.5)
88+
prism (1.8.0)
89+
public_suffix (4.0.7)
90+
rexml (3.4.4)
7691
ruby-macho (2.5.1)
77-
typhoeus (1.4.0)
78-
ethon (>= 0.9.0)
79-
tzinfo (2.0.4)
92+
securerandom (0.4.1)
93+
typhoeus (1.5.0)
94+
ethon (>= 0.9.0, < 0.16.0)
95+
tzinfo (2.0.6)
8096
concurrent-ruby (~> 1.0)
81-
xcodeproj (1.21.0)
97+
xcodeproj (1.27.0)
8298
CFPropertyList (>= 2.3.3, < 4.0)
8399
atomos (~> 0.1.3)
84100
claide (>= 1.0.2, < 2.0)
85101
colored2 (~> 3.1)
86-
nanaimo (~> 0.3.0)
87-
rexml (~> 3.2.4)
88-
zeitwerk (2.5.1)
102+
nanaimo (~> 0.4.0)
103+
rexml (>= 3.3.6, < 4.0)
89104

90105
PLATFORMS
91106
ruby
92107

93108
DEPENDENCIES
94-
cocoapods (~> 1.11)
109+
cocoapods (~> 1.14)
95110

96111
BUNDLED WITH
97-
2.2.29
112+
4.0.4

Package.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
1-
// swift-tools-version:5.1
1+
// swift-tools-version:5.5
22

33
import PackageDescription
44

55
let package = Package(
66
name: "FTAPIKit",
7-
platforms: [.iOS(.v12), .macOS(.v10_10), .tvOS(.v12), .watchOS(.v5)],
7+
platforms: [
8+
.iOS(.v14),
9+
.macOS(.v11),
10+
.tvOS(.v14),
11+
.watchOS(.v7)
12+
],
813
products: [
914
.library(
1015
name: "FTAPIKit",
1116
targets: ["FTAPIKit"])
1217
],
18+
dependencies: [],
1319
targets: [
1420
.target(
1521
name: "FTAPIKit",
1622
dependencies: []
1723
),
1824
.testTarget(
1925
name: "FTAPIKitTests",
20-
dependencies: ["FTAPIKit"]
21-
)
26+
dependencies: ["FTAPIKit"])
2227
]
2328
)

Package@swift-5.5.swift

Lines changed: 0 additions & 22 deletions
This file was deleted.

Sources/FTAPIKit/Combine/EndpointPublisher.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// swiftlint:disable nesting
21
import Foundation
32
#if canImport(Combine)
43
import Combine
54

65
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
76
extension Publishers {
7+
// swiftlint:disable nesting
88
struct Endpoint<R, E: Error>: Publisher {
99
typealias Output = R
1010
typealias Failure = E
@@ -18,6 +18,7 @@ extension Publishers {
1818
subscriber.receive(subscription: subscription)
1919
}
2020
}
21+
// swiftlint:enable nesting
2122
}
2223

2324
#endif
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import Foundation
2+
3+
#if os(Linux)
4+
import FoundationNetworking
5+
#endif
6+
7+
/// Protocol for observing network request lifecycle events.
8+
///
9+
/// Implement this protocol to add logging, analytics, or request tracking.
10+
///
11+
/// ## Context Lifecycle
12+
/// The `Context` associated type allows passing correlation data (request ID, start time, etc.)
13+
/// through the request lifecycle:
14+
/// 1. `willSendRequest` is called before the request starts and returns a `Context` value
15+
/// 2. `didReceiveResponse` is always called with the raw response data (useful for debugging)
16+
/// 3. `didFail` is called additionally if the request processing fails (network, HTTP status, or decoding error)
17+
/// 4. If the observer is deallocated before the request completes, the context is discarded
18+
/// and no completion callback is invoked
19+
public protocol NetworkObserver: AnyObject, Sendable {
20+
associatedtype Context: Sendable
21+
22+
/// Called immediately before a request is sent.
23+
/// - Parameter request: The URLRequest about to be sent
24+
/// - Returns: Context to be passed to `didReceiveResponse` and optionally `didFail`
25+
func willSendRequest(_ request: URLRequest) -> Context
26+
27+
/// Called when a response is received from the server.
28+
///
29+
/// This is always called with the raw response data, even if processing subsequently fails.
30+
/// This allows observers to inspect the actual response for debugging purposes.
31+
/// - Parameters:
32+
/// - request: The original request
33+
/// - response: The URL response (may be HTTPURLResponse)
34+
/// - data: Response body data, if any (nil for download tasks)
35+
/// - context: Value returned from `willSendRequest`
36+
func didReceiveResponse(for request: URLRequest, response: URLResponse?, data: Data?, context: Context)
37+
38+
/// Called when a request fails with an error.
39+
///
40+
/// Called after `didReceiveResponse` if processing determines the request failed.
41+
/// - Parameters:
42+
/// - request: The original request
43+
/// - error: The error that occurred (may be network, HTTP status, or decoding error)
44+
/// - context: Value returned from `willSendRequest`
45+
func didFail(request: URLRequest, error: Error, context: Context)
46+
}

Sources/FTAPIKit/URL+MIME.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ extension URL {
3030

3131
#if canImport(CoreServices)
3232
private func coreServicesMimeType(for fileExtension: String) -> String? {
33-
if
34-
let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue(),
35-
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue()
36-
{
33+
if let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue(),
34+
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue() {
3735
return contentType as String
3836
}
3937
return nil

0 commit comments

Comments
 (0)