Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
070ed8f
feat: Add documentation and integrate ApproovServiceMutator
Mar 6, 2026
7314ca8
feat: Add setUseApproovStatusIfNoToken
Mar 6, 2026
b0ba848
docs: Document setUseApproovStatusIfNoToken configuration
Mar 6, 2026
87172cb
feat: Add configurable ApproovLogLevel and setLoggingLevel API
Mar 6, 2026
b9552a1
Add loLevel description
Mar 6, 2026
4e92a88
fix: change loggingLevel from private to internal access
Mar 6, 2026
4382675
Add swift pm changes to Approov binary dependency; increase package v…
Mar 16, 2026
374e4fd
Remove test file
Mar 16, 2026
c399434
Module name for cocoapods spec file now matches swift pm
Mar 16, 2026
5b16bc5
Update documentation to reflect package name change
Mar 16, 2026
5ae8fde
Add a getter for current token header
Mar 16, 2026
5cf6637
fix: restore mutator compatibility and align Alamofire docs with curr…
Mar 17, 2026
6824a9d
fix: Approov exception for SDK already initialized is not based on st…
Mar 17, 2026
48ae004
USAGE.md now reflects multiple service layers using the same platform…
Mar 17, 2026
ed080ce
Add sfv library dependency to support message signing in podspec
Mar 18, 2026
55aa5b3
Update docs
Mar 18, 2026
89c3275
fix: restore network failure throws in interceptor handlers and gate …
Mar 20, 2026
0dc3e9f
Update version info
Mar 20, 2026
bfedf72
Update version info
Mar 20, 2026
39283ae
Merge branch 'feature/merge-remove-binary-target' of github.com:appro…
Mar 20, 2026
3bc9b5a
fix: implement backward-compatible processedRequest in ApproovDefault…
Mar 20, 2026
f63bbe5
fix: remove contradiction allowing unprotectedURL to undergo header s…
Mar 20, 2026
5e68c9a
build: add Alamofire dependency to podspec to match SwiftPM
Mar 20, 2026
b742380
Fix link to status token fetch
Mar 20, 2026
805d5b5
Minor changes to logging events
Mar 23, 2026
18b1b87
Add Alamofire specific configuration options
Mar 23, 2026
b7e9351
Update reference file
Mar 23, 2026
0287593
Remove log file
Mar 23, 2026
0a2c170
Add missing error types
Mar 23, 2026
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
52 changes: 52 additions & 0 deletions ALAMOFIRE-OPTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

# AlamoFire Options
This provides some other options available with the AlamoFire networking stack.

## Network Retry Options
The `ApproovInterceptor` class implements Alamofire's Interceptor protocol which includes an option to invoke a retry attempt in case the original request failed. We do not implement the retry option in `ApproovInterceptor`, but if you require implementing one, you should mimic the contents of the `adapt()` function and perhaps add some logic regarding retry attempts. See an example [here](https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests-with-requestinterceptor).

## Trust Manager
The `ApproovSession` object internally handles the creation of a default `AproovTrustManager` that handles dynamic pinning. You may set your own `ServerTrustManager` during construction like so:

```swift
let session = ApproovSession(serverTrustManager: manager)
```
However, if you do this then Approov dynamic pinning WILL NOT be applied.

An alternative is to use the `ApproovTrustManager` along with your own `ServerTrustEvaluating` implementations as follows:

```swift
let evaluators: [String: ServerTrustEvaluating] = [
"some.other.host.com": RevocationTrustEvaluator(),
"another.host": PinnedCertificatesTrustEvaluator()
]
let manager = ApproovTrustManager(allHostsMustBeEvaluated: true, evaluators: evaluators)
let session = ApproovSession(serverTrustManager: manager)
```

