Skip to content

FAQ and troubleshooting

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.

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:

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 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.

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.

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)"

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)

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.readingAvailable

Reading 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.

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.

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_GESTURE
LivenessController.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.

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_credentials token from POST /oauth/access_token is accepted for mobile id/* and face/* 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)