IOS EXC_BAD_ACCESS при запуске камеры HyperVerge KYC из приложения React Native Expo (Android работает)IOS

Программируем под IOS
Ответить
Anonymous
 IOS EXC_BAD_ACCESS при запуске камеры HyperVerge KYC из приложения React Native Expo (Android работает)

Сообщение Anonymous »

Я интегрирую 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»