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
12 changes: 11 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ jobs:
target: ConsumerAutoDetection
- product: DiditSDKNFC
target: ConsumerNFC
- product: DiditSDKLocation
target: ConsumerAllLocation
- product: DiditSDKCoreLocation
target: ConsumerCoreLocation
- product: DiditSDKNFCLocation
target: ConsumerNFCLocation
- product: DiditSDKSignals
target: ConsumerSignals
- product: DiditAuth
target: ConsumerAuth
steps:
- uses: actions/checkout@v4

Expand All @@ -56,7 +66,7 @@ jobs:
strategy:
fail-fast: false
matrix:
subspec: [Core, AutoDetection, NFC, All]
subspec: [Core, AutoDetection, NFC, All, Core-Location, NFC-Location, All-Location, Signals, Auth]
steps:
- uses: actions/checkout@v4

Expand Down
48 changes: 44 additions & 4 deletions DiditSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
Pod::Spec.new do |s|
s.name = 'DiditSDK'
s.version = '4.9.1'
s.version = '4.11.0'
s.summary = 'Didit Identity Verification SDK for iOS'
s.description = <<-DESC
Modular identity verification SDK. Install Core for the bare minimum,
add AutoDetection for MediaPipe-based auto capture, add NFC for passport
chip reading, or install All for the complete feature set.
Modular identity verification SDK. Every verification variant (Core, NFC,
All) includes auto capture through the Didit tiny detectors. Install Core
for the smallest build, NFC for passport chip reading, or All for the
complete feature set; AutoDetection is deprecated and identical to Core.
Core-Location, NFC-Location and All-Location are those variants with the
Location verification step (Core Location). Auth is authentication on its
own (DiditAuth) and Signals is device signals and event submission on their
own, with no verification UI; every verification variant includes both.
DESC

s.homepage = 'https://github.com/didit-protocol/sdk-ios'
Expand Down Expand Up @@ -45,6 +50,7 @@ SOFTWARE.

shared_frameworks = ['UIKit', 'SwiftUI', 'AVFoundation']
passport_frameworks = ['CoreNFC']
location_frameworks = ['CoreLocation']

s.subspec 'Core' do |core|
core.vendored_frameworks = 'Core/DiditSDK.xcframework'
Expand All @@ -67,4 +73,38 @@ SOFTWARE.
all.vendored_frameworks = 'All/DiditSDK.xcframework', 'All/OpenSSL.xcframework'
all.frameworks = shared_frameworks + passport_frameworks
end

# The verification variants with the Location module compiled in (the INCLUDE_LOCATION=true
# builds): Core Location linked, and the module's privacy manifest in every framework slice.
# Each replaces its plain variant, like every subspec here: pick exactly one.
s.subspec 'Core-Location' do |core|
core.vendored_frameworks = 'Core-Location/DiditSDK.xcframework'
core.frameworks = shared_frameworks + location_frameworks
end

s.subspec 'NFC-Location' do |nfc|
nfc.ios.deployment_target = '15.0'
nfc.vendored_frameworks = 'NFC-Location/DiditSDK.xcframework', 'NFC-Location/OpenSSL.xcframework'
nfc.frameworks = shared_frameworks + passport_frameworks + location_frameworks
end

s.subspec 'All-Location' do |all|
all.ios.deployment_target = '15.0'
all.vendored_frameworks = 'All-Location/DiditSDK.xcframework', 'All-Location/OpenSSL.xcframework'
all.frameworks = shared_frameworks + passport_frameworks + location_frameworks
end

# Device signals and event submission on their own, with no verification UI:
# `import DiditSDK`, then `DiditSignals`.
s.subspec 'Signals' do |signals|
signals.vendored_frameworks = 'Signals/DiditSDK.xcframework'
signals.frameworks = ['UIKit', 'AVFoundation', 'CryptoKit', 'DeviceCheck', 'Security']
end

# Authentication on its own: `import DiditAuth`.
s.subspec 'Auth' do |auth|
auth.ios.deployment_target = '15.0'
auth.vendored_frameworks = 'Auth/DiditAuth.xcframework'
auth.frameworks = ['UIKit', 'AVFoundation', 'AuthenticationServices', 'CryptoKit', 'DeviceCheck', 'Security']
end
end
47 changes: 40 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import PackageDescription

