iOS Crash: HyperVerge KYC camera step crashes with EXC_BAD_ACCESS (Android works) #8628
Unanswered
aadityabrainfog
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I am integrating HyperVerge KYC inside a React Native + Expo project.
The flow works normally on Android, but on iOS, the app crashes when trying to capture a document from the camera.
Crash Point
Face capture step works normally
When SDK asks for document capture → I choose Capture from Camera
App immediately crashes with this native error:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
No JS logs or error messages appear.
iOS Native Setup (AppDelegate.swift)
import Expo
import React
import ReactAppDependencyProvider
@UIApplicationMain
public class AppDelegate: ExpoAppDelegate {
var window: UIWindow?
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
var reactNativeFactory: RCTReactNativeFactory?
public override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = ExpoReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
bindReactNativeFactory(factory)
#if os(iOS) || os(tvOS)
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "main",
in: window,
launchOptions: launchOptions)
#endif
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// Linking API
public override func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
}
// Universal Links
public override func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: https://github.com/escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
}
}
class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
// Extension point for config-plugins
override func sourceURL(for bridge: RCTBridge) -> URL? {
// needed to return the correct URL for expo-dev-client.
bridge.bundleURL ?? bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
#else
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
React Native KYC Call (relevant part)
import { useNavigation } from '@react-navigation/native';
import * as ImagePicker from 'expo-image-picker';
import React, { useRef, useState } from 'react';
import { NativeModules, Platform, StyleSheet, View } from 'react-native';
import {
AuthButton,
AuthFormCard,
AuthHeader,
} from '../../components/auth';
import {
BenefitItem,
InfoSection,
KYCScreenLayout,
SkipButton,
useHideBottomNav,
} from '../../components/kyc';
import { HYPERKYC_CONFIG, generateTransactionId } from '../../constants/hyperkyc';
import { Spacing } from '../../constants/theme';
import { useAlert } from '../../contexts/AlertContext';
const { Hyperkyc } = NativeModules;
export default function KYCScreen() {
const navigation = useNavigation();
const { showError } = useAlert();
const [loading, setLoading] = useState(false);
const transactionIdRef = useRef(generateTransactionId());
// Hide bottom nav bar when this screen is focused (works in both AuthStack and SettingsStack)
useHideBottomNav();
const handleStartKYC = async () => {
setLoading(true);
try {
// Check camera permissions for iOS before starting SDK
if (Platform.OS === 'ios') {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== 'granted') {
showError(
'Camera Permission Required',
'Camera access is required for KYC verification. Please enable camera permissions in Settings.'
);
setLoading(false);
return;
}
}
// Check if HyperKYC module is available
if (!Hyperkyc) {
showError('SDK Error', 'HyperKYC SDK module not found. Please ensure the native module is properly linked.');
setLoading(false);
return;
}
// Validate configuration
if (
!HYPERKYC_CONFIG.appId ||
!HYPERKYC_CONFIG.workflowId ||
HYPERKYC_CONFIG.appId === 'YOUR_APP_ID' ||
HYPERKYC_CONFIG.workflowId === 'YOUR_WORKFLOW_ID'
) {
showError('Configuration Error', 'HyperKYC credentials not configured. Please set your appId and workflowId in constants/hyperkyc.ts');
setLoading(false);
return;
}
// Generate a new transaction ID for this verification session
transactionIdRef.current = generateTransactionId();
// Prepare configuration dictionary
const configDictionary: any = {
appId: HYPERKYC_CONFIG.appId,
appKey: HYPERKYC_CONFIG.appKey,
transactionId: transactionIdRef.current,
workflowId: HYPERKYC_CONFIG.workflowId,
inputs: {
// Add any pre-filled inputs here if needed
// bvnNumber: "number-123",
// image: "image-path"
},
};
// Generate unique ID
if (Hyperkyc.createUniqueId) {
await new Promise((resolve, reject) => {
Hyperkyc.createUniqueId((uniqueId: string) => {
if (uniqueId) {
configDictionary.uniqueId = uniqueId;
resolve();
} else {
reject(new Error('Failed to generate unique ID'));
}
});
});
}
console.log('HyperKYC Config:', configDictionary);
console.log('Launching HyperKYC...');
// Launch the HyperKYC SDK
Hyperkyc.launch(configDictionary, (response: any) => {
setLoading(false);
});
} catch (error: any) {
setLoading(false);
showError('Verification Failed', error?.message || 'Failed to start verification');
console.error('HyperKYC launch error:', error);
}
};
const handleVerificationComplete = () => {
// Navigate to completion screen
navigation.navigate('KYCComplete' as never);
};
const handleVerificationError = (error: any) => {
const errorMessage = typeof error === 'string' ? error : error?.message || 'An error occurred during verification';
showError('Verification Error', errorMessage);
};
const handleSkipForNow = () => {
navigation.navigate('RiskProfile' as never);
};
const benefits = [
{
title: 'Secure Trading',
description: 'Protect your account with verified identity',
},
{
title: 'Regulatory Compliance',
description: 'Meet SEBI and government requirements',
},
{
title: 'Faster Processing',
description: 'Quick verification and account activation',
},
];
return (
const styles = StyleSheet.create({
content: {
marginTop: Spacing.sm,
},
benefitsList: {
gap: Spacing.sm,
marginBottom: Spacing.lg,
},
startButton: {
marginTop: Spacing.sm,
},
});
What I Have Checked
Camera permissions requested using expo-image-picker
Hyperkyc module exists in NativeModules
Valid appId, appKey, and workflowId
Latest Expo + RN + HyperVerge SDK
Cleaned pods, reinstalled, rebuilt
Tried both simulator + physical device
Android implementation works fine with same config
Item | Version
Expo SDK | 54.0.12
React Native | 0.81.5
HyperVerge RN SDK | 2.2.4
iOS Version | 17.0
Device | macOS 26.0.1
Xcode | 26.0.1 (Build 17A400)
Expected Behavior
Document camera capture should open normally on iOS like it does on Android.
Actual Behavior
App crashes instantly with native EXC_BAD_ACCESS.
Question
Is this an integration issue with Expo's dev client?
Does HyperVerge’s iOS SDK require additional native configuration?
How can I enable deeper crash logs (symbolication suggestions appreciated)?
Beta Was this translation helpful? Give feedback.
All reactions