diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bde7c30..f1c3d93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 @@ -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 diff --git a/DiditSDK.podspec b/DiditSDK.podspec index 5e28546..53a3200 100644 --- a/DiditSDK.podspec +++ b/DiditSDK.podspec @@ -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' @@ -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' @@ -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 diff --git a/Package.swift b/Package.swift index bf8c2e4..0147612 100644 --- a/Package.swift +++ b/Package.swift @@ -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( @@ -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" ) ] ) diff --git a/README.md b/README.md index 7c828ab..0634303 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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`. @@ -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**. @@ -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. diff --git a/ci/ConsumerSmoke/Package.swift b/ci/ConsumerSmoke/Package.swift index dfd91ed..d2cbcd5 100644 --- a/ci/ConsumerSmoke/Package.swift +++ b/ci/ConsumerSmoke/Package.swift @@ -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: "../..") @@ -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")] ) ] ) diff --git a/ci/ConsumerSmoke/Sources/ConsumerAllLocation/Smoke.swift b/ci/ConsumerSmoke/Sources/ConsumerAllLocation/Smoke.swift new file mode 100644 index 0000000..ffe2b2e --- /dev/null +++ b/ci/ConsumerSmoke/Sources/ConsumerAllLocation/Smoke.swift @@ -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. diff --git a/ci/ConsumerSmoke/Sources/ConsumerAuth/Smoke.swift b/ci/ConsumerSmoke/Sources/ConsumerAuth/Smoke.swift new file mode 100644 index 0000000..a2a7dad --- /dev/null +++ b/ci/ConsumerSmoke/Sources/ConsumerAuth/Smoke.swift @@ -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. diff --git a/ci/ConsumerSmoke/Sources/ConsumerCoreLocation/Smoke.swift b/ci/ConsumerSmoke/Sources/ConsumerCoreLocation/Smoke.swift new file mode 100644 index 0000000..ffe2b2e --- /dev/null +++ b/ci/ConsumerSmoke/Sources/ConsumerCoreLocation/Smoke.swift @@ -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. diff --git a/ci/ConsumerSmoke/Sources/ConsumerNFCLocation/Smoke.swift b/ci/ConsumerSmoke/Sources/ConsumerNFCLocation/Smoke.swift new file mode 100644 index 0000000..ffe2b2e --- /dev/null +++ b/ci/ConsumerSmoke/Sources/ConsumerNFCLocation/Smoke.swift @@ -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. diff --git a/ci/ConsumerSmoke/Sources/ConsumerSignals/Smoke.swift b/ci/ConsumerSmoke/Sources/ConsumerSignals/Smoke.swift new file mode 100644 index 0000000..ffe2b2e --- /dev/null +++ b/ci/ConsumerSmoke/Sources/ConsumerSignals/Smoke.swift @@ -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.