@yeomessagingcom/react-native-yeofr 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @yeomessaging/react-native-yeofr
2
+
3
+ iOS face recognition bridge for React Native (device-only).
4
+ **Build & run on a real device.** No simulator support.
5
+
6
+ ## Install
7
+ ```bash
8
+ npm i @yeomessaging/react-native-yeofr
9
+ cd ios && pod install && cd ..
package/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { NativeModules } from 'react-native';
2
+ const { YEOFRModule } = NativeModules as any;
3
+
4
+ export const createTracker = (): Promise<number> => YEOFRModule.createTracker();
5
+ export const freeTracker = (): Promise<number> => YEOFRModule.freeTracker();
6
+ export const getTrackerData = (): Promise<string> => YEOFRModule.getTrackerData();
7
+ export const loadTracker = (base64: string): Promise<number> => YEOFRModule.loadTracker(base64);
8
+ export const enroll = (faceID: number, name: string): Promise<number> => YEOFRModule.enroll(faceID, name);
9
+ export const processFrameBase64 = (args: {
10
+ base64ARGB: string; width: number; height: number; stride: number; ratio?: number; needFaceRect?: boolean;
11
+ }) => YEOFRModule.processFrameBase64(args.base64ARGB, args.width, args.height, args.stride, args.ratio ?? 1, !!args.needFaceRect);
@@ -0,0 +1,36 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RCT_EXTERN_MODULE(YEOFRModule, NSObject)
4
+
5
+ RCT_EXTERN_METHOD(createTracker:(RCTPromiseResolveBlock)resolve
6
+ rejecter:(RCTPromiseRejectBlock)reject)
7
+
8
+ RCT_EXTERN_METHOD(freeTracker:(RCTPromiseResolveBlock)resolve
9
+ rejecter:(RCTPromiseRejectBlock)reject)
10
+
11
+ RCT_EXTERN_METHOD(resetTrackerParameters:(NSString *)paramString
12
+ resolver:(RCTPromiseResolveBlock)resolve
13
+ rejecter:(RCTPromiseRejectBlock)reject)
14
+
15
+ RCT_EXTERN_METHOD(getTrackerData:(RCTPromiseResolveBlock)resolve
16
+ rejecter:(RCTPromiseRejectBlock)reject)
17
+
18
+ RCT_EXTERN_METHOD(loadTracker:(NSString *)base64Blob
19
+ resolver:(RCTPromiseResolveBlock)resolve
20
+ rejecter:(RCTPromiseRejectBlock)reject)
21
+
22
+ RCT_EXTERN_METHOD(enroll:(nonnull NSNumber *)faceID
23
+ name:(NSString *)name
24
+ resolver:(RCTPromiseResolveBlock)resolve
25
+ rejecter:(RCTPromiseRejectBlock)reject)
26
+
27
+ RCT_EXTERN_METHOD(processFrameBase64:(NSString *)base64ARGB
28
+ width:(nonnull NSNumber *)width
29
+ height:(nonnull NSNumber *)height
30
+ stride:(nonnull NSNumber *)stride
31
+ ratio:(nonnull NSNumber *)ratio
32
+ needFaceRect:(BOOL)needFaceRect
33
+ resolver:(RCTPromiseResolveBlock)resolve
34
+ rejecter:(RCTPromiseRejectBlock)reject)
35
+
36
+ @end
@@ -0,0 +1,86 @@
1
+ import Foundation
2
+ import YEOFRSDK // from your xcframework
3
+
4
+ @objc(YEOFRModule)
5
+ class YEOFRModule: NSObject {
6
+ private let sdk = YEOFRSDK.shared
7
+ @objc static func requiresMainQueueSetup() -> Bool { false }
8
+
9
+ @objc func createTracker(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
10
+ let rc = sdk.createTracker()
11
+ rc == .OK ? resolve(rc.rawValue) : reject("rc", "createTracker failed: \(rc.rawValue)", nil)
12
+ }
13
+
14
+ @objc func freeTracker(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
15
+ let rc = sdk.freeTracker()
16
+ rc == .OK ? resolve(rc.rawValue) : reject("rc", "freeTracker failed: \(rc.rawValue)", nil)
17
+ }
18
+
19
+ @objc func resetTrackerParameters(_ _: String,
20
+ resolver resolve: RCTPromiseResolveBlock,
21
+ rejecter reject: RCTPromiseRejectBlock) {
22
+ let rc = sdk.resetTrackerParameters()
23
+ rc == .OK ? resolve(rc.rawValue) : reject("rc", "resetTrackerParameters failed: \(rc.rawValue)", nil)
24
+ }
25
+
26
+ @objc func getTrackerData(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
27
+ guard let data = sdk.faceRecognitionTrackerData() else {
28
+ return reject("no_data", "tracker data unavailable", nil)
29
+ }
30
+ resolve(data.base64EncodedString())
31
+ }
32
+
33
+ @objc func loadTracker(_ base64Blob: String,
34
+ resolver resolve: RCTPromiseResolveBlock,
35
+ rejecter reject: RCTPromiseRejectBlock) {
36
+ guard let d = Data(base64Encoded: base64Blob) else {
37
+ return reject("bad_input", "invalid base64", nil)
38
+ }
39
+ let rc = sdk.loadTracker(from: d)
40
+ rc == .OK ? resolve(rc.rawValue) : reject("rc", "loadTracker failed: \(rc.rawValue)", nil)
41
+ }
42
+
43
+ @objc func enroll(_ faceID: NSNumber,
44
+ name: String,
45
+ resolver resolve: RCTPromiseResolveBlock,
46
+ rejecter reject: RCTPromiseRejectBlock) {
47
+ let rc = sdk.enroll(faceID: faceID.int64Value, name: name, learnFromCurrentFrame: true)
48
+ rc == .OK ? resolve(rc.rawValue) : reject("rc", "enroll failed: \(rc.rawValue)", nil)
49
+ }
50
+
51
+ // JS-only helper for quick smoke tests; production should feed frames via native iOS component.
52
+ @objc func processFrameBase64(_ base64ARGB: String,
53
+ width: NSNumber,
54
+ height: NSNumber,
55
+ stride: NSNumber,
56
+ ratio: NSNumber,
57
+ needFaceRect: Bool,
58
+ resolver resolve: RCTPromiseResolveBlock,
59
+ rejecter reject: RCTPromiseRejectBlock) {
60
+ guard let bytes = Data(base64Encoded: base64ARGB) else {
61
+ return reject("bad_input", "invalid base64", nil)
62
+ }
63
+ let count = bytes.count
64
+ let ptr = UnsafeMutablePointer<UInt8>.allocate(capacity: count)
65
+ _ = bytes.copyBytes(to: ptr, count: count)
66
+
67
+ let params = ImageFrameParameters(buffer: ptr,
68
+ width: width.intValue,
69
+ height: height.intValue,
70
+ scanLine: stride.intValue,
71
+ ratio: ratio.floatValue)
72
+ let result = sdk.detectFaces(params: params, needFaceRect: needFaceRect)
73
+
74
+ var faces: [[String: Any]] = []
75
+ if let rects = result.faceRects, let ids = result.faceIDs {
76
+ for (id, rect) in rects {
77
+ faces.append([
78
+ "id": id,
79
+ "name": ids[id] ?? NSNull(),
80
+ "rect": ["x": rect.origin.x, "y": rect.origin.y, "w": rect.size.width, "h": rect.size.height]
81
+ ])
82
+ }
83
+ }
84
+ resolve(["state": result.faceState.rawValue, "count": result.detectedCount, "faces": faces])
85
+ }
86
+ }
@@ -0,0 +1,38 @@
1
+ Pod::Spec.new do |s|
2
+ s.name = "react-native-yeofr"
3
+ s.version = "0.1.3" # keep in lockstep with npm + SPM release tag
4
+ s.summary = "React Native iOS integration for YEO Face Recognition (device-only)."
5
+ s.homepage = "https://github.com/yeomessaging/react-native-yeofr"
6
+ s.license = { :type => "Commercial", :file => "../LICENSE" }
7
+ s.author = { "YEO Messaging" => "luca@yeomessaging.com" }
8
+ s.platform = :ios, "15.0"
9
+ s.swift_version = "5.9"
10
+
11
+ # Only the RN shim files (bridges are inside your xcframework)
12
+ s.source_files = "YEOFRModule.m", "YEOFRModule.swift"
13
+
14
+ # Download the binary zip from your SPM repo release assets
15
+ repo = "https://github.com/YEOMessaging/YEOFR-SPM"
16
+ zip = "YEOFR.xcframework.zip"
17
+ url = ENV['YEOFR_XCFRAMEWORK_URL'] || "#{repo}/releases/download/#{s.version}/#{zip}"
18
+ s.source = { :http => url }
19
+ # Optionally verify integrity:
20
+ # s.source = { :http => url, :sha256 => "PUT_SHA256_HERE" }
21
+
22
+ s.prepare_command = <<-CMD
23
+ rm -rf Vendor && mkdir -p Vendor
24
+ unzip -o #{zip} -d Vendor >/dev/null
25
+ CMD
26
+
27
+ s.vendored_frameworks = "Vendor/YEOFR.xcframework"
28
+ s.dependency "React-Core"
29
+
30
+ # Device-only: exclude simulator archs
31
+ s.pod_target_xcconfig = {
32
+ 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386 x86_64 arm64',
33
+ 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
34
+ }
35
+ s.user_target_xcconfig = {
36
+ 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386 x86_64 arm64'
37
+ }
38
+ end
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@yeomessagingcom/react-native-yeofr",
3
+ "version": "0.1.3",
4
+ "description": "React Native iOS integration for YEO Face Recognition (device-only).",
5
+ "main": "index.ts",
6
+ "react-native": "index.ts",
7
+ "license": "SEE LICENSE IN LICENSE",
8
+ "author": "YEO Messaging",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/yeomessaging/react-native-yeofr.git"
12
+ },
13
+ "homepage": "https://github.com/YEOMessaging/react-native-yeofr#readme",
14
+ "bugs": { "email": "luca@yeomessaging.com", "url": "https://github.com/YEOMessaging/react-native-yeofr/issues" },
15
+ "files": [
16
+ "index.ts",
17
+ "ios",
18
+ "react-native.config.js",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "keywords": ["react-native", "ios", "face-recognition", "yeofr"],
23
+ "peerDependencies": {
24
+ "react-native": ">=0.72.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/react-native": "^0.72.0"
28
+ }
29
+ }
@@ -0,0 +1,11 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ ios: {
5
+ project: null,
6
+ podspecPath: 'ios/react-native-yeofr.podspec'
7
+ },
8
+ android: null
9
+ }
10
+ }
11
+ };