Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: macOS 10.15
name: macOS 14

on:
push:
Expand All @@ -10,10 +10,12 @@ on:

jobs:
test:
runs-on: macos-10.15
runs-on: macos-14

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Install SwiftLint
run: brew install swiftlint
- name: Lint
run: |
swiftlint --strict
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: macOS 11
name: macOS 15

on:
push:
Expand All @@ -10,14 +10,12 @@ on:

jobs:
test:
runs-on: macos-11
runs-on: macos-15

steps:
- uses: actions/checkout@v2
- name: Setup Xcode version
uses: maxim-lobanov/setup-xcode@v1.4.0
with:
xcode-version: 13.1
- uses: actions/checkout@v4
- name: Install SwiftLint
run: brew install swiftlint
- name: Lint
run: |
swiftlint --strict
Expand Down
4 changes: 2 additions & 2 deletions FTAPIKit.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ Pod::Spec.new do |s|
s.weak_frameworks = ["Combine"]

s.swift_version = "5.1"
s.ios.deployment_target = "9.0"
s.osx.deployment_target = "10.10"
s.ios.deployment_target = "12.0"
s.osx.deployment_target = "10.13"
s.watchos.deployment_target = "5.0"
s.tvos.deployment_target = "12.0"
end
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

source "https://rubygems.org"

gem "cocoapods", "~> 1.11"
gem "cocoapods", "~> 1.14"
87 changes: 51 additions & 36 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,41 +1,49 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.4)
rexml
activesupport (6.1.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
CFPropertyList (3.0.8)
activesupport (7.2.3)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.8)
public_suffix (>= 2.0.2, < 8.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.0.3)
cocoapods (1.11.2)
base64 (0.3.0)
benchmark (0.5.0)
bigdecimal (4.0.1)
claide (1.1.0)
cocoapods (1.16.2)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.2)
cocoapods-core (= 1.16.2)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-downloader (>= 2.1, < 3.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-trunk (>= 1.6.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.2)
activesupport (>= 5.0, < 7)
ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.27.0, < 2.0)
cocoapods-core (1.16.2)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
Expand All @@ -45,7 +53,7 @@ GEM
public_suffix (~> 4.0)
typhoeus (~> 1.0)
cocoapods-deintegrate (1.0.5)
cocoapods-downloader (1.6.3)
cocoapods-downloader (2.1)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.1)
Expand All @@ -54,44 +62,51 @@ GEM
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.9)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
drb (2.2.3)
escape (0.0.4)
ethon (0.15.0)
ffi (>= 1.15.0)
ffi (1.15.4)
ffi (1.17.3)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.8.10)
httpclient (2.9.0)
mutex_m
i18n (1.14.8)
concurrent-ruby (~> 1.0)
json (2.6.1)
minitest (5.14.4)
json (2.18.0)
logger (1.7.0)
minitest (6.0.1)
prism (~> 1.5)
molinillo (0.8.0)
nanaimo (0.3.0)
mutex_m (0.3.0)
nanaimo (0.4.0)
nap (1.1.0)
netrc (0.11.0)
public_suffix (4.0.6)
rexml (3.2.5)
prism (1.8.0)
public_suffix (4.0.7)
rexml (3.4.4)
ruby-macho (2.5.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.4)
securerandom (0.4.1)
typhoeus (1.5.0)
ethon (>= 0.9.0, < 0.16.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.21.0)
xcodeproj (1.27.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
zeitwerk (2.5.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)

PLATFORMS
ruby

DEPENDENCIES
cocoapods (~> 1.11)
cocoapods (~> 1.14)

BUNDLED WITH
2.2.29
4.0.4
13 changes: 9 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
// swift-tools-version:5.1
// swift-tools-version:5.5

import PackageDescription

let package = Package(
name: "FTAPIKit",
platforms: [.iOS(.v12), .macOS(.v10_10), .tvOS(.v12), .watchOS(.v5)],
platforms: [
.iOS(.v14),
.macOS(.v11),
.tvOS(.v14),
.watchOS(.v7)
],
products: [
.library(
name: "FTAPIKit",
targets: ["FTAPIKit"])
],
dependencies: [],
targets: [
.target(
name: "FTAPIKit",
dependencies: []
),
.testTarget(
name: "FTAPIKitTests",
dependencies: ["FTAPIKit"]
)
dependencies: ["FTAPIKit"])
]
)
22 changes: 0 additions & 22 deletions Package@swift-5.5.swift

