@yeomessagingcom/react-native-yeofr
v0.4.5
Published
React Native iOS and Android integration for YEO Face Recognition (device-only).
Downloads
1,471
Readme
@yeomessagingcom/react-native-yeofr
iOS and Android face recognition bridge for React Native.
Recognition needs a real device. The package builds and runs in the
simulator — so an app that depends on it still compiles and its tests still
run — but activate there rejects with code E_UNAVAILABLE_SIMULATOR
(exported as UNAVAILABLE_ON_SIMULATOR), the same way the camera is
unavailable.
Engine each platform resolves:
| Platform | Engine build | How it arrives |
|---|---|---|
| iOS | YEOFR 0.7.10 (device arm64 + simulator arm64) | Swift Package — YEOFR-SPM, added to your app target; not vendored in the tarball |
| Android | com.yeomessaging:yeofr-android:0.1.24 | Gradle, from the Repsy repo; pulled in transitively |
Minimum deployment target is iOS 17.0. Apple-silicon Macs only for simulator builds — the xcframework has no Intel slice.
Upgrading to 0.4.5 (iOS engine 0.7.10)
One iOS behaviour change, and one thing hosts can now stop doing:
- Enrolment is single-identity: a capture replaces the previous one. Setting
enrolNamefor a second person used to leave the first still enrolled and still recognised, and graded the second person against the first person's stored face — so the new person was often never recognised. Exactly one identity is now enrolled at a time. Hosts that expected a gallery of several people will keep only the most recent. - Cancelling a capture no longer needs cleanup. Clearing
enrolNamemid-capture cancels the walk and restores the previously enrolled identity. Before, the capture stayed latched and every later attempt failed with "Enrolment already in progress" until the camera was torn down, so hosts had to restore or clear the tracker themselves — that workaround is no longer needed and can be removed.
Upgrading from 0.3.x
Three things changed for iOS hosts, all of which need action:
- The engine is no longer vendored.
ios/YEOFR.xcframeworkis gone from the package; add the Swift Package below to your app target or the bridge will not compile. - Minimum iOS is now 17.0, up from 15.1 — raise
platform :iosin yourPodfileandIPHONEOS_DEPLOYMENT_TARGETon your app target. - Simulator builds need
EXCLUDED_ARCHS[sdk=iphonesimulator*] = x86_64(see below). Apple-silicon Macs only; there is no Intel simulator slice.
The JS API also changed, on both platforms:
createTracker()/freeTracker()are gone. The SDK owns the tracker's lifetime since activation was introduced; there is nothing to create or free.- Return codes are strings, and failures resolve instead of rejecting.
loadTracker/clearTracker/enrollImageresolve"OK"on success and a platform failure string otherwise (iOS its Swift case names, Android"error(-5)") — they no longer resolve numbers, and no longer reject on an SDK failure. Oldcatch-based handling (iOS) and=== 0checks (Android) silently invert: migrate them toisOK(await loadTracker(...)). enroll(faceID, name)is gone. Camera enrolment runs behind the bridge on both platforms: setenrolNameon<YeofrCamera>and wait forregistered.- Every SDK call now requires
activate()first and rejectsnot_activateduntil it resolves.
iOS autolinking is also fixed — in 0.3.x the CLI reported ios: null and never
installed the pod at all.
Install
npm i @yeomessagingcom/react-native-yeofr
npx yeofr-setup # iOS Swift Package + Android Repsy repo + pod install
npx yeofr-setup doctor # verifies every stepFull walkthrough, both platforms, including the manual equivalents of what the script does: docs/REACT-NATIVE-INTEGRATION.md.
The module API works with the New Architecture left on (the RN template
default). Only the camera view (YeofrCameraView, a legacy RCTViewManager)
needs the old architecture: set RCT_NEW_ARCH_ENABLED=0 (iOS) /
newArchEnabled=false (Android) only if you use the camera screen — see
Verified.
iOS
The npm package ships only the RN bridge sources — the engine is not vendored. Add it to your app target in Xcode once:
- open
ios/<YourApp>.xcworkspace→ File ▸ Add Package Dependencies… - enter
https://github.com/yeo-messaging/YEOFR-SPM.git, rule Exact Version0.7.10, add theYEOFRlibrary to your app target - Xcode links and embeds it; the CocoaPods bridge target picks the module up from the shared build products directory
Then add the post_install block to your Podfile
and re-run pod install. On Xcode 26 it is required, not a fallback — it
does two things, and each is a hard build failure without it:
- sets
EXCLUDED_ARCHS[sdk=iphonesimulator*] = x86_64on the app and Pods targets. The published xcframework has no Intel simulator slice, so without this a simulator build fails withunable to resolve module dependency: 'YEOFR'. - patches the
fmtpod (see below).
Also raise platform :ios to '17.0' in your Podfile.
Android
Add the Repsy repository to your app module — android/app/build.gradle:
repositories {
mavenCentral()
google()
maven {
name = "Repsy"
url = uri("https://repo.repsy.io/mvn/samsonyeo/yeomessaging")
}
}This is not optional and npm i cannot do it for you. Gradle resolves a
project dependency's transitive artifacts against the consuming project's
repositories, so the repositories {} block inside this package's own
android/build.gradle never applies to your :app. Without the block above
the build fails with Could not find com.yeomessaging:yeofr-android:0.1.24.
Putting it in the root project's buildscript.repositories does not work
either — that only feeds the Gradle classpath.
Declare the camera permission yourself
This package's manifest declares no permissions. The frame API works with
no camera at all, so whether your app carries a dangerous permission on its
Play listing is your call, not this library's. If you mount YeofrCamera, add
to your own AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />Without it, camera binding fails at the OS level. And declaring it is not
enough — requesting the runtime grant is also your job. The package never
prompts. Mount YeofrCamera without the grant and it reports
{ type: 'error', failure: 'permissionDenied' } through onEvent and draws
nothing; ask with PermissionsAndroid.request first, as
example/src/CameraDemoScreen.tsx does.
If your app is nothing but a recognition screen, also mark the feature required so it cannot install on a camera-less device:
<uses-feature android:name="android.hardware.camera" android:required="true" />Verified
Against a stock React Native 0.81.4 project on Xcode 26, installed from the packed tarball, with the New Architecture left on (the template default):
| Target | Result |
|---|---|
| iOS simulator (Apple silicon) | pending re-verification against 0.7.10; on 0.7.8: getVersion() → 0.7.8, activate rejects E_UNAVAILABLE_SIMULATOR |
| iPhone 17 Pro Max | 0.7.10 Release verified through a consuming app — builds, installs, runs, enrols, recognises; the tarball-path Debug run is pending re-verification |
| Samsung SM-A155F | verified against 0.1.24 from the repo's example app: builds, installs, activates, restores the enrolled gallery |
| Android emulator (API 36) | pending re-verification against 0.1.24 |
The module API works under bridgeless — example/ios/Podfile sets
RCT_NEW_ARCH_ENABLED=0 only for the camera view (YeofrCameraView is a legacy
RCTViewManager). You need that opt-out only if you use the camera screen.
Xcode 26 and the fmt pod
Not caused by this package, but every React Native 0.81 app hits it on Xcode 26 and it looks like a YEOFR failure because it surfaces during the same build:
Pods/fmt/include/fmt/format-inl.h: error: call to consteval function
'fmt::basic_format_string<...>' is not a constant expressionfmt 11.0.2 already disables its consteval path for the compilers it knows
are broken; Xcode 26's clang is not on that list. The block below forces the
same branch by patching fmt/base.h in place, and raises if the patch stops
applying rather than silently handing you back the original compile error. Drop
it once React Native ships a newer fmt.
The post_install block
Paste into your Podfile's target, alongside the react_native_post_install
call you already have:
# No Intel simulator slice in the xcframework.
installer.pods_project.targets.each do |t|
t.build_configurations.each do |bc|
bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '17.0'
bc.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'x86_64'
end
end
installer.aggregate_targets.map(&:user_project).uniq.each do |proj|
proj.targets.each do |t|
t.build_configurations.each do |bc|
bc.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'x86_64'
end
end
proj.save
end
# Xcode 26 clang rejects fmt 11.0.2's consteval path.
base_h = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h')
raise "fmt patch: #{base_h} not found — has the fmt pod moved?" unless File.exist?(base_h)
src = File.read(base_h)
needle = "#if !defined(__cpp_lib_is_constant_evaluated)\n# define FMT_USE_CONSTEVAL 0"
marker = "// Xcode 26 clang rejects fmt's consteval path"
unless src.include?(marker) # already patched: `pod install` re-runs on a patched tree
unless src.include?(needle)
raise "fmt patch: the FMT_USE_CONSTEVAL branch is not where we expect in " \
"#{base_h}. Check the pinned fmt version before removing this patch."
end
File.chmod(0644, base_h) # CocoaPods checks pod sources out read-only
File.write(base_h, src.sub(needle, "#if 1 #{marker}\n# define FMT_USE_CONSTEVAL 0"))
endLicensing
This package and the engine it integrates are commercial — see LICENSE.
Shipping it in a product requires a licence agreement, and a licence covers
only the applications it names. Email [email protected] to obtain a
licence and the .yeolicense file to pass to activate.
Bumping npm module version:
- update s.version in podspec with the new version number
- update "version" in package.json with the new version number
if the iOS engine needs updating:
- cut a YEOFR-SPM release from
the engine branch of YEOFRSDK that this package tracks (never from
main) - bump the package requirement in
example/ios/YeofrDemo.xcodeproj(Xcode: package dependency → exact version) and re-resolve - update the version in the table above and in the install steps
for Android, bump com.yeomessaging:yeofr-android in android/build.gradle.
Publishing:
- deprecate previous version (if required) (NB 0.3.13 is an example):
npm deprecate @yeomessagingcom/[email protected] "Deprecated"- tag with the latest version (
X.Y.Zbelow is a placeholder — use the real next version of the npm module):
git tag X.Y.Z
git push --tags- publish
npm publish --access public