FAQ and troubleshooting
What is the minimum iOS version?
Section titled “What is the minimum iOS version?”iOS 13.0. Set platform :ios, '13.0' in your Podfile. You also need CocoaPods 1.16 or later. See Installation.
pod install can’t find techsigncloudlibs or asks for credentials. What’s wrong?
Section titled “pod install can’t find techsigncloudlibs or asks for credentials. What’s wrong?”The pod is distributed from Techsign’s private spec repository on GitHub (https://github.com/Techsign/PODSPECS.git). Your GitHub account needs read access to it; ask your Techsign representative. Use your normal Git credential helper or SSH key for access, and don’t put access tokens in the Podfile or the repository URL.
Do I open the .xcodeproj or the .xcworkspace?
Section titled “Do I open the .xcodeproj or the .xcworkspace?”After pod install, always open the .xcworkspace.
Can I test on the iOS Simulator?
Section titled “Can I test on the iOS Simulator?”The flow needs the camera and, for the NFC step, the NFC reader, which the Simulator doesn’t have. Test the verification steps on a real iPhone.
The app crashes when it opens the camera or the NFC reader.
Section titled “The app crashes when it opens the camera or the NFC reader.”iOS terminates an app that uses the camera or NFC without a usage description. Add NSCameraUsageDescription and, for NFC, NFCReaderUsageDescription to Info.plist:
<key>NSCameraUsageDescription</key><string>The camera is used to scan your ID document and verify your face.</string><key>NFCReaderUsageDescription</key><string>NFC is used to read the chip on your ID document.</string>When do I regenerate ProveIDApiClient?
Section titled “When do I regenerate ProveIDApiClient?”When the Prove ID API changes and you need a new service or field. Download the current OpenAPI definition from the API Reference tab and run OpenAPI Generator with the same options as in Installation (library=alamofire, responseAs=Result), so the examples keep working.
Tokens and security
Section titled “Tokens and security”Where do I put my Prove ID API credentials?
Section titled “Where do I put my Prove ID API credentials?”Only on your server. The app gets a short-lived access token from your own backend after the user signs in to your app. See Authentication and the Quickstart.
A call returns 401. What should I do?
Section titled “A call returns 401. What should I do?”The access token is invalid or has expired. Get a new token from your server, set it again and retry the step:
ProveIDApiClientAPI.customHeaders["Authorization"] = "Bearer \(newToken)"Can I store the token to reuse it later?
Section titled “Can I store the token to reuse it later?”No. Keep it in memory for the current verification only, and remove it when the flow ends. Don’t store it in UserDefaults, files or the Keychain, and don’t log it.
Where should I decide whether the user is verified?
Section titled “Where should I decide whether the user is verified?”On your server. The app sends the transactionId to your backend; your server checks that the transaction belongs to the signed-in user and reads the result from Prove ID. Never approve a user based only on what the app reports. See Results.
How long are document images and videos kept on the device?
Section titled “How long are document images and videos kept on the device?”They shouldn’t be kept at all. Send document images straight from memory and don’t save them to the photo library or files. Delete liveness and hologram videos as soon as they are sent:
try? FileManager.default.removeItem(at: videoURL)Which iPhones can read the ID card chip?
Section titled “Which iPhones can read the ID card chip?”iPhone 7 or later, with the NFC capability and the A0000002471001 identifier set up as in Installation. Check at runtime before showing the NFC step:
import CoreNFC
let hasNfc = NFCNDEFReaderSession.readingAvailableReading fails with AuthenticationFailed or ConnectionError.
Section titled “Reading fails with AuthenticationFailed or ConnectionError.”The document moved away from the phone or the connection dropped. Ask the user to remove the phone case, place the top of the phone on the middle of the document and hold still until reading finishes, then try again.
Reading fails with InvalidMRZKey.
Section titled “Reading fails with InvalidMRZKey.”The serial number, date of birth or expiry date passed to read doesn’t match the document. These come from the document capture result (capturedData.sno, bdat, edat); show them to the user to confirm or correct, then read again.
What date format does the NFC reader expect?
Section titled “What date format does the NFC reader expect?”dd.MM.yyyy, parsed into Date values in UTC:
let formatter = DateFormatter()formatter.dateFormat = "dd.MM.yyyy"formatter.timeZone = TimeZone(secondsFromGMT: 0)let birth = formatter.date(from: capturedData.bdat ?? "")The iOS NFC sheet closes or shows an error I handle myself.
Section titled “The iOS NFC sheet closes or shows an error I handle myself.”Return suppressError: true from the errorMessage closure for errors you show on your own screen, so iOS doesn’t also show them on the NFC sheet. The full list is in Errors.
Liveness
Section titled “Liveness”Which gesture should I ask for?
Section titled “Which gesture should I ask for?”The one Prove ID returns as gestureType when the transaction starts. Map it to LivenessController.GESTURE_TYPE:
gestureType |
GESTURE_TYPE |
|---|---|
EYE |
.EYE |
MOUTH |
.MOUTH |
HEAD-VERTICAL |
.HEAD_VERTICAL |
HEAD-HORIZONTAL |
.HEAD_HORIZONTAL |
MULTIDIR_… |
.RANDOMIZED_MULTI_GESTURE |
What does a gestureType starting with MULTIDIR_ mean?
Section titled “What does a gestureType starting with MULTIDIR_ mean?”The user turns their head in several directions in a row. The directions follow the prefix, separated by -:
let directions = gestureType.dropFirst("MULTIDIR_".count).split(separator: "-")LivenessController.GESTURE_TYPE = .RANDOMIZED_MULTI_GESTURELivenessController.RANDOMIZED_GESTURES = directions.compactMap { HeadPosition(string: String($0)) }The gesture score is low. What should I do?
Section titled “The gesture score is low. What should I do?”For head gestures, gestureModel.gestureScore tells you how well the gesture was made. When it is low (for example below 0.8), ask the user to try again and call startCapture() again. See Liveness.
onMultiFaceDetected or onVideoCanceled is called.
Section titled “onMultiFaceDetected or onVideoCanceled is called.”More than one face was in the frame, or the face left the frame during recording. Ask the user to be alone in the frame, hold the phone at eye level and try again.
I set GESTURE_TYPE but onVideoCaptured is never called.
Section titled “I set GESTURE_TYPE but onVideoCaptured is never called.”With gesture control on (IS_GESTURE_CONTROL_ENABLED = true) the video arrives in GestureDelegate.gestureControlled(gestureModel:) as gestureModel.videoURL. onVideoCaptured is used for passive video only. See Liveness.
A setting from a previous run is still active.
Section titled “A setting from a previous run is still active.”LivenessController settings are static. Set all of them before every capture session.
Coverage and open questions
Section titled “Coverage and open questions”What isn’t covered in these guides yet?
Section titled “What isn’t covered in these guides yet?”These appear in the sample apps and/or the OpenAPI definition, but are not walked through in the iOS guides. Use the API Reference tab for the endpoints:
- International document templates:
getCountryTemplates,checkTemplateIDCard,addSecondaryTemplate transferTransaction- Trust Engine / blacklist
verify-with-voice(FaceServiceAPI.verifyFaceWithVoice)- Client settings
Token and role questions for your Prove ID contact
Section titled “Token and role questions for your Prove ID contact”Treat these as open items until your Prove ID contact confirms them for your organisation:
- Whether a
client_credentialstoken fromPOST /oauth/access_tokenis accepted for mobileid/*andface/*calls (the sample apps use username/password login on the server side) - Whether a transaction-scoped token exists
- Which least-privilege roles to assign to the dedicated mobile API user
- The full control list and score thresholds (control pass/fail in Results is decided per organisation)