This file was deleted.

3 changes: 2 additions & 1 deletion Sources/FTAPIKit/Combine/EndpointPublisher.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// swiftlint:disable nesting
import Foundation
#if canImport(Combine)
import Combine

@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
extension Publishers {
// swiftlint:disable nesting
struct Endpoint<R, E: Error>: Publisher {
typealias Output = R
typealias Failure = E
Expand All @@ -18,6 +18,7 @@ extension Publishers {
subscriber.receive(subscription: subscription)
}
}
// swiftlint:enable nesting
}

#endif
46 changes: 46 additions & 0 deletions Sources/FTAPIKit/NetworkObserver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Foundation

#if os(Linux)
import FoundationNetworking
#endif

/// Protocol for observing network request lifecycle events.
///
/// Implement this protocol to add logging, analytics, or request tracking.
///
/// ## Context Lifecycle
/// The `Context` associated type allows passing correlation data (request ID, start time, etc.)
/// through the request lifecycle:
/// 1. `willSendRequest` is called before the request starts and returns a `Context` value
/// 2. `didReceiveResponse` is always called with the raw response data (useful for debugging)
/// 3. `didFail` is called additionally if the request processing fails (network, HTTP status, or decoding error)
/// 4. If the observer is deallocated before the request completes, the context is discarded
/// and no completion callback is invoked
public protocol NetworkObserver: AnyObject, Sendable {
associatedtype Context: Sendable

/// Called immediately before a request is sent.
/// - Parameter request: The URLRequest about to be sent
/// - Returns: Context to be passed to `didReceiveResponse` and optionally `didFail`
func willSendRequest(_ request: URLRequest) -> Context

/// Called when a response is received from the server.
///
/// This is always called with the raw response data, even if processing subsequently fails.
/// This allows observers to inspect the actual response for debugging purposes.
/// - Parameters:
/// - request: The original request
/// - response: The URL response (may be HTTPURLResponse)
/// - data: Response body data, if any (nil for download tasks)
/// - context: Value returned from `willSendRequest`
func didReceiveResponse(for request: URLRequest, response: URLResponse?, data: Data?, context: Context)

/// Called when a request fails with an error.
///
/// Called after `didReceiveResponse` if processing determines the request failed.
/// - Parameters:
/// - request: The original request
/// - error: The error that occurred (may be network, HTTP status, or decoding error)
/// - context: Value returned from `willSendRequest`
func didFail(request: URLRequest, error: Error, context: Context)
}
6 changes: 2 additions & 4 deletions Sources/FTAPIKit/URL+MIME.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ extension URL {

#if canImport(CoreServices)
private func coreServicesMimeType(for fileExtension: String) -> String? {
if
let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue(),
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue()
{
if let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension as CFString, nil)?.takeRetainedValue(),
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue() {
return contentType as String
}
return nil
Expand Down
5 changes: 0 additions & 5 deletions Sources/FTAPIKit/URLRequestBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ struct URLRequestBuilder<S: URLServer> {
let server: S
let endpoint: Endpoint

init(server: S, endpoint: Endpoint) {
self.server = server
self.endpoint = endpoint
}

/// Creates an instance of `URLRequest` corresponding to provided endpoint executed on provided server.
/// It is safe to execute this method multiple times per instance lifetime.
/// - Returns: A valid `URLRequest`.
Expand Down
Loading