let version = "4.9.1"
let version = "4.11.0"
let releaseURL = "https://github.com/didit-protocol/sdk-ios/releases/download/\(version)"

let package = Package(
Expand All @@ -14,33 +14,66 @@ let package = Package(
.library(name: "DiditSDK", targets: ["DiditSDKAllBinary", "OpenSSLBinary"]),
.library(name: "DiditSDKCore", targets: ["DiditSDKCoreBinary"]),
.library(name: "DiditSDKAutoDetection", targets: ["DiditSDKAutoDetectionBinary"]),
.library(name: "DiditSDKNFC", targets: ["DiditSDKNFCBinary", "OpenSSLBinary"])
.library(name: "DiditSDKNFC", targets: ["DiditSDKNFCBinary", "OpenSSLBinary"]),
// The variants above with the Location verification step (Core Location); each replaces its plain one.
.library(name: "DiditSDKLocation", targets: ["DiditSDKAllLocationBinary", "OpenSSLBinary"]),
.library(name: "DiditSDKCoreLocation", targets: ["DiditSDKCoreLocationBinary"]),
.library(name: "DiditSDKNFCLocation", targets: ["DiditSDKNFCLocationBinary", "OpenSSLBinary"]),
// Device signals and event submission on their own (`import DiditSDK`); the products above include them.
.library(name: "DiditSDKSignals", targets: ["DiditSDKSignalsBinary"]),
// Authentication on its own (`import DiditAuth`, iOS 15+); the products above include it.
.library(name: "DiditAuth", targets: ["DiditAuthBinary"])
],
targets: [
.binaryTarget(
name: "DiditSDKAllBinary",
url: "\(releaseURL)/DiditSDK.xcframework.zip",
checksum: "99719d054d3cf3abbec5cd63eed50498dfd8ce90cdc41fc5d150d3e7ecbcb89c"
checksum: "b8abe51a4ddf2cd61985999d33ba24c3f4efdd10dfd0cbb989fc7706c0b5b000"
),
.binaryTarget(
name: "DiditSDKCoreBinary",
url: "\(releaseURL)/DiditSDK-Core.xcframework.zip",
checksum: "ba416a76cf7e3f7f57a90c31a63c2b8499e2de6e7c9a8830a2b30e5ad2a61831"
checksum: "296bae547cec6462dcefca56264f921240d3e114febf44cfc98706ac71f5bbe0"
),
.binaryTarget(
name: "DiditSDKAutoDetectionBinary",
url: "\(releaseURL)/DiditSDK-AutoDetection.xcframework.zip",
checksum: "cbf5684d57477926874fb88e09f9283fc7b10f572d3e165b2c40153149f01cfe"
checksum: "b40ab7743618f84ba31b5769c4b496b4f14391723fed1333d76d2d8737690e69"
),
.binaryTarget(
name: "DiditSDKNFCBinary",
url: "\(releaseURL)/DiditSDK-NFC.xcframework.zip",
checksum: "b200b4cb5ede371eaff5d3d34fc286708b07a7c583b37b0573bb99ad7b86d449"
checksum: "73459f3afaddf7a7e14c8b82ca129ae9ed767e2585fb86543112ac566029042a"
),
.binaryTarget(
name: "DiditSDKAllLocationBinary",
url: "\(releaseURL)/DiditSDK-Location.xcframework.zip",
checksum: "447bd34c1b5892dbe3b7859efa0eda894cc642cb15fdc21ddd3e9715dee3ba17"
),
.binaryTarget(
name: "DiditSDKCoreLocationBinary",
url: "\(releaseURL)/DiditSDK-Core-Location.xcframework.zip",
checksum: "3b7feec4b5720c62a6883c183fcab438b2326db4289c2ba1c9656a7a74521a0e"
),
.binaryTarget(
name: "DiditSDKNFCLocationBinary",
url: "\(releaseURL)/DiditSDK-NFC-Location.xcframework.zip",
checksum: "9790d048920f0b43289ed386e80bd3f2297ade8c6e4f3ea5e797772e6a9b0a34"
),
.binaryTarget(
name: "DiditSDKSignalsBinary",
url: "\(releaseURL)/DiditSDK-Signals.xcframework.zip",
checksum: "a72659876982396d5f1e5b8550cf565ba8b963581168f7ede5f0a28ccb07a6ea"
),
.binaryTarget(
name: "OpenSSLBinary",
url: "\(releaseURL)/OpenSSL.xcframework.zip",
checksum: "3a0887a9c54ceb2a905229a078a126a4a0066f9636ab9beeb2aa37858c70db2a"
checksum: "2ac4bea658b31d6e583716654f7a39b35216f8877d53c1b60fc8de3d87da5d50"
),
.binaryTarget(
name: "DiditAuthBinary",
url: "\(releaseURL)/DiditAuth.xcframework.zip",
checksum: "ec3f5aefe606d6de7140cc7b761bd84ddc62c683fff86b229b7357dca2bf2f79"
)
]
)
46 changes: 32 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,25 @@ A lightweight iOS SDK for identity verification. Server-driven, minimal configur

