Anonymous
IOS EXC_BAD_ACCESS при запуске камеры HyperVerge KYC из приложения React Native Expo (Android работает)
Сообщение
Anonymous » 20 ноя 2025, 08:02
Я интегрирую
HyperVerge в качестве своего поставщика KYC в приложение
React Native + Expo .
На
Android все работает нормально. В
iOS порядок действий следующий:
HyperVerge успешно фиксирует лицо пользователя
Когда SDK запрашивает захват документа и я выбираю «Снимок с камеры» , приложение немедленно аварийно завершает работу
Я не вижу ошибок JS — только родной сбой:
Код: Выделить всё
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
Я использую последние версии Expo / React Native / HyperVerge RN SDK (управляемый рабочий процесс с помощью специального клиента разработки).
Встроенная настройка iOS (AppDelegate.swift)
Это мой AppDelegate, созданный Expo с помощью React Native + Expo Factory:
Код: Выделить всё
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: @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
Я вызываю HyperVerge SDK с экрана KYC:
Код: Выделить всё
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());
useHideBottomNav();
const handleStartKYC = async () => {
setLoading(true);
try {
// iOS camera permission
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;
}
}
if (!Hyperkyc) {
showError('SDK Error', 'HyperKYC SDK module not found. Please ensure the native module is properly linked.');
setLoading(false);
return;
}
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.');
setLoading(false);
return;
}
// new transaction ID
transactionIdRef.current = generateTransactionId();
const configDictionary: any = {
appId: HYPERKYC_CONFIG.appId,
appKey: HYPERKYC_CONFIG.appKey,
transactionId: transactionIdRef.current,
workflowId: HYPERKYC_CONFIG.workflowId,
inputs: {},
};
// 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...');
Hyperkyc.launch(configDictionary, (response: any) => {
setLoading(false);
console.log('HyperKYC Response:', response);
if (Hyperkyc && Hyperkyc.removeAllEventListeners) {
Hyperkyc.removeAllEventListeners();
}
const sdkStatus = response?.status || 'needs_review';
if (sdkStatus === 'auto_approved') {
handleVerificationComplete();
} else if (sdkStatus === 'auto_declined') {
handleVerificationError('KYC verification was declined.');
} else if (sdkStatus === 'user_cancelled') {
console.log('User cancelled KYC verification');
} else if (
sdkStatus === 'needs_review' ||
sdkStatus === 'success' ||
sdkStatus === 'completed'
) {
handleVerificationComplete();
} else if (sdkStatus === 'error' || sdkStatus === 'failed') {
handleVerificationError(response?.error || response?.message || 'Verification failed');
} else {
console.log('Unknown KYC status:', sdkStatus);
handleVerificationComplete();
}
});
} catch (error: any) {
setLoading(false);
showError('Verification Failed', error?.message || 'Failed to start verification');
console.error('HyperKYC launch error:', error);
}
};
const handleVerificationComplete = () => {
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);
};
// ... JSX omitted for brevity
}
Что я вижу
Этап захвата лица работает
Когда HyperVerge запрашивает документ и я нажимаю Захватить с камеры , приложение вылетает с ошибкой:
Код: Выделить всё
Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
Нет полезных журналов в консоли Metro / JS
Реализация Android с тем же кодом RN работает нормально
Среда
Expo SDK : (например, 51/52 — пожалуйста, заполните)
React Native : (версия, используемая текущим Expo SDK)
HyperVerge RN SDK : (точная версия)
iOS : (устройство или симулятор, например iOS) 18 на iPhone 15)
Xcode : (версия)
Что я пробовал
Проверенные разрешения камеры на iOS (с помощью expo-image-picker)
Проверено, что собственный модуль Hyperkyc определен
Проверено, что appId, appKey и workflowId установлены правильно
Записан словарь конфигурации перед вызовом Hyperkyc.launch
Очищено папка сборки, переустановка модулей, пересборка приложения
Проверено как на симуляторе, так и на физическом устройстве
Вопрос
Есть ли что-то явно неправильное или отсутствующее в моей интеграции с iOS/Expo , что может привести к EXC_BAD_ACCESSкогда HyperVerge открывает камеру для шага документа?
Известна ли какая-либо несовместимость между RN SDK HyperVerge и клиентом разработки Expo / Expo на iOS?
Как я могу получить более подробную информацию о сбое для такого рода EXC_BAD_ACCESS (любые конкретные настройки Xcode/символики, которые мне следует включить)?
Будем признательны за любые подсказки о том, что изменить в настройке iOS или как правильно интегрировать SDK HyperVerge с Expo на iOS.
Подробнее здесь:
https://stackoverflow.com/questions/798 ... ive-expo-a
1763614970
Anonymous
Я интегрирую [b]HyperVerge[/b] в качестве своего поставщика KYC в приложение [b]React Native + Expo[/b]. На [b]Android[/b] все работает нормально. В [b]iOS[/b] порядок действий следующий: [list] [*]HyperVerge успешно фиксирует лицо пользователя [*]Когда SDK запрашивает захват документа и я выбираю [b]«Снимок с камеры»[/b], приложение [b]немедленно аварийно завершает работу[/b] [*]Я не вижу ошибок JS — только родной сбой: [/list] [code]Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) [/code] Я использую последние версии Expo / React Native / HyperVerge RN SDK (управляемый рабочий процесс с помощью специального клиента разработки). Встроенная настройка iOS (AppDelegate.swift) Это мой AppDelegate, созданный Expo с помощью React Native + Expo Factory: [code]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: @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 } } [/code] Сторона React Native Я вызываю HyperVerge SDK с экрана KYC: [code]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()); useHideBottomNav(); const handleStartKYC = async () => { setLoading(true); try { // iOS camera permission 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; } } if (!Hyperkyc) { showError('SDK Error', 'HyperKYC SDK module not found. Please ensure the native module is properly linked.'); setLoading(false); return; } 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.'); setLoading(false); return; } // new transaction ID transactionIdRef.current = generateTransactionId(); const configDictionary: any = { appId: HYPERKYC_CONFIG.appId, appKey: HYPERKYC_CONFIG.appKey, transactionId: transactionIdRef.current, workflowId: HYPERKYC_CONFIG.workflowId, inputs: {}, }; // 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...'); Hyperkyc.launch(configDictionary, (response: any) => { setLoading(false); console.log('HyperKYC Response:', response); if (Hyperkyc && Hyperkyc.removeAllEventListeners) { Hyperkyc.removeAllEventListeners(); } const sdkStatus = response?.status || 'needs_review'; if (sdkStatus === 'auto_approved') { handleVerificationComplete(); } else if (sdkStatus === 'auto_declined') { handleVerificationError('KYC verification was declined.'); } else if (sdkStatus === 'user_cancelled') { console.log('User cancelled KYC verification'); } else if ( sdkStatus === 'needs_review' || sdkStatus === 'success' || sdkStatus === 'completed' ) { handleVerificationComplete(); } else if (sdkStatus === 'error' || sdkStatus === 'failed') { handleVerificationError(response?.error || response?.message || 'Verification failed'); } else { console.log('Unknown KYC status:', sdkStatus); handleVerificationComplete(); } }); } catch (error: any) { setLoading(false); showError('Verification Failed', error?.message || 'Failed to start verification'); console.error('HyperKYC launch error:', error); } }; const handleVerificationComplete = () => { 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); }; // ... JSX omitted for brevity } [/code] Что я вижу [list] [*]Этап захвата лица работает [*]Когда HyperVerge запрашивает документ и я нажимаю [b]Захватить с камеры[/b], приложение вылетает с ошибкой: [/list] [code]Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) [/code] [list] [*]Нет полезных журналов в консоли Metro / JS [*]Реализация Android с тем же кодом RN работает нормально [/list] Среда [list] [*][b]Expo SDK[/b]: (например, 51/52 — пожалуйста, заполните) [*][b]React Native[/b]: (версия, используемая текущим Expo SDK) [*][b]HyperVerge RN SDK[/b]: (точная версия) [*][b]iOS[/b]: (устройство или симулятор, например iOS) 18 на iPhone 15) [*][b]Xcode[/b]: (версия) [/list] Что я пробовал [list] [*]Проверенные разрешения камеры на iOS (с помощью expo-image-picker) [*]Проверено, что собственный модуль Hyperkyc определен [*]Проверено, что appId, appKey и workflowId установлены правильно [*]Записан словарь конфигурации перед вызовом Hyperkyc.launch [*]Очищено папка сборки, переустановка модулей, пересборка приложения [*]Проверено как на симуляторе, так и на физическом устройстве [/list] Вопрос [list] [*]Есть ли что-то явно неправильное или отсутствующее в моей [b]интеграции с iOS/Expo[/b], что может привести к EXC_BAD_ACCESSкогда HyperVerge открывает камеру для шага документа? [*]Известна ли какая-либо несовместимость между [b]RN SDK HyperVerge[/b] и [b]клиентом разработки Expo / Expo[/b] на iOS? [*]Как я могу получить [b]более подробную информацию о сбое[/b] для такого рода EXC_BAD_ACCESS (любые конкретные настройки Xcode/символики, которые мне следует включить)? [/list] Будем признательны за любые подсказки о том, что изменить в настройке iOS или как правильно интегрировать SDK HyperVerge с Expo на iOS. Подробнее здесь: [url]https://stackoverflow.com/questions/79825104/ios-exc-bad-access-when-launching-hyperverge-kyc-camera-from-react-native-expo-a[/url]