@succinctlabs/react-native-zcam1 0.2.5
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 +61 -0
- package/Zcam1Sdk.podspec +157 -0
- package/app.plugin.js +11 -0
- package/cpp/generated/zcam1_c2pa_utils.cpp +4091 -0
- package/cpp/generated/zcam1_c2pa_utils.hpp +367 -0
- package/cpp/generated/zcam1_certs_utils.cpp +1799 -0
- package/cpp/generated/zcam1_certs_utils.hpp +72 -0
- package/cpp/generated/zcam1_verify_utils.cpp +1857 -0
- package/cpp/generated/zcam1_verify_utils.hpp +79 -0
- package/cpp/proving/generated/zcam1_proving_utils.cpp +3661 -0
- package/cpp/proving/generated/zcam1_proving_utils.hpp +275 -0
- package/cpp/proving/zcam1-proving.cpp +16 -0
- package/cpp/proving/zcam1-proving.h +15 -0
- package/cpp/zcam1-sdk.cpp +20 -0
- package/cpp/zcam1-sdk.h +15 -0
- package/ios/Zcam1Camera.swift +2945 -0
- package/ios/Zcam1CameraFilmStyle.swift +191 -0
- package/ios/Zcam1CameraViewManager.m +86 -0
- package/ios/Zcam1Capture.h +13 -0
- package/ios/Zcam1Capture.mm +500 -0
- package/ios/Zcam1DepthData.swift +417 -0
- package/ios/Zcam1Sdk.h +16 -0
- package/ios/Zcam1Sdk.mm +66 -0
- package/ios/proving/Zcam1Proving.h +16 -0
- package/ios/proving/Zcam1Proving.mm +66 -0
- package/lib/module/NativeZcam1Capture.js +12 -0
- package/lib/module/NativeZcam1Capture.js.map +1 -0
- package/lib/module/NativeZcam1Sdk.js +7 -0
- package/lib/module/NativeZcam1Sdk.js.map +1 -0
- package/lib/module/bindings.js +51 -0
- package/lib/module/bindings.js.map +1 -0
- package/lib/module/camera.js +522 -0
- package/lib/module/camera.js.map +1 -0
- package/lib/module/capture.js +120 -0
- package/lib/module/capture.js.map +1 -0
- package/lib/module/common.js +35 -0
- package/lib/module/common.js.map +1 -0
- package/lib/module/generated/zcam1_c2pa_utils-ffi.js +43 -0
- package/lib/module/generated/zcam1_c2pa_utils-ffi.js.map +1 -0
- package/lib/module/generated/zcam1_c2pa_utils.js +1202 -0
- package/lib/module/generated/zcam1_c2pa_utils.js.map +1 -0
- package/lib/module/generated/zcam1_certs_utils-ffi.js +43 -0
- package/lib/module/generated/zcam1_certs_utils-ffi.js.map +1 -0
- package/lib/module/generated/zcam1_certs_utils.js +399 -0
- package/lib/module/generated/zcam1_certs_utils.js.map +1 -0
- package/lib/module/generated/zcam1_proving_utils-ffi.js +43 -0
- package/lib/module/generated/zcam1_proving_utils-ffi.js.map +1 -0
- package/lib/module/generated/zcam1_proving_utils.js +515 -0
- package/lib/module/generated/zcam1_proving_utils.js.map +1 -0
- package/lib/module/generated/zcam1_verify_utils-ffi.js +43 -0
- package/lib/module/generated/zcam1_verify_utils-ffi.js.map +1 -0
- package/lib/module/generated/zcam1_verify_utils.js +252 -0
- package/lib/module/generated/zcam1_verify_utils.js.map +1 -0
- package/lib/module/index.js +31 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/picker.js +222 -0
- package/lib/module/picker.js.map +1 -0
- package/lib/module/proving/NativeZcam1Proving.js +7 -0
- package/lib/module/proving/NativeZcam1Proving.js.map +1 -0
- package/lib/module/proving/bindings.js +46 -0
- package/lib/module/proving/bindings.js.map +1 -0
- package/lib/module/proving/index.js +5 -0
- package/lib/module/proving/index.js.map +1 -0
- package/lib/module/proving/prove.js +346 -0
- package/lib/module/proving/prove.js.map +1 -0
- package/lib/module/utils.js +27 -0
- package/lib/module/utils.js.map +1 -0
- package/lib/module/verify.js +82 -0
- package/lib/module/verify.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeZcam1Capture.d.ts +280 -0
- package/lib/typescript/src/NativeZcam1Capture.d.ts.map +1 -0
- package/lib/typescript/src/NativeZcam1Sdk.d.ts +8 -0
- package/lib/typescript/src/NativeZcam1Sdk.d.ts.map +1 -0
- package/lib/typescript/src/bindings.d.ts +14 -0
- package/lib/typescript/src/bindings.d.ts.map +1 -0
- package/lib/typescript/src/camera.d.ts +300 -0
- package/lib/typescript/src/camera.d.ts.map +1 -0
- package/lib/typescript/src/capture.d.ts +59 -0
- package/lib/typescript/src/capture.d.ts.map +1 -0
- package/lib/typescript/src/common.d.ts +10 -0
- package/lib/typescript/src/common.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_c2pa_utils-ffi.d.ts +175 -0
- package/lib/typescript/src/generated/zcam1_c2pa_utils-ffi.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_c2pa_utils.d.ts +811 -0
- package/lib/typescript/src/generated/zcam1_c2pa_utils.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_certs_utils-ffi.d.ts +82 -0
- package/lib/typescript/src/generated/zcam1_certs_utils-ffi.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_certs_utils.d.ts +413 -0
- package/lib/typescript/src/generated/zcam1_certs_utils.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_proving_utils-ffi.d.ts +153 -0
- package/lib/typescript/src/generated/zcam1_proving_utils-ffi.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_proving_utils.d.ts +321 -0
- package/lib/typescript/src/generated/zcam1_proving_utils.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_verify_utils-ffi.d.ts +84 -0
- package/lib/typescript/src/generated/zcam1_verify_utils-ffi.d.ts.map +1 -0
- package/lib/typescript/src/generated/zcam1_verify_utils.d.ts +286 -0
- package/lib/typescript/src/generated/zcam1_verify_utils.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +29 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/picker.d.ts +103 -0
- package/lib/typescript/src/picker.d.ts.map +1 -0
- package/lib/typescript/src/proving/NativeZcam1Proving.d.ts +8 -0
- package/lib/typescript/src/proving/NativeZcam1Proving.d.ts.map +1 -0
- package/lib/typescript/src/proving/bindings.d.ts +8 -0
- package/lib/typescript/src/proving/bindings.d.ts.map +1 -0
- package/lib/typescript/src/proving/index.d.ts +3 -0
- package/lib/typescript/src/proving/index.d.ts.map +1 -0
- package/lib/typescript/src/proving/prove.d.ts +74 -0
- package/lib/typescript/src/proving/prove.d.ts.map +1 -0
- package/lib/typescript/src/utils.d.ts +2 -0
- package/lib/typescript/src/utils.d.ts.map +1 -0
- package/lib/typescript/src/verify.d.ts +45 -0
- package/lib/typescript/src/verify.d.ts.map +1 -0
- package/package.json +118 -0
- package/src/NativeZcam1Capture.ts +335 -0
- package/src/NativeZcam1Sdk.ts +10 -0
- package/src/bindings.tsx +49 -0
- package/src/camera.tsx +705 -0
- package/src/capture.tsx +165 -0
- package/src/common.tsx +46 -0
- package/src/generated/zcam1_c2pa_utils-ffi.ts +456 -0
- package/src/generated/zcam1_c2pa_utils.ts +1866 -0
- package/src/generated/zcam1_certs_utils-ffi.ts +187 -0
- package/src/generated/zcam1_certs_utils.ts +549 -0
- package/src/generated/zcam1_proving_utils-ffi.ts +374 -0
- package/src/generated/zcam1_proving_utils.ts +804 -0
- package/src/generated/zcam1_verify_utils-ffi.ts +196 -0
- package/src/generated/zcam1_verify_utils.ts +372 -0
- package/src/index.ts +73 -0
- package/src/picker.tsx +342 -0
- package/src/proving/NativeZcam1Proving.ts +10 -0
- package/src/proving/bindings.tsx +50 -0
- package/src/proving/index.ts +8 -0
- package/src/proving/prove.tsx +492 -0
- package/src/utils.ts +38 -0
- package/src/verify.tsx +119 -0
- package/turbo.json +27 -0
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
#import "Zcam1Capture.h"
|
|
2
|
+
#import <Security/Security.h>
|
|
3
|
+
#import <AVFoundation/AVFoundation.h>
|
|
4
|
+
#import <QuickLook/QuickLook.h>
|
|
5
|
+
#import "Zcam1Sdk-Swift.h"
|
|
6
|
+
#import <React/RCTBridgeModule.h>
|
|
7
|
+
|
|
8
|
+
// Static storage for pending promise callbacks - stored outside the instance to ensure they survive.
|
|
9
|
+
static NSMutableDictionary<NSString *, RCTPromiseResolveBlock> *sPendingResolvers = nil;
|
|
10
|
+
static NSMutableDictionary<NSString *, RCTPromiseRejectBlock> *sPendingRejecters = nil;
|
|
11
|
+
static dispatch_once_t sOnceToken;
|
|
12
|
+
|
|
13
|
+
static void ensureStaticStorageInitialized(void) {
|
|
14
|
+
dispatch_once(&sOnceToken, ^{
|
|
15
|
+
sPendingResolvers = [NSMutableDictionary new];
|
|
16
|
+
sPendingRejecters = [NSMutableDictionary new];
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// MARK: - QLPreviewController helpers
|
|
21
|
+
|
|
22
|
+
@interface Zcam1PreviewItem : NSObject <QLPreviewItem>
|
|
23
|
+
@property (nonatomic, strong) NSURL *previewItemURL;
|
|
24
|
+
- (instancetype)initWithURL:(NSURL *)url;
|
|
25
|
+
@end
|
|
26
|
+
|
|
27
|
+
@implementation Zcam1PreviewItem
|
|
28
|
+
- (instancetype)initWithURL:(NSURL *)url {
|
|
29
|
+
self = [super init];
|
|
30
|
+
if (self) {
|
|
31
|
+
_previewItemURL = url;
|
|
32
|
+
}
|
|
33
|
+
return self;
|
|
34
|
+
}
|
|
35
|
+
@end
|
|
36
|
+
|
|
37
|
+
@interface Zcam1PreviewDataSource : NSObject <QLPreviewControllerDataSource>
|
|
38
|
+
@property (nonatomic, strong) Zcam1PreviewItem *item;
|
|
39
|
+
- (instancetype)initWithItem:(Zcam1PreviewItem *)item;
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
@implementation Zcam1PreviewDataSource
|
|
43
|
+
- (instancetype)initWithItem:(Zcam1PreviewItem *)item {
|
|
44
|
+
self = [super init];
|
|
45
|
+
if (self) {
|
|
46
|
+
_item = item;
|
|
47
|
+
}
|
|
48
|
+
return self;
|
|
49
|
+
}
|
|
50
|
+
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
|
|
51
|
+
return 1;
|
|
52
|
+
}
|
|
53
|
+
- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
|
|
54
|
+
return self.item;
|
|
55
|
+
}
|
|
56
|
+
@end
|
|
57
|
+
|
|
58
|
+
@implementation Zcam1Capture
|
|
59
|
+
|
|
60
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
61
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
62
|
+
{
|
|
63
|
+
return std::make_shared<facebook::react::NativeZcam1CaptureSpecJSI>(params);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
+ (NSString *)moduleName
|
|
67
|
+
{
|
|
68
|
+
return @"Zcam1Capture";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
- (void)takeNativePhoto:(NSString *)format
|
|
73
|
+
position:(NSString *)position
|
|
74
|
+
flash:(NSString *)flash
|
|
75
|
+
includeDepthData:(BOOL)includeDepthData
|
|
76
|
+
aspectRatio:(NSString *)aspectRatio
|
|
77
|
+
orientation:(NSString *)orientation
|
|
78
|
+
skipPostProcessing:(BOOL)skipPostProcessing
|
|
79
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
80
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
81
|
+
{
|
|
82
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
83
|
+
if (@available(iOS 16.0, *)) {
|
|
84
|
+
Zcam1CameraService *service = [Zcam1CameraService shared];
|
|
85
|
+
|
|
86
|
+
// If empty strings are passed, let Swift fall back to its defaults.
|
|
87
|
+
NSString *positionString = (position.length > 0) ? position : nil;
|
|
88
|
+
NSString *formatString = (format.length > 0) ? format : nil;
|
|
89
|
+
|
|
90
|
+
// Set flash mode before capture.
|
|
91
|
+
if (flash.length > 0) {
|
|
92
|
+
[service setFlashMode:flash];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Store callbacks in static storage with a unique key.
|
|
96
|
+
// This ensures they survive regardless of TurboModule instance lifecycle.
|
|
97
|
+
ensureStaticStorageInitialized();
|
|
98
|
+
NSString *callbackKey = [[NSUUID UUID] UUIDString];
|
|
99
|
+
@synchronized (sPendingResolvers) {
|
|
100
|
+
sPendingResolvers[callbackKey] = [resolve copy];
|
|
101
|
+
sPendingRejecters[callbackKey] = [reject copy];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
[service takePhotoWithPositionString:positionString
|
|
105
|
+
formatString:formatString
|
|
106
|
+
includeDepthData:includeDepthData
|
|
107
|
+
aspectRatio:aspectRatio
|
|
108
|
+
orientation:orientation
|
|
109
|
+
skipPostProcessing:skipPostProcessing
|
|
110
|
+
completion:^(NSDictionary *result, NSError *error) {
|
|
111
|
+
// Retrieve and remove callbacks from static storage.
|
|
112
|
+
RCTPromiseResolveBlock storedResolve = nil;
|
|
113
|
+
RCTPromiseRejectBlock storedReject = nil;
|
|
114
|
+
@synchronized (sPendingResolvers) {
|
|
115
|
+
storedResolve = sPendingResolvers[callbackKey];
|
|
116
|
+
storedReject = sPendingRejecters[callbackKey];
|
|
117
|
+
[sPendingResolvers removeObjectForKey:callbackKey];
|
|
118
|
+
[sPendingRejecters removeObjectForKey:callbackKey];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (error != nil) {
|
|
122
|
+
NSString *code = @"CAMERA_CAPTURE_ERROR";
|
|
123
|
+
NSString *message = error.localizedDescription ?: @"Failed to capture photo";
|
|
124
|
+
if (storedReject) storedReject(code, message, error);
|
|
125
|
+
} else if (result != nil) {
|
|
126
|
+
if (storedResolve) storedResolve(result);
|
|
127
|
+
} else {
|
|
128
|
+
if (storedReject) storedReject(@"CAMERA_CAPTURE_ERROR", @"Capture returned no data", nil);
|
|
129
|
+
}
|
|
130
|
+
}];
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// iOS version too old for the Swift camera implementation.
|
|
135
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS 16+ and Swift component", nil);
|
|
136
|
+
#else
|
|
137
|
+
// Swift-generated header is not available (no Swift camera implementation linked).
|
|
138
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS Swift component", nil);
|
|
139
|
+
#endif
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
- (void)setZoom:(double)factor
|
|
143
|
+
{
|
|
144
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
145
|
+
if (@available(iOS 16.0, *)) {
|
|
146
|
+
[[Zcam1CameraService shared] setZoom:factor];
|
|
147
|
+
}
|
|
148
|
+
#endif
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
- (void)setZoomAnimated:(double)factor
|
|
152
|
+
{
|
|
153
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
154
|
+
if (@available(iOS 16.0, *)) {
|
|
155
|
+
// Both paths use the same session queue dispatch for reliable lens switching.
|
|
156
|
+
[[Zcam1CameraService shared] setZoom:factor];
|
|
157
|
+
}
|
|
158
|
+
#endif
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
- (void)getMinZoom:(RCTPromiseResolveBlock)resolve
|
|
162
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
163
|
+
{
|
|
164
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
165
|
+
if (@available(iOS 16.0, *)) {
|
|
166
|
+
CGFloat minZoom = [[Zcam1CameraService shared] getMinZoom];
|
|
167
|
+
resolve(@(minZoom));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
#endif
|
|
171
|
+
resolve(@(1.0));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
- (void)getMaxZoom:(RCTPromiseResolveBlock)resolve
|
|
175
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
176
|
+
{
|
|
177
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
178
|
+
if (@available(iOS 16.0, *)) {
|
|
179
|
+
CGFloat maxZoom = [[Zcam1CameraService shared] getMaxZoom];
|
|
180
|
+
resolve(@(maxZoom));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
#endif
|
|
184
|
+
resolve(@(1.0));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
- (void)getSwitchOverZoomFactors:(RCTPromiseResolveBlock)resolve
|
|
188
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
189
|
+
{
|
|
190
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
191
|
+
if (@available(iOS 16.0, *)) {
|
|
192
|
+
NSArray<NSNumber *> *factors = [[Zcam1CameraService shared] getSwitchOverZoomFactors];
|
|
193
|
+
resolve(factors);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
#endif
|
|
197
|
+
resolve(@[]);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
- (void)hasUltraWideCamera:(RCTPromiseResolveBlock)resolve
|
|
201
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
202
|
+
{
|
|
203
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
204
|
+
if (@available(iOS 16.0, *)) {
|
|
205
|
+
BOOL hasUltraWide = [[Zcam1CameraService shared] hasUltraWideCamera];
|
|
206
|
+
resolve(@(hasUltraWide));
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
#endif
|
|
210
|
+
resolve(@(NO));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
- (void)focusAtPoint:(double)x
|
|
214
|
+
y:(double)y
|
|
215
|
+
{
|
|
216
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
217
|
+
if (@available(iOS 16.0, *)) {
|
|
218
|
+
CGPoint point = CGPointMake(x, y);
|
|
219
|
+
[[Zcam1CameraService shared] focusAtPoint:point];
|
|
220
|
+
}
|
|
221
|
+
#endif
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
- (void)getExposureRange:(RCTPromiseResolveBlock)resolve
|
|
225
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
226
|
+
{
|
|
227
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
228
|
+
if (@available(iOS 16.0, *)) {
|
|
229
|
+
NSDictionary *range = [[Zcam1CameraService shared] getExposureRange];
|
|
230
|
+
resolve(range);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
#endif
|
|
234
|
+
resolve(@{@"min": @(0.0), @"max": @(0.0)});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
- (void)resetExposure
|
|
238
|
+
{
|
|
239
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
240
|
+
if (@available(iOS 16.0, *)) {
|
|
241
|
+
[[Zcam1CameraService shared] resetExposure];
|
|
242
|
+
}
|
|
243
|
+
#endif
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
- (void)getDeviceDiagnostics:(RCTPromiseResolveBlock)resolve
|
|
247
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
248
|
+
{
|
|
249
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
250
|
+
if (@available(iOS 16.0, *)) {
|
|
251
|
+
NSDictionary *diagnostics = [[Zcam1CameraService shared] getDeviceDiagnostics];
|
|
252
|
+
resolve(diagnostics);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
#endif
|
|
256
|
+
resolve(@{@"error": @"Diagnostics not available"});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
- (void)isDepthSupported:(RCTPromiseResolveBlock)resolve
|
|
260
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
261
|
+
{
|
|
262
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
263
|
+
if (@available(iOS 16.0, *)) {
|
|
264
|
+
BOOL supported = [[Zcam1CameraService shared] isDepthSupported];
|
|
265
|
+
resolve(@(supported));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
#endif
|
|
269
|
+
resolve(@(NO));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
- (void)hasDepthZoomLimitations:(RCTPromiseResolveBlock)resolve
|
|
273
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
274
|
+
{
|
|
275
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
276
|
+
if (@available(iOS 16.0, *)) {
|
|
277
|
+
BOOL hasLimitations = [[Zcam1CameraService shared] hasDepthZoomLimitations];
|
|
278
|
+
resolve(@(hasLimitations));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
#endif
|
|
282
|
+
resolve(@(NO));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
- (void)getDepthSupportedZoomRanges:(RCTPromiseResolveBlock)resolve
|
|
286
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
287
|
+
{
|
|
288
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
289
|
+
if (@available(iOS 16.0, *)) {
|
|
290
|
+
NSArray<NSArray<NSNumber *> *> *ranges = [[Zcam1CameraService shared] getDepthSupportedZoomRanges];
|
|
291
|
+
resolve(ranges);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
#endif
|
|
295
|
+
resolve(@[]);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
- (void)startNativeVideoRecording:(NSString *)position
|
|
299
|
+
maxDurationSeconds:(double)maxDurationSeconds
|
|
300
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
301
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
302
|
+
{
|
|
303
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
304
|
+
if (@available(iOS 16.0, *)) {
|
|
305
|
+
Zcam1CameraService *service = [Zcam1CameraService shared];
|
|
306
|
+
|
|
307
|
+
// If empty strings are passed, let Swift fall back to its defaults.
|
|
308
|
+
NSString *positionString = (position.length > 0) ? position : nil;
|
|
309
|
+
|
|
310
|
+
// Store callbacks in static storage with a unique key.
|
|
311
|
+
ensureStaticStorageInitialized();
|
|
312
|
+
NSString *callbackKey = [[NSUUID UUID] UUIDString];
|
|
313
|
+
@synchronized (sPendingResolvers) {
|
|
314
|
+
sPendingResolvers[callbackKey] = [resolve copy];
|
|
315
|
+
sPendingRejecters[callbackKey] = [reject copy];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
[service startVideoRecordingWithPositionString:positionString
|
|
319
|
+
maxDurationSeconds:maxDurationSeconds
|
|
320
|
+
completion:^(NSDictionary *result, NSError *error) {
|
|
321
|
+
RCTPromiseResolveBlock storedResolve = nil;
|
|
322
|
+
RCTPromiseRejectBlock storedReject = nil;
|
|
323
|
+
@synchronized (sPendingResolvers) {
|
|
324
|
+
storedResolve = sPendingResolvers[callbackKey];
|
|
325
|
+
storedReject = sPendingRejecters[callbackKey];
|
|
326
|
+
[sPendingResolvers removeObjectForKey:callbackKey];
|
|
327
|
+
[sPendingRejecters removeObjectForKey:callbackKey];
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (error != nil) {
|
|
331
|
+
NSString *code = @"VIDEO_RECORDING_START_ERROR";
|
|
332
|
+
NSString *message = error.localizedDescription ?: @"Failed to start video recording";
|
|
333
|
+
if (storedReject) storedReject(code, message, error);
|
|
334
|
+
} else if (result != nil) {
|
|
335
|
+
if (storedResolve) storedResolve(result);
|
|
336
|
+
} else {
|
|
337
|
+
if (storedReject) storedReject(@"VIDEO_RECORDING_START_ERROR", @"Start recording returned no data", nil);
|
|
338
|
+
}
|
|
339
|
+
}];
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// iOS version too old for the Swift camera implementation.
|
|
344
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS 16+ and Swift component", nil);
|
|
345
|
+
#else
|
|
346
|
+
// Swift-generated header is not available (no Swift camera implementation linked).
|
|
347
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS Swift component", nil);
|
|
348
|
+
#endif
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
- (void)stopNativeVideoRecording:(RCTPromiseResolveBlock)resolve
|
|
352
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
353
|
+
{
|
|
354
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
355
|
+
if (@available(iOS 16.0, *)) {
|
|
356
|
+
Zcam1CameraService *service = [Zcam1CameraService shared];
|
|
357
|
+
|
|
358
|
+
// Store callbacks in static storage with a unique key.
|
|
359
|
+
ensureStaticStorageInitialized();
|
|
360
|
+
NSString *callbackKey = [[NSUUID UUID] UUIDString];
|
|
361
|
+
@synchronized (sPendingResolvers) {
|
|
362
|
+
sPendingResolvers[callbackKey] = [resolve copy];
|
|
363
|
+
sPendingRejecters[callbackKey] = [reject copy];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
[service stopVideoRecordingWithCompletion:^(NSDictionary *result, NSError *error) {
|
|
367
|
+
RCTPromiseResolveBlock storedResolve = nil;
|
|
368
|
+
RCTPromiseRejectBlock storedReject = nil;
|
|
369
|
+
@synchronized (sPendingResolvers) {
|
|
370
|
+
storedResolve = sPendingResolvers[callbackKey];
|
|
371
|
+
storedReject = sPendingRejecters[callbackKey];
|
|
372
|
+
[sPendingResolvers removeObjectForKey:callbackKey];
|
|
373
|
+
[sPendingRejecters removeObjectForKey:callbackKey];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (error != nil) {
|
|
377
|
+
NSString *code = @"VIDEO_RECORDING_STOP_ERROR";
|
|
378
|
+
NSString *message = error.localizedDescription ?: @"Failed to stop video recording";
|
|
379
|
+
if (storedReject) storedReject(code, message, error);
|
|
380
|
+
} else if (result != nil) {
|
|
381
|
+
if (storedResolve) storedResolve(result);
|
|
382
|
+
} else {
|
|
383
|
+
if (storedReject) storedReject(@"VIDEO_RECORDING_STOP_ERROR", @"Stop recording returned no data", nil);
|
|
384
|
+
}
|
|
385
|
+
}];
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// iOS version too old for the Swift camera implementation.
|
|
390
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS 16+ and Swift component", nil);
|
|
391
|
+
#else
|
|
392
|
+
// Swift-generated header is not available (no Swift camera implementation linked).
|
|
393
|
+
reject(@"CAMERA_UNAVAILABLE", @"Native camera requires iOS Swift component", nil);
|
|
394
|
+
#endif
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
- (void)previewFile:(NSString *)filePath
|
|
398
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
399
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
400
|
+
{
|
|
401
|
+
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
|
|
402
|
+
|
|
403
|
+
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
|
|
404
|
+
reject(@"FILE_NOT_FOUND", [NSString stringWithFormat:@"File not found: %@", filePath], nil);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
409
|
+
Zcam1PreviewItem *item = [[Zcam1PreviewItem alloc] initWithURL:fileURL];
|
|
410
|
+
Zcam1PreviewDataSource *dataSource = [[Zcam1PreviewDataSource alloc] initWithItem:item];
|
|
411
|
+
|
|
412
|
+
// Store data source so it isn't deallocated.
|
|
413
|
+
static Zcam1PreviewDataSource *currentDataSource = nil;
|
|
414
|
+
currentDataSource = dataSource;
|
|
415
|
+
|
|
416
|
+
QLPreviewController *previewController = [[QLPreviewController alloc] init];
|
|
417
|
+
previewController.dataSource = dataSource;
|
|
418
|
+
|
|
419
|
+
// Find the key window using modern scene-based API (iOS 13+).
|
|
420
|
+
UIWindow *keyWindow = nil;
|
|
421
|
+
for (UIWindowScene *scene in [UIApplication sharedApplication].connectedScenes) {
|
|
422
|
+
if (scene.activationState == UISceneActivationStateForegroundActive) {
|
|
423
|
+
for (UIWindow *window in scene.windows) {
|
|
424
|
+
if (window.isKeyWindow) {
|
|
425
|
+
keyWindow = window;
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (keyWindow) break;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
UIViewController *rootVC = keyWindow.rootViewController;
|
|
434
|
+
// Walk to the topmost presented controller.
|
|
435
|
+
while (rootVC.presentedViewController) {
|
|
436
|
+
rootVC = rootVC.presentedViewController;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (!rootVC) {
|
|
440
|
+
reject(@"NO_VIEW_CONTROLLER", @"Could not find a view controller to present from", nil);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
[rootVC presentViewController:previewController animated:YES completion:^{
|
|
445
|
+
resolve(nil);
|
|
446
|
+
}];
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
- (void)getDepthSensorInfo:(RCTPromiseResolveBlock)resolve
|
|
451
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
452
|
+
{
|
|
453
|
+
#if __has_include("Zcam1Sdk-Swift.h")
|
|
454
|
+
if (@available(iOS 16.0, *)) {
|
|
455
|
+
// Check if current device supports depth data capture
|
|
456
|
+
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInDualCamera
|
|
457
|
+
mediaType:AVMediaTypeVideo
|
|
458
|
+
position:AVCaptureDevicePositionBack];
|
|
459
|
+
|
|
460
|
+
// Also try triple camera and dual wide camera for broader support
|
|
461
|
+
if (!device) {
|
|
462
|
+
device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInTripleCamera
|
|
463
|
+
mediaType:AVMediaTypeVideo
|
|
464
|
+
position:AVCaptureDevicePositionBack];
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (!device) {
|
|
468
|
+
device = [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInDualWideCamera
|
|
469
|
+
mediaType:AVMediaTypeVideo
|
|
470
|
+
position:AVCaptureDevicePositionBack];
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
BOOL supportsDepth = device != nil;
|
|
474
|
+
|
|
475
|
+
NSMutableArray<NSString *> *formats = [NSMutableArray array];
|
|
476
|
+
if (supportsDepth) {
|
|
477
|
+
[formats addObject:@"depthFloat32"];
|
|
478
|
+
[formats addObject:@"depthFloat16"];
|
|
479
|
+
[formats addObject:@"disparityFloat32"];
|
|
480
|
+
[formats addObject:@"disparityFloat16"];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
NSDictionary *result = @{
|
|
484
|
+
@"available": @(supportsDepth),
|
|
485
|
+
@"formats": formats,
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
resolve(result);
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// iOS version too old
|
|
493
|
+
resolve(nil);
|
|
494
|
+
#else
|
|
495
|
+
// Swift-generated header is not available
|
|
496
|
+
resolve(nil);
|
|
497
|
+
#endif
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
@end
|