This approach will use the Approov dynamic pinning for all hosts that are being [mangaged](https://approov.io/docs/latest/approov-usage-documentation/#managing-api-domains) by Approov. Other host names will be passed to your custom evaluators. If you specify an evaluator that is also managed by Approov, then Approov will take precedence.

### Alamofire Request
If your code makes use of the default Alamofire `Session`, like so:

```swift
AF.request("https://httpbin.org/get").response { response in
debugPrint(response)
}
```

all you will need to do to use Approov is to replace the default `Session` object with the `ApproovSession`:

```swift
let approovSession = ApproovSession()
approovSession!.request("https://httpbin.org/get").responseData { response in
debugPrint(response)
}
```

## Network Delegate
You may specify your own network delegate when the `ApproovSession` is constructed as follows:

```swift
let session = ApproovSession(delegate: delegate)
```
8 changes: 6 additions & 2 deletions ApproovSession.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "ApproovSession"
s.version = "3.5.4"
s.version = "3.5.5"
s.summary = "Approov mobile attestation SDK"
s.description = <<-DESC
Approov SDK integrates security attestation and secure string fetching for both iOS and watchOS apps.
Expand All @@ -9,7 +9,8 @@ Pod::Spec.new do |s|
s.license = { :type => "Commercial", :file => "LICENSE" }
s.authors = { "Approov, Ltd." => "support@approov.io" }
s.source = { :git => "https://github.com/approov/approov-service-alamofire", :tag => s.version }

s.module_name = 'ApproovAFSession'

# Supported platforms
s.ios.deployment_target = '11.0'
s.watchos.deployment_target = '9.0'
Expand All @@ -18,6 +19,9 @@ Pod::Spec.new do |s|
s.source_files = "Sources/ApproovSession/**/*.{swift,h}"
# Dependency on the Approov SDK
s.dependency 'approov-ios-sdk', '~> 3.5.3'
# Add dependency on swift-http-structured-headers
s.dependency 'swift-http-structured-headers', '~> 1.4.0'
s.dependency 'Alamofire', '~> 5.2.0'
s.frameworks = 'Approov'
# Pod target xcconfig settings if required
s.pod_target_xcconfig = {
Expand Down
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog

All notable changes to this package will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.


## [3.5.5] - 2026-03-06

### Fixed
- Made `loggingLevel` thread-safe with a dedicated `loggingQueue` to prevent data races on concurrent reads/writes.
- Gated all `os_log` calls in `ApproovTrustManager` behind `ApproovService.loggingLevel` so that `setLoggingLevel` controls all package logging consistently.
- Fixed logging level guard mismatch in `ApproovDefaultMessageSigning` (`.info` → `.error`) and gated additional debug logs.

### Added
- Added `REFERENCE.md` and `USAGE.md` documentation to match other Approov Swift service layers.
- Separated `CHANGELOG.md` from the primary README for better discoverability.
- Introduced `ApproovServiceMutator` interface to allow customizing the behavior of the `ApproovService` during attestation and interception flows without forking the project.
- Added `setUseApproovStatusIfNoToken` configuration to `ApproovService`. When enabled, failure reasons (like `mitm_detected` or `no_network`) are placed in the Approov-Token header if a request proceeds without a valid token.
- Added `setLoggingLevel(_ level: ApproovLogLevel)` configuration for fine-grained control over the package's internal `os_log` statements. Supports `.off`, `.error`, `.warning`, `.info`, and `.debug`.
### Changed
- `ApproovDefaultMessageSigning` now gracefully skips signing and proceeds with the request without throwing an error if the install message signature is unavailable.
- `ApproovDefaultMessageSigning` now implements `ApproovServiceMutator` instead of `ApproovInterceptorExtensions`.
- `ApproovDefaultMessageSigning` now checks for the configured Approov token header via an internal synchronized accessor instead of assuming `Approov-Token`.
### Deprecated
- `ApproovInterceptorExtensions` was replaced by the much more robust `ApproovServiceMutator` protocol. The deprecated `setApproovInterceptorExtensions` API now forwards to `setServiceMutator` for backward compatibility.
### Removed
- `setProceedOnNetworkFailure()` has been removed. Use the `ApproovServiceMutator` instead to customize behavior on network failures. See `USAGE.md` for examples of how to implement a custom mutator.
8 changes: 4 additions & 4 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 11 additions & 15 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,43 @@
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
// Release tag
let releaseTAG = "3.5.4"
let releaseTAG = "3.5.5"
// SDK package version (used for both iOS and watchOS)
let sdkVersion = "3.5.3"

let package = Package(
name: "ApproovSession",
name: "ApproovAFSession",
platforms: [
.iOS(.v11),
.watchOS(.v9)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "ApproovSession",
targets: ["ApproovSession"]
name: "ApproovAFSession",
targets: ["ApproovAFSession"]
),
.library(name: "ApproovSessionDynamic", type: .dynamic, targets: ["ApproovSession"])
.library(name: "ApproovAFSessionDynamic", type: .dynamic, targets: ["ApproovAFSession"])
],
dependencies: [
// Package's external dependencies and from where they can be fetched:
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.2.0")),
.package(url: "https://github.com/apple/swift-http-structured-headers.git", from: "1.0.0")
.package(url: "https://github.com/apple/swift-http-structured-headers.git", from: "1.0.0"),
// Force-unwrapping is safe here because sdkVersion is a valid semantic version string
.package(url: "https://github.com/approov/approov-ios-sdk.git", from: Version(sdkVersion)!)
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "ApproovSession",
name: "ApproovAFSession",
dependencies: [
"Approov",
"Alamofire",
.product(name: "Approov", package: "approov-ios-sdk"),
.product(name: "Alamofire", package: "Alamofire"),
.product(name: "RawStructuredFieldValues", package: "swift-http-structured-headers")
],
path: "Sources/ApproovSession", // Point to the shared source code
exclude: ["README.md", "LICENSE"]
),
// Binary target for the merged xcframework
.binaryTarget(
name: "Approov",
url: "https://github.com/approov/approov-ios-sdk/releases/download/\(sdkVersion)/Approov.xcframework.zip",
checksum: "acfbee9e6c8009535c070c87c0d5756c2ba8f78e7b8147d7632f12bfcb940c89" // SHA256 checksum of the xcframework zip file
)
]
)
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,22 @@
A wrapper for the [Approov SDK](https://github.com/approov/approov-ios-sdk) to enable easy integration when using [`Alamofire`](https://github.com/Alamofire/Alamofire) for making the API calls that you wish to protect with Approov. In order to use this you will need a trial or paid [Approov](https://www.approov.io) account.

Please see the [Quickstart](https://github.com/approov/quickstart-ios-swift-alamofire) for usage instructions.

## Swift Package Manager Import

When adding this package with Swift Package Manager, import the module as:

```swift
import ApproovAFSession
```

The primary Alamofire session type remains `ApproovSession`.

## Documentation

This repository includes several Markdown files to help you understand and configure the Approov Service:

- [**README.md**](README.md) - This file, providing a basic overview and import instructions.
- [**USAGE.md**](USAGE.md) - Detailed guide on the features and functionality of the Approov Service, including how to interact with the service layer, customize its behavior with `ApproovServiceMutator`, and setup token binding or message signing.
- [**ALAMOFIRE-OPTIONS.md**](ALAMOFIRE-OPTIONS.md) - Additional options specifically available with the Alamofire networking stack, such as network retry options and customizing the `Session`, `ServerTrustManager`, or network delegates.
- [**CHANGELOG.md**](CHANGELOG.md) - Record of all notable changes, new features, and bug fixes for each version of the package.
Loading