## SDK Variants

Starting with `4.0.0` the SDK is split into four installable variants so apps only pay the binary cost of features they actually use.

| Variant | NFC passport reading | Auto-detection | Device-slice Mach-O | Use when |
|---------|----------------------|--------------------------|--------------------:|----------|
| `Core` | – | – | **~11.1 MB** | smallest footprint, manual capture only |
| `NFC` | ✓ | – | ~11.7 MB *(plus OpenSSL, ~4 MB)* | passport chip reading without auto capture |
| `AutoDetection` | – | ✓ | ~16.0 MB | auto capture without passport chip reading |
| `All` | ✓ | ✓ | ~16.6 MB *(plus OpenSSL, ~4 MB)* | every feature (default subspec) |

Numbers above are the `ios-arm64` slice Mach-O, measured from release 4.9.0.
The SDK ships in installable variants so apps only pay for the features they use. Since `4.10.0` every variant includes auto capture.

| Variant | NFC passport reading | Auto capture | Location verification | Use when |
|---------|----------------------|--------------|-----------------------|----------|
| `Core` | – | ✓ | – | smallest footprint |
| `NFC` | ✓ | ✓ | – | passport chip reading |
| `AutoDetection` | – | ✓ | – | deprecated, identical to `Core`; switch to `Core` |
| `All` | ✓ | ✓ | – | every feature (default subspec) |
| `Core-Location` | – | ✓ | ✓ | `Core` with the Location verification step |
| `NFC-Location` | ✓ | ✓ | ✓ | `NFC` with the Location verification step |
| `All-Location` | ✓ | ✓ | ✓ | `All` with the Location verification step |

