iOS Quick Start
From zero to a YES verdict on an iOS device in ten minutes.
Work through Prerequisites first. You will need a license key and the two Info.plist keys.
1. Add the SDK
Swift Package Manager (recommended)
In Xcode: File → Add Packages… and enter:
https://github.com/octetproof/octet-sdk-ios
Pin to a version rather than tracking main. Or in Package.swift:
dependencies: [
.package(url: "https://github.com/octetproof/octet-sdk-ios", from: "0.0.1-alpha")
]
Then import:
import OctetSDK
Carthage
Carthage does not propagate SwiftPM transitive dependencies. Add two lines to your Cartfile:
binary "https://raw.githubusercontent.com/octetproof/octet-sdk-ios/main/OctetSDK.json" ~> 0.0
github "apple/swift-protobuf" ~> 1.28
Carthage consumers import OctetSDKCore (not OctetSDK).
2. Add Info.plist keys
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app uses your location to verify and prove your location
to services that request it.</string>
<key>NSMotionUsageDescription</key>
<string>This app uses motion data to detect when you're stationary or
moving, which improves the confidence of location proofs.</string>
Without these, the app crashes on first launch.
3. Request location permission
The SDK refuses to start until the user grants location authorization. Request it before calling Octet.start(...):
import CoreLocation
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
Wait for the authorization status callback (locationManagerDidChangeAuthorization) before continuing.
4. Start the SDK
import OctetSDK
let config = OctetConfig(licenseKey: "octet_live_v4.public.…")
let sdk = try await Octet.start(config: config)
Octet.start(...) is async throws. On first launch the SDK verifies the license key locally, exchanges it for an activation token via api.octetproof.com/v1/activate, caches the token in Keychain, and brings up the proof pipeline. On subsequent launches the cached token is reused.
Any license problem throws a typed LicenseError. See License Types for the case list.
5. Ask your first question
let verdict = await sdk.loc.isWithin(
region: .country(isoCode: "US"),
atTime: Date()
)
switch verdict.result {
case .yes:
print("YES — proof attached: \(verdict.proof != nil)")
case .no:
print("NO — provable negative")
case .indeterminate:
print("INDETERMINATE — reason: \(verdict.reason)")
}
The predicate returns an OctetVerdict. The result is a trichotomy. Never treat INDETERMINATE as NO.
6. What to expect
- On a real device, outdoors, with cellular and GPS available,
isWithin(.country(isoCode: ...))typically returnsYESwith an attached proof. - On the iOS Simulator the verdict will always be
INDETERMINATE / NO_FIXwith the messagerunning on simulator — location proofs are unavailable in this environment. This is by design. The simulator has no GNSS or motion stack, and the spoof-detection pipeline blocks proof generation. Run on hardware to see the full flow. - On a real device, indoors, the first proof may take longer or come back at
MEDIUMconfidence. See Concepts: Verdicts for how confidence relates to the verdict.
7. From here
- The OctetV1Toy sample app is a single-button SwiftUI app that exercises this whole flow.
- Concepts: Proof of Location explains what a verdict actually proves.
- API Reference Overview maps the public surface.