What each variant adds to an app, measured per release: [iOS SDK installation](https://docs.didit.me/integration/native-sdks/ios-sdk#installation).
The detection models are downloaded at runtime and cached, so they do not contribute to the app bundle size.
Core and NFC omit the automatic-capture ML runtime.
Only the Location variants link Core Location; each carries the privacy manifest for the location it collects.
NFC and All additionally embed `OpenSSL.xcframework`.
App Store delivery compresses these binaries; use App Store Connect's app size report for the exact per-device download size.

The `AutoDetection` and `NFC` subspecs depend on `Core`; `All` depends on both. Pick exactly one subspec in your `Podfile` and exactly one library product in your `Package.swift`.
Each subspec and library product is one complete prebuilt framework: pick exactly one subspec in your `Podfile` and exactly one library product in your `Package.swift`.

## Permissions

Expand Down Expand Up @@ -131,8 +134,13 @@ Pick exactly one library product to match your chosen variant:
| `AutoDetection` | `DiditSDKAutoDetection` |
| `NFC` | `DiditSDKNFC` |
| `All` (default) | `DiditSDK` |
| `Core-Location` | `DiditSDKCoreLocation` |
| `NFC-Location` | `DiditSDKNFCLocation` |
| `All-Location` | `DiditSDKLocation` |
| `Signals` (device signals and event submission only) | `DiditSDKSignals` |
| `Auth` (authentication only, iOS 15+) | `DiditAuth` |

In all cases your app code imports the same module: `import DiditSDK`.
Every product except `DiditAuth` is imported as `import DiditSDK`. The verification variants include signals and authentication; `Auth` on its own is imported as `import DiditAuth`.

> **Swift Package Manager does not enforce the iOS 15 floor for you.** `Package.swift` declares
> `platforms: [.iOS(.v13)]` for the whole package — SwiftPM has no per-product platform
Expand All @@ -152,6 +160,11 @@ pod 'DiditSDK/All', :podspec => podspec_url
# pod 'DiditSDK/Core', :podspec => podspec_url # platform :ios, '13.0'
# pod 'DiditSDK/AutoDetection', :podspec => podspec_url # platform :ios, '13.0'
# pod 'DiditSDK/NFC', :podspec => podspec_url # platform :ios, '15.0'
# pod 'DiditSDK/Core-Location', :podspec => podspec_url # platform :ios, '13.0', Core with Location verification
# pod 'DiditSDK/NFC-Location', :podspec => podspec_url # platform :ios, '15.0', NFC with Location verification
# pod 'DiditSDK/All-Location', :podspec => podspec_url # platform :ios, '15.0', All with Location verification
# pod 'DiditSDK/Signals', :podspec => podspec_url # platform :ios, '13.0', device signals and events only
# pod 'DiditSDK/Auth', :podspec => podspec_url # platform :ios, '15.0', authentication only
```

Pick exactly one subspec. `Core` and `AutoDetection` deploy down to iOS 13; `NFC` and `All` require iOS 15 because of `NFCPassportReader`.
Expand Down Expand Up @@ -184,6 +197,11 @@ Each release publishes one XCFramework per variant. Pick the variant you want, d
| `AutoDetection` | `DiditSDK-AutoDetection.xcframework.zip` |
| `NFC` | `DiditSDK-NFC.xcframework.zip` + `OpenSSL.xcframework.zip` |
| `All` | `DiditSDK.xcframework.zip` + `OpenSSL.xcframework.zip` |
| `Core-Location` | `DiditSDK-Core-Location.xcframework.zip` |
| `NFC-Location` | `DiditSDK-NFC-Location.xcframework.zip` + `OpenSSL.xcframework.zip` |
| `All-Location` | `DiditSDK-Location.xcframework.zip` + `OpenSSL.xcframework.zip` |
| `Signals` | `DiditSDK-Signals.xcframework.zip` |
| `Auth` | `DiditAuth.xcframework.zip` |

Extract each zip and set the embed option to **Embed & Sign** under **Frameworks, Libraries, and Embedded Content**.

Expand Down Expand Up @@ -578,7 +596,7 @@ The install surface is split into four variants. Most integrations keep working

### 4.1.0
- Native wallet-ownership verification flow (method picker, message signing, screenshot upload, self-declaration, satoshi/micro-deposit test, completion/expired) styled like the verification process, launched natively for the `wallet_ownership` action via the public `DiditSdk.presentWalletOwnership(widgetToken:)`.
- WalletConnect message signing behind an optional `DiditSDK/WalletConnect` subspec (reown-swift / ReownAppKit, iOS 15+): EVM `personal_sign` and Solana `solana_signMessage`, enabled with `DiditSdk.enableWalletConnect(projectId:appGroupIdentifier:)`. The core SDK stays iOS 13 and ships a no-op signer by default, so apps that don't need signing are unaffected.
- WalletConnect message signing behind an optional `DiditSDK/WalletConnect` subspec (reown-swift / ReownAppKit, iOS 15+): EVM `personal_sign` and Solana `solana_signMessage`, enabled with `DiditSdk.enableWalletConnect(projectId:appGroupIdentifier:)`. The core SDK stays iOS 13 and ships a no-op signer by default, so apps that don't need signing are unaffected. **Correction:** the subspec builds from the mobile-sdks source only; this podspec and the Swift Package Manager products have never included it. Since 4.10.0, without a signer the flow does not offer message signing, and a transaction opens the web flow when a proof allows only message signing.
- Transaction submission: native `submitTransaction` / `getTransaction`. A `wallet_ownership` required-action auto-launches the native flow; a `verification_session` action is returned on `result.actionRequired` (type, url, sessionId, sessionToken, status) for your existing `startVerification` / `.diditVerification` integration. Concurrent submissions are de-duplicated so a second call can't clobber an in-flight verification.
- New document quality-check screen validates the captured document (framing/crop) before it is uploaded.
- Full-color Didit logo on the verification welcome and wallet-ownership entry screens (the muted mark stays in the "Secured by" footer), and white-label logos now support SVG sources.
Expand Down
27 changes: 26 additions & 1 deletion ci/ConsumerSmoke/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ let package = Package(
.library(name: "ConsumerAll", targets: ["ConsumerAll"]),
.library(name: "ConsumerCore", targets: ["ConsumerCore"]),
.library(name: "ConsumerAutoDetection", targets: ["ConsumerAutoDetection"]),
.library(name: "ConsumerNFC", targets: ["ConsumerNFC"])
.library(name: "ConsumerNFC", targets: ["ConsumerNFC"]),
.library(name: "ConsumerAllLocation", targets: ["ConsumerAllLocation"]),
.library(name: "ConsumerCoreLocation", targets: ["ConsumerCoreLocation"]),
.library(name: "ConsumerNFCLocation", targets: ["ConsumerNFCLocation"]),
.library(name: "ConsumerSignals", targets: ["ConsumerSignals"]),
.library(name: "ConsumerAuth", targets: ["ConsumerAuth"])
],
dependencies: [
.package(name: "DiditSDK", path: "../..")
Expand All @@ -38,6 +43,26 @@ let package = Package(
.target(
name: "ConsumerNFC",
dependencies: [.product(name: "DiditSDKNFC", package: "DiditSDK")]
),
.target(
name: "ConsumerAllLocation",
dependencies: [.product(name: "DiditSDKLocation", package: "DiditSDK")]
),
.target(
name: "ConsumerCoreLocation",
dependencies: [.product(name: "DiditSDKCoreLocation", package: "DiditSDK")]
),
.target(
name: "ConsumerNFCLocation",
dependencies: [.product(name: "DiditSDKNFCLocation", package: "DiditSDK")]
),
.target(
name: "ConsumerSignals",
dependencies: [.product(name: "DiditSDKSignals", package: "DiditSDK")]
),
.target(
name: "ConsumerAuth",
dependencies: [.product(name: "DiditAuth", package: "DiditSDK")]
)
]
)
6 changes: 6 additions & 0 deletions ci/ConsumerSmoke/Sources/ConsumerAllLocation/Smoke.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import DiditSDK

// The import above IS the test: it compiles the binary framework's
// .swiftinterface, which is what broke for every consumer in 4.7.0
// ("no such module 'TensorFlowLite'"). Kept API-free on purpose so this file
// never needs updating alongside SDK releases.
6 changes: 6 additions & 0 deletions ci/ConsumerSmoke/Sources/ConsumerAuth/Smoke.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import DiditAuth

// The import above IS the test: it compiles the binary framework's
// .swiftinterface, which is what broke for every consumer in 4.7.0
// ("no such module 'TensorFlowLite'"). Kept API-free on purpose so this file
// never needs updating alongside SDK releases.
6 changes: 6 additions & 0 deletions ci/ConsumerSmoke/Sources/ConsumerCoreLocation/Smoke.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import DiditSDK

// The import above IS the test: it compiles the binary framework's
// .swiftinterface, which is what broke for every consumer in 4.7.0
// ("no such module 'TensorFlowLite'"). Kept API-free on purpose so this file
// never needs updating alongside SDK releases.
6 changes: 6 additions & 0 deletions ci/ConsumerSmoke/Sources/ConsumerNFCLocation/Smoke.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import DiditSDK

// The import above IS the test: it compiles the binary framework's
// .swiftinterface, which is what broke for every consumer in 4.7.0
// ("no such module 'TensorFlowLite'"). Kept API-free on purpose so this file
// never needs updating alongside SDK releases.
6 changes: 6 additions & 0 deletions ci/ConsumerSmoke/Sources/ConsumerSignals/Smoke.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import DiditSDK

// The import above IS the test: it compiles the binary framework's
// .swiftinterface, which is what broke for every consumer in 4.7.0
// ("no such module 'TensorFlowLite'"). Kept API-free on purpose so this file
// never needs updating alongside SDK releases.
Loading