Fixed SafeAreaView dummy support on iOS

Fixed zoom issue
Fixed Fabric (new arch) compile issues on both platforms
Fixed included broken codegen lib code
Fixed broken .h import paths to avoid setting custom build settings
Fixed potential memory issue by disabling view recycling
Added Fabric (new arch) support for camera view component
Added RN 0.81 for example
Added RN 0.79 for main lib
Added helper for re-running codegen
Added gitignore for Android codegen making a podspec
Added support for scanThrottleDelay on Android
Added includesGeneratedCode to package.json to indicate changes
Rewrote optional int props to use -1 instead due to RN bug
Moved to Obj-C with C++ support (.mm) to avoid C++ compile issues
This commit is contained in:
Seph Soliman 2025-09-02 16:26:49 -07:00
parent 4f376b5d0f
commit 9a41d1c8ae
76 changed files with 3904 additions and 3173 deletions

4
.gitignore vendored
View File

@ -89,3 +89,7 @@ dist/
*.xcodeproj/*
!*.xcodeproj/project.pbxproj
!*.xcworkspace/contents.xcworkspacedata
### RN Codegen bug
# There's no such thing as podspecs for Android, so ignore the generated file
android/generated/ReactCodegen.podspec

View File

@ -5,25 +5,22 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "ReactNativeCameraKit"
s.version = package["version"]
s.summary = "A high performance, easy to use camera API"
s.summary = package["description"]
s.license = "MIT"
s.authors = "CameraKit"
s.homepage = "https://github.com/teslamotors/react-native-camera-kit"
s.platform = :ios, "11.0"
s.platform = :ios, "15.0"
s.source = { :git => "https://github.com/teslamotors/react-native-camera-kit.git", :tag => "v#{s.version}" }
s.source_files = "ios/**/*.{h,m,mm,swift}"
s.private_header_files = 'ios/ReactNativeCameraKit/ReactNativeCameraKit-Swift.pre.h'
s.source_files = [
# Exclude .h files as they cause Swift compiler to treat them as C files, but they are C++
# See https://github.com/facebook/react-native/issues/45424#issuecomment-2354737063
"ios/ReactNativeCameraKit/*.{m,swift,mm}",
"ios/generated/rncamerakit_specs/*.{m,mm,cpp}",
]
if ENV['USE_FRAMEWORKS']
exisiting_flags = s.attributes_hash["compiler_flags"]
if exisiting_flags.present?
s.compiler_flags = exisiting_flags + "-DCK_USE_FRAMEWORKS=1"
else
s.compiler_flags = "-DCK_USE_FRAMEWORKS=1"
end
end
s.private_header_files = 'ios/ReactNativeCameraKit/ReactNativeCameraKit-Swift.pre.h'
if defined?(install_modules_dependencies()) != nil
install_modules_dependencies(s)

View File

@ -34,11 +34,9 @@ android {
warning 'InvalidPackage'
}
if (!isNewArchitectureEnabled()) {
sourceSets {
main {
java.srcDirs += 'src/paper/java'
}
sourceSets {
main {
java.srcDirs += 'generated'
}
}
}

View File

@ -10,7 +10,7 @@
* @nolint
*/
package com.rncamerakit;
package com.facebook.fbreact.specs;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.bridge.Promise;

View File

@ -37,10 +37,10 @@ public class CKCameraManagerDelegate<T extends View, U extends BaseViewManager<T
mViewManager.setZoomMode(view, value == null ? null : (String) value);
break;
case "zoom":
mViewManager.setZoom(view, value == null ? 0f : ((Double) value).doubleValue());
mViewManager.setZoom(view, value == null ? -1f : ((Double) value).doubleValue());
break;
case "maxZoom":
mViewManager.setMaxZoom(view, value == null ? 0f : ((Double) value).doubleValue());
mViewManager.setMaxZoom(view, value == null ? -1f : ((Double) value).doubleValue());
break;
case "torchMode":
mViewManager.setTorchMode(view, value == null ? null : (String) value);
@ -67,7 +67,7 @@ public class CKCameraManagerDelegate<T extends View, U extends BaseViewManager<T
mViewManager.setRatioOverlayColor(view, ColorPropConverter.getColor(value, view.getContext()));
break;
case "resetFocusTimeout":
mViewManager.setResetFocusTimeout(view, value == null ? 0 : ((Double) value).intValue());
mViewManager.setResetFocusTimeout(view, value == null ? -1 : ((Double) value).intValue());
break;
case "resetFocusWhenMotionDetected":
mViewManager.setResetFocusWhenMotionDetected(view, value == null ? false : (boolean) value);
@ -76,7 +76,7 @@ public class CKCameraManagerDelegate<T extends View, U extends BaseViewManager<T
mViewManager.setResizeMode(view, value == null ? null : (String) value);
break;
case "scanThrottleDelay":
mViewManager.setScanThrottleDelay(view, value == null ? 0 : ((Double) value).intValue());
mViewManager.setScanThrottleDelay(view, value == null ? -1 : ((Double) value).intValue());
break;
case "barcodeFrameSize":
mViewManager.setBarcodeFrameSize(view, (ReadableMap) value);
@ -85,7 +85,7 @@ public class CKCameraManagerDelegate<T extends View, U extends BaseViewManager<T
mViewManager.setShutterPhotoSound(view, value == null ? false : (boolean) value);
break;
case "shutterAnimationDuration":
mViewManager.setShutterAnimationDuration(view, value == null ? 0 : ((Double) value).intValue());
mViewManager.setShutterAnimationDuration(view, value == null ? -1 : ((Double) value).intValue());
break;
case "outputPath":
mViewManager.setOutputPath(view, value == null ? null : (String) value);

View File

@ -12,8 +12,9 @@ package com.facebook.react.viewmanagers;
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.uimanager.ViewManagerWithGeneratedInterface;
public interface CKCameraManagerInterface<T extends View> {
public interface CKCameraManagerInterface<T extends View> extends ViewManagerWithGeneratedInterface {
void setFlashMode(T view, @Nullable String value);
void setFocusMode(T view, @Nullable String value);
void setMaxPhotoQualityPrioritization(T view, @Nullable String value);

View File

@ -0,0 +1,45 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)
file(GLOB react_codegen_SRCS CONFIGURE_DEPENDS *.cpp react/renderer/components/rncamerakit_specs/*.cpp)
add_library(
react_codegen_rncamerakit_specs
OBJECT
${react_codegen_SRCS}
)
target_include_directories(react_codegen_rncamerakit_specs PUBLIC . react/renderer/components/rncamerakit_specs)
target_link_libraries(
react_codegen_rncamerakit_specs
fbjni
jsi
# We need to link different libraries based on whether we are building rncore or not, that's necessary
# because we want to break a circular dependency between react_codegen_rncore and reactnative
reactnative
)
# Fix crash on startup on RN 0.81 or newer due to broken codegen (it always uses target_compile_options)
# Do not commit the change where the if-statement is removed unless they fix Codegen
# See https://github.com/software-mansion/react-native-screens/pull/3114/commits/b4d283c8fc65e36ec60726fd7513735ccc7e1fe9
# See https://github.com/react-native-maps/react-native-maps/issues/5699
# (commit https://github.com/react-native-maps/react-native-maps/commit/c587f30b8499b79a2266687c641bfed10b3ecc2c)
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 80)
target_compile_reactnative_options(react_codegen_rncamerakit_specs PRIVATE)
else()
target_compile_options(
react_codegen_rncamerakit_specs
PRIVATE
-DLOG_TAG=\"ReactNative\"
-fexceptions
-frtti
-std=c++20
-Wall
)
endif()

View File

@ -0,0 +1,22 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorCpp.js
*/
#include "ComponentDescriptors.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
namespace facebook::react {
void rncamerakit_specs_registerComponentDescriptorsFromCodegen(
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry) {
registry->add(concreteComponentDescriptorProvider<CKCameraComponentDescriptor>());
}
} // namespace facebook::react

View File

@ -0,0 +1,24 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorH.js
*/
#pragma once
#include "ShadowNodes.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
namespace facebook::react {
using CKCameraComponentDescriptor = ConcreteComponentDescriptor<CKCameraShadowNode>;
void rncamerakit_specs_registerComponentDescriptorsFromCodegen(
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
} // namespace facebook::react

View File

@ -0,0 +1,79 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterCpp.js
*/
#include "EventEmitters.h"
namespace facebook::react {
void CKCameraEventEmitter::onOrientationChange(OnOrientationChange $event) const {
dispatchEvent("orientationChange", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "orientation", $event.orientation);
return $payload;
});
}
void CKCameraEventEmitter::onZoom(OnZoom $event) const {
dispatchEvent("zoom", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "zoom", $event.zoom);
return $payload;
});
}
void CKCameraEventEmitter::onError(OnError $event) const {
dispatchEvent("error", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "errorMessage", $event.errorMessage);
return $payload;
});
}
void CKCameraEventEmitter::onReadCode(OnReadCode $event) const {
dispatchEvent("readCode", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "codeStringValue", $event.codeStringValue);
$payload.setProperty(runtime, "codeFormat", $event.codeFormat);
return $payload;
});
}
void CKCameraEventEmitter::onCaptureButtonPressIn(OnCaptureButtonPressIn $event) const {
dispatchEvent("captureButtonPressIn", [](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
return $payload;
});
}
void CKCameraEventEmitter::onCaptureButtonPressOut(OnCaptureButtonPressOut $event) const {
dispatchEvent("captureButtonPressOut", [](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
return $payload;
});
}
void CKCameraEventEmitter::onPictureTaken(OnPictureTaken $event) const {
dispatchEvent("pictureTaken", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "uri", $event.uri);
return $payload;
});
}
} // namespace facebook::react

View File

@ -0,0 +1,62 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterH.js
*/
#pragma once
#include <react/renderer/components/view/ViewEventEmitter.h>
namespace facebook::react {
class CKCameraEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
struct OnOrientationChange {
int orientation;
};
struct OnZoom {
double zoom;
};
struct OnError {
std::string errorMessage;
};
struct OnReadCode {
std::string codeStringValue;
std::string codeFormat;
};
struct OnCaptureButtonPressIn {
};
struct OnCaptureButtonPressOut {
};
struct OnPictureTaken {
std::string uri;
};
void onOrientationChange(OnOrientationChange value) const;
void onZoom(OnZoom value) const;
void onError(OnError value) const;
void onReadCode(OnReadCode value) const;
void onCaptureButtonPressIn(OnCaptureButtonPressIn value) const;
void onCaptureButtonPressOut(OnCaptureButtonPressOut value) const;
void onPictureTaken(OnPictureTaken value) const;
};
} // namespace facebook::react

View File

@ -0,0 +1,46 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsCpp.js
*/
#include "Props.h"
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
namespace facebook::react {
CKCameraProps::CKCameraProps(
const PropsParserContext &context,
const CKCameraProps &sourceProps,
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
flashMode(convertRawProp(context, rawProps, "flashMode", sourceProps.flashMode, {})),
focusMode(convertRawProp(context, rawProps, "focusMode", sourceProps.focusMode, {})),
maxPhotoQualityPrioritization(convertRawProp(context, rawProps, "maxPhotoQualityPrioritization", sourceProps.maxPhotoQualityPrioritization, {})),
zoomMode(convertRawProp(context, rawProps, "zoomMode", sourceProps.zoomMode, {})),
zoom(convertRawProp(context, rawProps, "zoom", sourceProps.zoom, {-1.0})),
maxZoom(convertRawProp(context, rawProps, "maxZoom", sourceProps.maxZoom, {-1.0})),
torchMode(convertRawProp(context, rawProps, "torchMode", sourceProps.torchMode, {})),
cameraType(convertRawProp(context, rawProps, "cameraType", sourceProps.cameraType, {})),
scanBarcode(convertRawProp(context, rawProps, "scanBarcode", sourceProps.scanBarcode, {false})),
showFrame(convertRawProp(context, rawProps, "showFrame", sourceProps.showFrame, {false})),
laserColor(convertRawProp(context, rawProps, "laserColor", sourceProps.laserColor, {})),
frameColor(convertRawProp(context, rawProps, "frameColor", sourceProps.frameColor, {})),
ratioOverlay(convertRawProp(context, rawProps, "ratioOverlay", sourceProps.ratioOverlay, {})),
ratioOverlayColor(convertRawProp(context, rawProps, "ratioOverlayColor", sourceProps.ratioOverlayColor, {})),
resetFocusTimeout(convertRawProp(context, rawProps, "resetFocusTimeout", sourceProps.resetFocusTimeout, {-1})),
resetFocusWhenMotionDetected(convertRawProp(context, rawProps, "resetFocusWhenMotionDetected", sourceProps.resetFocusWhenMotionDetected, {false})),
resizeMode(convertRawProp(context, rawProps, "resizeMode", sourceProps.resizeMode, {})),
scanThrottleDelay(convertRawProp(context, rawProps, "scanThrottleDelay", sourceProps.scanThrottleDelay, {-1})),
barcodeFrameSize(convertRawProp(context, rawProps, "barcodeFrameSize", sourceProps.barcodeFrameSize, {})),
shutterPhotoSound(convertRawProp(context, rawProps, "shutterPhotoSound", sourceProps.shutterPhotoSound, {false})),
shutterAnimationDuration(convertRawProp(context, rawProps, "shutterAnimationDuration", sourceProps.shutterAnimationDuration, {-1})),
outputPath(convertRawProp(context, rawProps, "outputPath", sourceProps.outputPath, {}))
{}
} // namespace facebook::react

View File

@ -0,0 +1,71 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsH.js
*/
#pragma once
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/graphics/Color.h>
namespace facebook::react {
struct CKCameraBarcodeFrameSizeStruct {
Float width{300.0};
Float height{150.0};
};
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, CKCameraBarcodeFrameSizeStruct &result) {
auto map = (std::unordered_map<std::string, RawValue>)value;
auto tmp_width = map.find("width");
if (tmp_width != map.end()) {
fromRawValue(context, tmp_width->second, result.width);
}
auto tmp_height = map.find("height");
if (tmp_height != map.end()) {
fromRawValue(context, tmp_height->second, result.height);
}
}
static inline std::string toString(const CKCameraBarcodeFrameSizeStruct &value) {
return "[Object CKCameraBarcodeFrameSizeStruct]";
}
class CKCameraProps final : public ViewProps {
public:
CKCameraProps() = default;
CKCameraProps(const PropsParserContext& context, const CKCameraProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
std::string flashMode{};
std::string focusMode{};
std::string maxPhotoQualityPrioritization{};
std::string zoomMode{};
double zoom{-1.0};
double maxZoom{-1.0};
std::string torchMode{};
std::string cameraType{};
bool scanBarcode{false};
bool showFrame{false};
SharedColor laserColor{};
SharedColor frameColor{};
std::string ratioOverlay{};
SharedColor ratioOverlayColor{};
int resetFocusTimeout{-1};
bool resetFocusWhenMotionDetected{false};
std::string resizeMode{};
int scanThrottleDelay{-1};
CKCameraBarcodeFrameSizeStruct barcodeFrameSize{};
bool shutterPhotoSound{false};
int shutterAnimationDuration{-1};
std::string outputPath{};
};
} // namespace facebook::react

View File

@ -0,0 +1,17 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeCpp.js
*/
#include "ShadowNodes.h"
namespace facebook::react {
extern const char CKCameraComponentName[] = "CKCamera";
} // namespace facebook::react

View File

@ -0,0 +1,32 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeH.js
*/
#pragma once
#include "EventEmitters.h"
#include "Props.h"
#include "States.h"
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <jsi/jsi.h>
namespace facebook::react {
JSI_EXPORT extern const char CKCameraComponentName[];
/*
* `ShadowNode` for <CKCamera> component.
*/
using CKCameraShadowNode = ConcreteViewShadowNode<
CKCameraComponentName,
CKCameraProps,
CKCameraEventEmitter,
CKCameraState>;
} // namespace facebook::react

View File

@ -0,0 +1,16 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateCpp.js
*/
#include "States.h"
namespace facebook::react {
} // namespace facebook::react

View File

@ -0,0 +1,29 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateH.js
*/
#pragma once
#ifdef ANDROID
#include <folly/dynamic.h>
#endif
namespace facebook::react {
class CKCameraState {
public:
CKCameraState() = default;
#ifdef ANDROID
CKCameraState(CKCameraState const &previousState, folly::dynamic data){};
folly::dynamic getDynamic() const {
return {};
};
#endif
};
} // namespace facebook::react

View File

@ -0,0 +1,40 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleCpp.js
*/
#include "rncamerakit_specsJSI.h"
namespace facebook::react {
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_capture(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->capture(
rt,
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)),
count <= 1 || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asNumber())
);
}
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_requestDeviceCameraAuthorization(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->requestDeviceCameraAuthorization(
rt
);
}
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->checkDeviceCameraAuthorizationStatus(
rt
);
}
NativeCameraKitModuleCxxSpecJSI::NativeCameraKitModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule("RNCameraKitModule", jsInvoker) {
methodMap_["capture"] = MethodMetadata {2, __hostFunction_NativeCameraKitModuleCxxSpecJSI_capture};
methodMap_["requestDeviceCameraAuthorization"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleCxxSpecJSI_requestDeviceCameraAuthorization};
methodMap_["checkDeviceCameraAuthorizationStatus"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleCxxSpecJSI_checkDeviceCameraAuthorizationStatus};
}
} // namespace facebook::react

View File

@ -0,0 +1,177 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleH.js
*/
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook::react {
#pragma mark - NativeCameraKitModuleCaptureData
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct NativeCameraKitModuleCaptureData {
P0 uri;
P1 name;
P2 height;
P3 width;
P4 id;
P5 path;
P6 size;
bool operator==(const NativeCameraKitModuleCaptureData &other) const {
return uri == other.uri && name == other.name && height == other.height && width == other.width && id == other.id && path == other.path && size == other.size;
}
};
template <typename T>
struct NativeCameraKitModuleCaptureDataBridging {
static T types;
static T fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
T result{
bridging::fromJs<decltype(types.uri)>(rt, value.getProperty(rt, "uri"), jsInvoker),
bridging::fromJs<decltype(types.name)>(rt, value.getProperty(rt, "name"), jsInvoker),
bridging::fromJs<decltype(types.height)>(rt, value.getProperty(rt, "height"), jsInvoker),
bridging::fromJs<decltype(types.width)>(rt, value.getProperty(rt, "width"), jsInvoker),
bridging::fromJs<decltype(types.id)>(rt, value.getProperty(rt, "id"), jsInvoker),
bridging::fromJs<decltype(types.path)>(rt, value.getProperty(rt, "path"), jsInvoker),
bridging::fromJs<decltype(types.size)>(rt, value.getProperty(rt, "size"), jsInvoker)};
return result;
}
#ifdef DEBUG
static jsi::String uriToJs(jsi::Runtime &rt, decltype(types.uri) value) {
return bridging::toJs(rt, value);
}
static jsi::String nameToJs(jsi::Runtime &rt, decltype(types.name) value) {
return bridging::toJs(rt, value);
}
static int heightToJs(jsi::Runtime &rt, decltype(types.height) value) {
return bridging::toJs(rt, value);
}
static int widthToJs(jsi::Runtime &rt, decltype(types.width) value) {
return bridging::toJs(rt, value);
}
static jsi::String idToJs(jsi::Runtime &rt, decltype(types.id) value) {
return bridging::toJs(rt, value);
}
static jsi::String pathToJs(jsi::Runtime &rt, decltype(types.path) value) {
return bridging::toJs(rt, value);
}
static int sizeToJs(jsi::Runtime &rt, decltype(types.size) value) {
return bridging::toJs(rt, value);
}
#endif
static jsi::Object toJs(
jsi::Runtime &rt,
const T &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "uri", bridging::toJs(rt, value.uri, jsInvoker));
result.setProperty(rt, "name", bridging::toJs(rt, value.name, jsInvoker));
result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker));
result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker));
if (value.id) {
result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker));
}
if (value.path) {
result.setProperty(rt, "path", bridging::toJs(rt, value.path.value(), jsInvoker));
}
if (value.size) {
result.setProperty(rt, "size", bridging::toJs(rt, value.size.value(), jsInvoker));
}
return result;
}
};
class JSI_EXPORT NativeCameraKitModuleCxxSpecJSI : public TurboModule {
protected:
NativeCameraKitModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual jsi::Value capture(jsi::Runtime &rt, std::optional<jsi::Object> options, std::optional<double> tag) = 0;
virtual jsi::Value requestDeviceCameraAuthorization(jsi::Runtime &rt) = 0;
virtual jsi::Value checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt) = 0;
};
template <typename T>
class JSI_EXPORT NativeCameraKitModuleCxxSpec : public TurboModule {
public:
jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.create(rt, propName);
}
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
return delegate_.getPropertyNames(runtime);
}
static constexpr std::string_view kModuleName = "RNCameraKitModule";
protected:
NativeCameraKitModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(std::string{NativeCameraKitModuleCxxSpec::kModuleName}, jsInvoker),
delegate_(reinterpret_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeCameraKitModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeCameraKitModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {
}
jsi::Value capture(jsi::Runtime &rt, std::optional<jsi::Object> options, std::optional<double> tag) override {
static_assert(
bridging::getParameterCount(&T::capture) == 3,
"Expected capture(...) to have 3 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::capture, jsInvoker_, instance_, std::move(options), std::move(tag));
}
jsi::Value requestDeviceCameraAuthorization(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::requestDeviceCameraAuthorization) == 1,
"Expected requestDeviceCameraAuthorization(...) to have 1 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::requestDeviceCameraAuthorization, jsInvoker_, instance_);
}
jsi::Value checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::checkDeviceCameraAuthorizationStatus) == 1,
"Expected checkDeviceCameraAuthorizationStatus(...) to have 1 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::checkDeviceCameraAuthorizationStatus, jsInvoker_, instance_);
}
private:
friend class NativeCameraKitModuleCxxSpec;
T *instance_;
};
Delegate delegate_;
};
} // namespace facebook::react

View File

@ -0,0 +1,44 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleJniCpp.js
*/
#include "rncamerakit_specs.h"
namespace facebook::react {
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_capture(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "capture", "(Lcom/facebook/react/bridge/ReadableMap;Ljava/lang/Double;Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
}
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_requestDeviceCameraAuthorization(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "requestDeviceCameraAuthorization", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
}
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_checkDeviceCameraAuthorizationStatus(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "checkDeviceCameraAuthorizationStatus", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
}
NativeCameraKitModuleSpecJSI::NativeCameraKitModuleSpecJSI(const JavaTurboModule::InitParams &params)
: JavaTurboModule(params) {
methodMap_["capture"] = MethodMetadata {2, __hostFunction_NativeCameraKitModuleSpecJSI_capture};
methodMap_["requestDeviceCameraAuthorization"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleSpecJSI_requestDeviceCameraAuthorization};
methodMap_["checkDeviceCameraAuthorizationStatus"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleSpecJSI_checkDeviceCameraAuthorizationStatus};
}
std::shared_ptr<TurboModule> rncamerakit_specs_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params) {
if (moduleName == "RNCameraKitModule") {
return std::make_shared<NativeCameraKitModuleSpecJSI>(params);
}
return nullptr;
}
} // namespace facebook::react

View File

@ -0,0 +1,31 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleJniH.js
*/
#pragma once
#include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/TurboModule.h>
#include <jsi/jsi.h>
namespace facebook::react {
/**
* JNI C++ class for module 'NativeCameraKitModule'
*/
class JSI_EXPORT NativeCameraKitModuleSpecJSI : public JavaTurboModule {
public:
NativeCameraKitModuleSpecJSI(const JavaTurboModule::InitParams &params);
};
JSI_EXPORT
std::shared_ptr<TurboModule> rncamerakit_specs_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params);
} // namespace facebook::react

View File

@ -105,6 +105,7 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
// Barcode Props
private var scanBarcode: Boolean = false
private var scanThrottleDelay: Long = 2000L
private var frameColor = Color.GREEN
private var laserColor = Color.RED
private var barcodeFrameSize: Size? = null
@ -270,7 +271,7 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
val minZoomFactor = videoDevice?.cameraInfo?.zoomState?.value?.minZoomRatio?.toDouble()
var maxZoomFactor: Double? = videoDevice?.cameraInfo?.zoomState?.value?.maxZoomRatio?.toDouble()
val maxZoom = this.maxZoom
if (maxZoom != null) {
if (maxZoom != null && maxZoom > -1) {
maxZoomFactor = min(maxZoomFactor ?: maxZoom, maxZoom)
}
if (maxZoomFactor != null) {
@ -328,16 +329,16 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
val useCases = mutableListOf(preview, imageCapture)
if (scanBarcode) {
val analyzer = QRCodeAnalyzer { barcodes, imageSize ->
if (scanBarcode) {
val analyzer = QRCodeAnalyzer(analyzerBlock@{ barcodes, imageSize ->
if (barcodes.isEmpty()) {
return@QRCodeAnalyzer
return@analyzerBlock
}
val barcodeFrame = barcodeFrame;
val barcodeFrame = barcodeFrame
if (barcodeFrame == null) {
onBarcodeRead(barcodes)
return@QRCodeAnalyzer
return@analyzerBlock
}
// Calculate scaling factors (image is always rotated by 90 degrees)
@ -358,7 +359,7 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
if (filteredBarcodes.isNotEmpty()) {
onBarcodeRead(filteredBarcodes)
}
}
}, scanThrottleDelay)
imageAnalyzer!!.setAnalyzer(cameraExecutor, analyzer)
useCases.add(imageAnalyzer)
}
@ -639,6 +640,13 @@ class CKCamera(context: ThemedReactContext) : FrameLayout(context), LifecycleObs
if (restartCamera) bindCameraUseCases()
}
fun setScanThrottleDelay(delayMs: Int) {
val newDelay = if (delayMs < 0) 2000L else delayMs.toLong()
val restartCamera = scanThrottleDelay != newDelay && scanBarcode
scanThrottleDelay = newDelay
if (restartCamera) bindCameraUseCases()
}
fun setCameraType(type: String = "back") {
val newLensType = when (type) {
"front" -> CameraSelector.LENS_FACING_FRONT

View File

@ -143,6 +143,11 @@ class CKCameraManager : SimpleViewManager<CKCamera>(), CKCameraManagerInterface<
view.setShutterPhotoSound(enabled);
}
@ReactProp(name = "scanThrottleDelay")
override fun setScanThrottleDelay(view: CKCamera?, value: Int) {
view?.setScanThrottleDelay(value)
}
// Methods only available on iOS
override fun setRatioOverlay(view: CKCamera?, value: String?) = Unit
@ -154,7 +159,5 @@ class CKCameraManager : SimpleViewManager<CKCamera>(), CKCameraManagerInterface<
override fun setResizeMode(view: CKCamera?, value: String?) = Unit
override fun setScanThrottleDelay(view: CKCamera?, value: Int) = Unit
override fun setMaxPhotoQualityPrioritization(view: CKCamera?, value: String?) = Unit
}

View File

@ -10,8 +10,11 @@ import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.common.InputImage
class QRCodeAnalyzer (
private val onQRCodesDetected: (qrCodes: List<Barcode>, imageSize: Size) -> Unit
private val onQRCodesDetected: (qrCodes: List<Barcode>, imageSize: Size) -> Unit,
private val scanThrottleDelay: Long = 0L
) : ImageAnalysis.Analyzer {
// Time in milliseconds of the last time we dispatched detected barcodes
private var lastBarcodeDetectedTime: Long = 0L
@SuppressLint("UnsafeExperimentalUsageError")
@ExperimentalGetImage
override fun analyze(image: ImageProxy) {
@ -22,11 +25,21 @@ class QRCodeAnalyzer (
val scanner = BarcodeScanning.getClient()
scanner.process(inputImage)
.addOnSuccessListener { barcodes ->
// Throttle callback invocations based on scanThrottleDelay (ms)
val now = System.currentTimeMillis()
if (scanThrottleDelay > 0 && (now - lastBarcodeDetectedTime) < scanThrottleDelay) {
return@addOnSuccessListener
}
val strBarcodes = mutableListOf<Barcode>()
barcodes.forEach { barcode ->
strBarcodes.add(barcode ?: return@forEach)
}
onQRCodesDetected(strBarcodes, Size(image.width, image.height))
if (strBarcodes.isNotEmpty()) {
lastBarcodeDetectedTime = now
onQRCodesDetected(strBarcodes, Size(image.width, image.height))
}
}
.addOnCompleteListener {
image.close()

View File

@ -2,6 +2,7 @@ package com.rncamerakit
import com.facebook.react.bridge.*
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.fbreact.specs.NativeCameraKitModuleSpec
/**
* Native module for interacting with the camera in React Native applications.

View File

@ -2,4 +2,7 @@ import { AppRegistry } from 'react-native';
import App from './src/App';
import { name as appName } from './app.json';
const uiManager = global?.nativeFabricUIManager ? 'Fabric/New Arch' : 'Paper/Old Arch';
console.log(`Using ${uiManager}`);
AppRegistry.registerComponent(appName, () => App);

View File

@ -9,21 +9,21 @@
/* Begin PBXBuildFile section */
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2974027C475F8964BCB398F9 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
722A1C7BDEE5E8B6E6971EA3 /* libPods-CameraKitExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191D1EBB8F1C844E1CA62B17 /* libPods-CameraKitExample.a */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
D975D4EB80B67AD86A792025 /* libPods-CameraKitExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E6E2B4A77CDB7834D09E2292 /* libPods-CameraKitExample.a */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0FFDC1ABAC32A4DB4D28CC18 /* Pods-CameraKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CameraKitExample.debug.xcconfig"; path = "Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample.debug.xcconfig"; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* CameraKitExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CameraKitExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = CameraKitExample/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = CameraKitExample/Info.plist; sourceTree = "<group>"; };
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = CameraKitExample/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
191D1EBB8F1C844E1CA62B17 /* libPods-CameraKitExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CameraKitExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
2F83BAA1040463A57FFB7C9A /* Pods-CameraKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CameraKitExample.release.xcconfig"; path = "Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample.release.xcconfig"; sourceTree = "<group>"; };
358558293FE95B474D1FC005 /* Pods-CameraKitExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CameraKitExample.debug.xcconfig"; path = "Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample.debug.xcconfig"; sourceTree = "<group>"; };
3E4898C86F19D8D285B59EF7 /* Pods-CameraKitExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CameraKitExample.release.xcconfig"; path = "Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample.release.xcconfig"; sourceTree = "<group>"; };
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = CameraKitExample/AppDelegate.swift; sourceTree = "<group>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = CameraKitExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
E6E2B4A77CDB7834D09E2292 /* libPods-CameraKitExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CameraKitExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
@ -32,7 +32,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
722A1C7BDEE5E8B6E6971EA3 /* libPods-CameraKitExample.a in Frameworks */,
D975D4EB80B67AD86A792025 /* libPods-CameraKitExample.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -55,7 +55,7 @@
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
191D1EBB8F1C844E1CA62B17 /* libPods-CameraKitExample.a */,
E6E2B4A77CDB7834D09E2292 /* libPods-CameraKitExample.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -92,8 +92,8 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
358558293FE95B474D1FC005 /* Pods-CameraKitExample.debug.xcconfig */,
2F83BAA1040463A57FFB7C9A /* Pods-CameraKitExample.release.xcconfig */,
0FFDC1ABAC32A4DB4D28CC18 /* Pods-CameraKitExample.debug.xcconfig */,
3E4898C86F19D8D285B59EF7 /* Pods-CameraKitExample.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@ -105,13 +105,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "CameraKitExample" */;
buildPhases = (
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
B31039B35BCBA0F1930CC09D /* [CP] Check Pods Manifest.lock */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
F011528C18328DDFDA366E5E /* [CP] Embed Pods Frameworks */,
7AE0101032D021A93E0531B9 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -183,24 +183,24 @@
shellPath = /bin/sh;
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
7AE0101032D021A93E0531B9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources.sh\"\n";
showEnvVarsInLog = 0;
};
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
B31039B35BCBA0F1930CC09D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -222,21 +222,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
F011528C18328DDFDA366E5E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CameraKitExample/Pods-CameraKitExample-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -255,7 +255,7 @@
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 358558293FE95B474D1FC005 /* Pods-CameraKitExample.debug.xcconfig */;
baseConfigurationReference = 0FFDC1ABAC32A4DB4D28CC18 /* Pods-CameraKitExample.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@ -286,7 +286,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2F83BAA1040463A57FFB7C9A /* Pods-CameraKitExample.release.xcconfig */;
baseConfigurationReference = 3E4898C86F19D8D285B59EF7 /* Pods-CameraKitExample.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;

View File

@ -34,7 +34,7 @@
<key>NSCameraUsageDescription</key>
<string>For taking photos</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<string>debugging</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>For saving photos</string>
<key>RCTNewArchEnabled</key>

View File

@ -2552,7 +2552,7 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: c91900fa724baee992f01c05eeb4c9e01a807f78
ReactCodegen: a55799cae416c387aeaae3aabc1bc0289ac19cee
ReactCommon: 116d6ee71679243698620d8cd9a9042541e44aa6
ReactNativeCameraKit: e4c112e7acc10772600a7be279d522335f2db10f
ReactNativeCameraKit: cb379ef61a771225da5e3c4ad94d04f4d4a9ad68
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
Yoga: 00013dd9cde63a2d98e8002fcc4f5ddb66c10782

View File

@ -7,8 +7,10 @@
"android": "react-native run-android",
"ios": "react-native run-ios",
"lint": "eslint .",
"start": "react-native start",
"reverse": "adb reverse tcp:8081 tcp:8081"
"start": "react-native start --client-logs",
"reinstall": "rm -rf ios/Pods && bundle && rm -rf ../node_modules/ ../android/build/ ./node_modules/ ./ios/Pods/ ./android/app/build/ ./android/app/.cxx && cd ../ && yarn && cd example && yarn",
"reverse": "adb reverse tcp:8081 tcp:8081",
"postinstall": "cd ios && bundle exec pod install"
},
"dependencies": {
"react": "19.1.0",

View File

@ -119,6 +119,7 @@ const BarcodeExample = ({ onBack }: { onBack: () => void }) => {
flashMode={flashData?.mode}
zoomMode="on"
focusMode="on"
scanThrottleDelay={2000}
torchMode={torchMode ? 'on' : 'off'}
onOrientationChange={(e) => {
// We recommend locking the camera UI to portrait (using a different library)

View File

@ -4,9 +4,7 @@ import { View, Platform } from 'react-native';
// Dummy implementation of SafeAreaView
// In a real app, please use the react-native-safe-area-context package
function SafeAreaView({ style, children }: { style?: any; children: React.ReactNode }) {
const paddingTop = Platform.OS === 'android' ? 50 : 0;
const paddingBottom = Platform.OS === 'android' ? 50 : 0;
return <View style={[{ paddingTop, paddingBottom }, style]}>{children}</View>;
return <View style={[{ paddingTop: 50, paddingBottom: 50 }, style]}>{children}</View>;
}
export default SafeAreaView;

View File

@ -3,7 +3,7 @@
// ReactNativeCameraKit
//
@import AVFoundation;
#import <AVFoundation/AVFoundation.h>
#if __has_include(<React/RCTBridge.h>)
#import <React/RCTViewManager.h>

View File

@ -7,10 +7,10 @@
#import <React/RCTFabricComponentsPlugins.h>
#import <folly/dynamic.h>
#import <react/renderer/components/rncamerakit_specs/ComponentDescriptors.h>
#import <react/renderer/components/rncamerakit_specs/EventEmitters.h>
#import <react/renderer/components/rncamerakit_specs/Props.h>
#import <react/renderer/components/rncamerakit_specs/RCTComponentViewHelpers.h>
#import "../generated/rncamerakit_specs/ComponentDescriptors.h"
#import "../generated/rncamerakit_specs/EventEmitters.h"
#import "../generated/rncamerakit_specs/Props.h"
#import "../generated/rncamerakit_specs/RCTComponentViewHelpers.h"
#import "ReactNativeCameraKit-Swift.pre.h"
@ -148,31 +148,42 @@ static id CKConvertFollyDynamicToId(const folly::dynamic &dyn)
- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
const auto &newProps = static_cast<const CKCameraProps &>(*props);
const auto &oldViewProps = *std::static_pointer_cast<CKCameraProps const>(_props);
const auto &newProps = *std::static_pointer_cast<CKCameraProps const>(props);
NSMutableArray<NSString *> *changedProps = [NSMutableArray new];
id cameraType = CKConvertFollyDynamicToId(newProps.cameraType);
if (cameraType != nil && [cameraType isKindOfClass:NSString.class]) {
_view.cameraType = [cameraType isEqualToString:@"back"] ? CKCameraTypeBack : CKCameraTypeFront;
// Keep changedProps aligned with CameraView.swift didSetProps
// Include event-related props so CameraView can update listeners/state
[changedProps addObject:@"onOrientationChange"];
[changedProps addObject:@"onZoom"];
[changedProps addObject:@"onReadCode"];
if (oldViewProps.cameraType != newProps.cameraType) {
_view.cameraType = newProps.cameraType == "back" ? CKCameraTypeBack : CKCameraTypeFront;
[changedProps addObject:@"cameraType"];
}
id resizeMode = CKConvertFollyDynamicToId(newProps.resizeMode);
if (resizeMode != nil && [resizeMode isKindOfClass:NSString.class]) {
_view.resizeMode = [resizeMode isEqualToString:@"contain"] ? CKResizeModeContain : CKResizeModeCover;
if (oldViewProps.resizeMode != newProps.resizeMode) {
_view.resizeMode = newProps.resizeMode == "contain" ? CKResizeModeContain : CKResizeModeCover;
[changedProps addObject:@"resizeMode"];
}
id flashMode = CKConvertFollyDynamicToId(newProps.flashMode);
if (flashMode != nil && [flashMode isKindOfClass:NSString.class]) {
if (oldViewProps.flashMode != newProps.flashMode) {
_view.flashMode = [flashMode isEqualToString:@"auto"] ? CKFlashModeAuto : [flashMode isEqualToString:@"on"] ? CKFlashModeOn : CKFlashModeOff;
[changedProps addObject:@"flashMode"];
}
id maxPhotoQualityPrioritization = CKConvertFollyDynamicToId(newProps.maxPhotoQualityPrioritization);
if (maxPhotoQualityPrioritization != nil && [maxPhotoQualityPrioritization isKindOfClass:NSString.class]) {
_view.maxPhotoQualityPrioritization = [maxPhotoQualityPrioritization isEqualToString:@"balanced"] ? CKMaxPhotoQualityPrioritizationBalanced : [maxPhotoQualityPrioritization isEqualToString:@"quality"] ? CKMaxPhotoQualityPrioritizationQuality : CKMaxPhotoQualityPrioritizationSpeed;
if (oldViewProps.maxPhotoQualityPrioritization != newProps.maxPhotoQualityPrioritization) {
if (newProps.maxPhotoQualityPrioritization == "balanced") {
_view.maxPhotoQualityPrioritization = CKMaxPhotoQualityPrioritizationBalanced;
} else if (newProps.maxPhotoQualityPrioritization == "quality") {
_view.maxPhotoQualityPrioritization = CKMaxPhotoQualityPrioritizationQuality;
} else {
_view.maxPhotoQualityPrioritization = CKMaxPhotoQualityPrioritizationSpeed;
}
[changedProps addObject:@"maxPhotoQualityPrioritization"];
}
id torchMode = CKConvertFollyDynamicToId(newProps.torchMode);
if (torchMode != nil && [torchMode isKindOfClass:NSString.class]) {
_view.torchMode = [torchMode isEqualToString:@"on"] ? CKTorchModeOn : CKTorchModeOff;
if (oldViewProps.torchMode != newProps.torchMode) {
_view.torchMode = newProps.torchMode == "on" ? CKTorchModeOn : CKTorchModeOff;
[changedProps addObject:@"torchMode"];
}
id ratioOverlay = CKConvertFollyDynamicToId(newProps.ratioOverlay);
@ -180,9 +191,8 @@ static id CKConvertFollyDynamicToId(const folly::dynamic &dyn)
_view.ratioOverlay = ratioOverlay;
[changedProps addObject:@"ratioOverlay"];
}
UIColor *ratioOverlayColor = RCTUIColorFromSharedColor(newProps.ratioOverlayColor);
if (ratioOverlayColor != nil) {
_view.ratioOverlayColor = ratioOverlayColor;
if (oldViewProps.ratioOverlayColor != newProps.ratioOverlayColor) {
_view.ratioOverlayColor = RCTUIColorFromSharedColor(newProps.ratioOverlayColor);
[changedProps addObject:@"ratioOverlayColor"];
}
if (_view.scanBarcode != newProps.scanBarcode) {
@ -193,48 +203,43 @@ static id CKConvertFollyDynamicToId(const folly::dynamic &dyn)
_view.showFrame = newProps.showFrame;
[changedProps addObject:@"showFrame"];
}
id scanThrottleDelay = CKConvertFollyDynamicToId(newProps.scanThrottleDelay);
if (scanThrottleDelay != nil) {
_view.scanThrottleDelay = [scanThrottleDelay intValue];
if (newProps.scanThrottleDelay > -1) {
_view.scanThrottleDelay = newProps.scanThrottleDelay;
[changedProps addObject:@"scanThrottleDelay"];
}
UIColor *frameColor = RCTUIColorFromSharedColor(newProps.frameColor);
if (frameColor != nil) {
_view.frameColor = frameColor;
if (oldViewProps.frameColor != newProps.frameColor) {
_view.frameColor = RCTUIColorFromSharedColor(newProps.frameColor);
[changedProps addObject:@"frameColor"];
}
UIColor *laserColor = RCTUIColorFromSharedColor(newProps.laserColor);
if (laserColor != nil) {
if (oldViewProps.laserColor != newProps.laserColor) {
UIColor *laserColor = RCTUIColorFromSharedColor(newProps.laserColor);
_view.laserColor = laserColor;
[changedProps addObject:@"laserColor"];
}
id resetFocusTimeout = CKConvertFollyDynamicToId(newProps.resetFocusTimeout);
if (resetFocusTimeout != nil) {
_view.resetFocusTimeout = [resetFocusTimeout intValue];
if (oldViewProps.resetFocusTimeout != newProps.resetFocusTimeout) {
_view.resetFocusTimeout = newProps.resetFocusTimeout;
[changedProps addObject:@"resetFocusTimeout"];
}
if (_view.resetFocusWhenMotionDetected != newProps.resetFocusWhenMotionDetected) {
_view.resetFocusWhenMotionDetected = newProps.resetFocusWhenMotionDetected;
[changedProps addObject:@"resetFocusWhenMotionDetected"];
}
id focusMode = CKConvertFollyDynamicToId(newProps.focusMode);
if (focusMode != nil) {
if (oldViewProps.focusMode != newProps.focusMode) {
id focusMode = CKConvertFollyDynamicToId(newProps.focusMode);
_view.focusMode = [focusMode isEqualToString:@"on"] ? CKFocusModeOn : CKFocusModeOff;
[changedProps addObject:@"focusMode"];
}
id zoomMode = CKConvertFollyDynamicToId(newProps.zoomMode);
if (zoomMode != nil) {
if (oldViewProps.zoomMode != newProps.zoomMode) {
id zoomMode = CKConvertFollyDynamicToId(newProps.zoomMode);
_view.zoomMode = [zoomMode isEqualToString:@"on"] ? CKZoomModeOn : CKZoomModeOff;
[changedProps addObject:@"zoomMode"];
}
id zoom = CKConvertFollyDynamicToId(newProps.zoom);
if (zoom != nil) {
_view.zoom = zoom;
if (oldViewProps.zoom != newProps.zoom) {
_view.zoom = newProps.zoom > -1 ? @(newProps.zoom) : nil;
[changedProps addObject:@"zoom"];
}
id maxZoom = CKConvertFollyDynamicToId(newProps.maxZoom);
if (maxZoom != nil) {
_view.maxZoom = maxZoom;
if (oldViewProps.maxZoom != newProps.maxZoom) {
_view.maxZoom = newProps.maxZoom > -1 ? @(newProps.maxZoom) : nil;
[changedProps addObject:@"maxZoom"];
}
float barcodeWidth = newProps.barcodeFrameSize.width;
@ -249,6 +254,14 @@ static id CKConvertFollyDynamicToId(const folly::dynamic &dyn)
[_view didSetProps:changedProps];
}
+ (BOOL)shouldBeRecycled
{
// Disable recycling as cameras are expensive to keep in memory and may cause unintended behaviors
// (we need to reset the camera properly when recycling)
// We can enable it later if find that the performance is needed
return NO;
}
- (void)prepareForRecycle
{
[super prepareForRecycle];

View File

@ -5,6 +5,7 @@
import AVFoundation
import Foundation
import React
/*
* Class managing the communication between React Native and the native implementation

View File

@ -4,6 +4,7 @@
//
import AVFoundation
import React
protocol CameraProtocol: AnyObject, FocusInterfaceViewDelegate {
var previewView: UIView { get }

View File

@ -6,6 +6,7 @@
import AVFoundation
import UIKit
import AVKit
import React
/*
* View abtracting the logic unrelated to the actual camera

View File

@ -2,7 +2,7 @@
#import <UIKit/UIKit.h>
#ifdef RCT_NEW_ARCH_ENABLED
#import "rncamerakit_specs/rncamerakit_specs.h"
#import "../generated/rncamerakit_specs/rncamerakit_specs.h"
#else
#import <React/RCTBridge.h>
#endif

View File

@ -8,6 +8,7 @@
import AVFoundation
import UIKit
import CoreMotion
import React
/*
* Real camera implementation that uses AVFoundation

View File

@ -5,6 +5,7 @@
import AVFoundation
import UIKit
import React
/*
* Fake camera implementation to be used on simulator

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#if __has_include(<React-RCTAppDelegate/RCTDependencyProvider.h>)
#import <React-RCTAppDelegate/RCTDependencyProvider.h>
#elif __has_include(<React_RCTAppDelegate/RCTDependencyProvider.h>)
#import <React_RCTAppDelegate/RCTDependencyProvider.h>
#else
#import "RCTDependencyProvider.h"
#endif
NS_ASSUME_NONNULL_BEGIN
@interface RCTAppDependencyProvider : NSObject <RCTDependencyProvider>
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTAppDependencyProvider.h"
#import <ReactCodegen/RCTModulesConformingToProtocolsProvider.h>
#import <ReactCodegen/RCTThirdPartyComponentsProvider.h>
#import <ReactCodegen/RCTModuleProviders.h>
@implementation RCTAppDependencyProvider
- (nonnull NSArray<NSString *> *)URLRequestHandlerClassNames {
return RCTModulesConformingToProtocolsProvider.URLRequestHandlerClassNames;
}
- (nonnull NSArray<NSString *> *)imageDataDecoderClassNames {
return RCTModulesConformingToProtocolsProvider.imageDataDecoderClassNames;
}
- (nonnull NSArray<NSString *> *)imageURLLoaderClassNames {
return RCTModulesConformingToProtocolsProvider.imageURLLoaderClassNames;
}
- (nonnull NSDictionary<NSString *,Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents {
return RCTThirdPartyComponentsProvider.thirdPartyFabricComponents;
}
- (nonnull NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders {
return RCTModuleProviders.moduleProviders;
}
@end

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@protocol RCTModuleProvider;
@interface RCTModuleProviders: NSObject
+ (NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders;
@end

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import "RCTModuleProviders.h"
#import <ReactCommon/RCTTurboModule.h>
#import <React/RCTLog.h>
@implementation RCTModuleProviders
+ (NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders
{
static NSDictionary<NSString *, id<RCTModuleProvider>> *providers = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSDictionary<NSString *, NSString *> * moduleMapping = @{
};
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:moduleMapping.count];
for (NSString *key in moduleMapping) {
NSString * moduleProviderName = moduleMapping[key];
Class klass = NSClassFromString(moduleProviderName);
if (!klass) {
RCTLogError(@"Module provider %@ cannot be found in the runtime", moduleProviderName);
continue;
}
id instance = [klass new];
if (![instance respondsToSelector:@selector(getTurboModule:)]) {
RCTLogError(@"Module provider %@ does not conform to RCTModuleProvider", moduleProviderName);
continue;
}
[dict setObject:instance forKey:key];
}
providers = dict;
});
return providers;
}
@end

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@interface RCTModulesConformingToProtocolsProvider: NSObject
+(NSArray<NSString *> *)imageURLLoaderClassNames;
+(NSArray<NSString *> *)imageDataDecoderClassNames;
+(NSArray<NSString *> *)URLRequestHandlerClassNames;
@end

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTModulesConformingToProtocolsProvider.h"
@implementation RCTModulesConformingToProtocolsProvider
+(NSArray<NSString *> *)imageURLLoaderClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
];
});
return classNames;
}
+(NSArray<NSString *> *)imageDataDecoderClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
];
});
return classNames;
}
+(NSArray<NSString *> *)URLRequestHandlerClassNames
{
static NSArray<NSString *> *classNames = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
classNames = @[
];
});
return classNames;
}
@end

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@protocol RCTComponentViewProtocol;
@interface RCTThirdPartyComponentsProvider: NSObject
+ (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
@end

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import "RCTThirdPartyComponentsProvider.h"
#import <React/RCTComponentViewProtocol.h>
@implementation RCTThirdPartyComponentsProvider
+ (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents
{
static NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *thirdPartyComponents = nil;
static dispatch_once_t nativeComponentsToken;
dispatch_once(&nativeComponentsToken, ^{
thirdPartyComponents = @{
@"CKCamera": NSClassFromString(@"CKCameraViewComponentView"), // react-native-camera-kit
};
});
return thirdPartyComponents;
}
@end

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
@interface RCTUnstableModulesRequiringMainQueueSetupProvider: NSObject
+(NSArray<NSString *> *)modules;
@end

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTUnstableModulesRequiringMainQueueSetupProvider.h"
@implementation RCTUnstableModulesRequiringMainQueueSetupProvider
+(NSArray<NSString *> *)modules
{
return @[
];
}
@end

View File

@ -0,0 +1,34 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
version = "0.79.0"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
Pod::Spec.new do |s|
s.name = "ReactAppDependencyProvider"
s.version = version
s.summary = "The third party dependency provider for the app"
s.homepage = "https://reactnative.dev/"
s.documentation_url = "https://reactnative.dev/"
s.license = "MIT"
s.author = "Meta Platforms, Inc. and its affiliates"
s.platforms = min_supported_versions
s.source = source
s.source_files = "**/RCTAppDependencyProvider.{h,mm}"
# This guard prevent to install the dependencies when we run `pod install` in the old architecture.
s.pod_target_xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
"DEFINES_MODULE" => "YES"
}
s.dependency "ReactCodegen"
end

View File

@ -0,0 +1,113 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
version = "0.79.0"
source = { :git => 'https://github.com/facebook/react-native.git' }
if version == '1000.0.0'
# This is an unpublished version, use the latest commit hash of the react-native repo, which were presumably in.
source[:commit] = `git rev-parse HEAD`.strip if system("git rev-parse --git-dir > /dev/null 2>&1")
else
source[:tag] = "v#{version}"
end
use_frameworks = ENV['USE_FRAMEWORKS'] != nil
folly_compiler_flags = Helpers::Constants.folly_config[:compiler_flags]
boost_compiler_flags = Helpers::Constants.boost_config[:compiler_flags]
header_search_paths = [
"\"$(PODS_ROOT)/boost\"",
"\"$(PODS_ROOT)/RCT-Folly\"",
"\"$(PODS_ROOT)/DoubleConversion\"",
"\"$(PODS_ROOT)/fast_float/include\"",
"\"$(PODS_ROOT)/fmt/include\"",
"\"${PODS_ROOT}/Headers/Public/ReactCodegen/react/renderer/components\"",
"\"$(PODS_ROOT)/Headers/Private/React-Fabric\"",
"\"$(PODS_ROOT)/Headers/Private/React-RCTFabric\"",
"\"$(PODS_ROOT)/Headers/Private/Yoga\"",
"\"$(PODS_TARGET_SRCROOT)\"",
]
framework_search_paths = []
if use_frameworks
ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/components/view/platform/cxx"])
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-FabricImage", "React_FabricImage", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-graphics", "React_graphics", ["react/renderer/graphics/platform/ios"]))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "ReactCommon", "ReactCommon", ["react/nativemodule/core"]))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-NativeModulesApple", "React_NativeModulesApple", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-RCTFabric", "RCTFabric", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-debug", "React_debug", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-rendererdebug", "React_rendererdebug", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-utils", "React_utils", []))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-featureflags", "React_featureflags", []))
.each { |search_path|
header_search_paths << "\"#{search_path}\""
}
end
Pod::Spec.new do |s|
s.name = "ReactCodegen"
s.version = version
s.summary = 'Temp pod for generated files for React Native'
s.homepage = 'https://facebook.com/'
s.license = 'Unlicense'
s.authors = 'Facebook'
s.compiler_flags = "#{folly_compiler_flags} #{boost_compiler_flags} -Wno-nullability-completeness -std=c++20"
s.source = { :git => '' }
s.header_mappings_dir = './'
s.platforms = min_supported_versions
s.source_files = "**/*.{h,mm,cpp}"
s.exclude_files = "RCTAppDependencyProvider.{h,mm}" # these files are generated in the same codegen path but needs to belong to a different pod
s.pod_target_xcconfig = {
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
"FRAMEWORK_SEARCH_PATHS" => framework_search_paths,
"OTHER_CPLUSPLUSFLAGS" => "$(inherited) #{folly_compiler_flags} #{boost_compiler_flags}"
}
s.dependency "React-jsiexecutor"
s.dependency "RCT-Folly"
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "React-Core"
s.dependency "React-jsi"
s.dependency "ReactCommon/turbomodule/bridging"
s.dependency "ReactCommon/turbomodule/core"
s.dependency "React-NativeModulesApple"
s.dependency "glog"
s.dependency "DoubleConversion"
s.dependency 'React-graphics'
s.dependency 'React-rendererdebug'
s.dependency 'React-Fabric'
s.dependency 'React-FabricImage'
s.dependency 'React-debug'
s.dependency 'React-utils'
s.dependency 'React-featureflags'
s.dependency 'React-RCTAppDelegate'
depend_on_js_engine(s)
s.script_phases = {
'name' => 'Generate Specs',
'execution_position' => :before_compile,
'input_files' => ["${PODS_ROOT}/../../../src/specs/CameraNativeComponent.ts",
"${PODS_ROOT}/../../../src/specs/NativeCameraKitModule.ts"],
'show_env_vars_in_log' => true,
'output_files' => ["${DERIVED_FILE_DIR}/react-codegen.log"],
'script': <<-SCRIPT
pushd "$PODS_ROOT/../" > /dev/null
RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd)
popd >/dev/null
export RCT_SCRIPT_RN_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT/../../node_modules/react-native"
export RCT_SCRIPT_APP_PATH="$RCT_SCRIPT_POD_INSTALLATION_ROOT/../.."
export RCT_SCRIPT_OUTPUT_DIR="$RCT_SCRIPT_POD_INSTALLATION_ROOT"
export RCT_SCRIPT_TYPE="withCodegenDiscovery"
SCRIPT_PHASES_SCRIPT="$RCT_SCRIPT_RN_DIR/scripts/react_native_pods_utils/script_phases.sh"
WITH_ENVIRONMENT="$RCT_SCRIPT_RN_DIR/scripts/xcode/with-environment.sh"
/bin/sh -c "$WITH_ENVIRONMENT $SCRIPT_PHASES_SCRIPT"
SCRIPT
}
end

View File

@ -0,0 +1,22 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorCpp.js
*/
#include "ComponentDescriptors.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
namespace facebook::react {
void rncamerakit_specs_registerComponentDescriptorsFromCodegen(
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry) {
registry->add(concreteComponentDescriptorProvider<CKCameraComponentDescriptor>());
}
} // namespace facebook::react

View File

@ -0,0 +1,24 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentDescriptorH.js
*/
#pragma once
#include "ShadowNodes.h"
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
namespace facebook::react {
using CKCameraComponentDescriptor = ConcreteComponentDescriptor<CKCameraShadowNode>;
void rncamerakit_specs_registerComponentDescriptorsFromCodegen(
std::shared_ptr<const ComponentDescriptorProviderRegistry> registry);
} // namespace facebook::react

View File

@ -0,0 +1,79 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterCpp.js
*/
#include "EventEmitters.h"
namespace facebook::react {
void CKCameraEventEmitter::onOrientationChange(OnOrientationChange $event) const {
dispatchEvent("orientationChange", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "orientation", $event.orientation);
return $payload;
});
}
void CKCameraEventEmitter::onZoom(OnZoom $event) const {
dispatchEvent("zoom", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "zoom", $event.zoom);
return $payload;
});
}
void CKCameraEventEmitter::onError(OnError $event) const {
dispatchEvent("error", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "errorMessage", $event.errorMessage);
return $payload;
});
}
void CKCameraEventEmitter::onReadCode(OnReadCode $event) const {
dispatchEvent("readCode", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "codeStringValue", $event.codeStringValue);
$payload.setProperty(runtime, "codeFormat", $event.codeFormat);
return $payload;
});
}
void CKCameraEventEmitter::onCaptureButtonPressIn(OnCaptureButtonPressIn $event) const {
dispatchEvent("captureButtonPressIn", [](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
return $payload;
});
}
void CKCameraEventEmitter::onCaptureButtonPressOut(OnCaptureButtonPressOut $event) const {
dispatchEvent("captureButtonPressOut", [](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
return $payload;
});
}
void CKCameraEventEmitter::onPictureTaken(OnPictureTaken $event) const {
dispatchEvent("pictureTaken", [$event=std::move($event)](jsi::Runtime &runtime) {
auto $payload = jsi::Object(runtime);
$payload.setProperty(runtime, "uri", $event.uri);
return $payload;
});
}
} // namespace facebook::react

View File

@ -0,0 +1,62 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateEventEmitterH.js
*/
#pragma once
#include <react/renderer/components/view/ViewEventEmitter.h>
namespace facebook::react {
class CKCameraEventEmitter : public ViewEventEmitter {
public:
using ViewEventEmitter::ViewEventEmitter;
struct OnOrientationChange {
int orientation;
};
struct OnZoom {
double zoom;
};
struct OnError {
std::string errorMessage;
};
struct OnReadCode {
std::string codeStringValue;
std::string codeFormat;
};
struct OnCaptureButtonPressIn {
};
struct OnCaptureButtonPressOut {
};
struct OnPictureTaken {
std::string uri;
};
void onOrientationChange(OnOrientationChange value) const;
void onZoom(OnZoom value) const;
void onError(OnError value) const;
void onReadCode(OnReadCode value) const;
void onCaptureButtonPressIn(OnCaptureButtonPressIn value) const;
void onCaptureButtonPressOut(OnCaptureButtonPressOut value) const;
void onPictureTaken(OnPictureTaken value) const;
};
} // namespace facebook::react

View File

@ -0,0 +1,46 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsCpp.js
*/
#include "Props.h"
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
namespace facebook::react {
CKCameraProps::CKCameraProps(
const PropsParserContext &context,
const CKCameraProps &sourceProps,
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
flashMode(convertRawProp(context, rawProps, "flashMode", sourceProps.flashMode, {})),
focusMode(convertRawProp(context, rawProps, "focusMode", sourceProps.focusMode, {})),
maxPhotoQualityPrioritization(convertRawProp(context, rawProps, "maxPhotoQualityPrioritization", sourceProps.maxPhotoQualityPrioritization, {})),
zoomMode(convertRawProp(context, rawProps, "zoomMode", sourceProps.zoomMode, {})),
zoom(convertRawProp(context, rawProps, "zoom", sourceProps.zoom, {-1.0})),
maxZoom(convertRawProp(context, rawProps, "maxZoom", sourceProps.maxZoom, {-1.0})),
torchMode(convertRawProp(context, rawProps, "torchMode", sourceProps.torchMode, {})),
cameraType(convertRawProp(context, rawProps, "cameraType", sourceProps.cameraType, {})),
scanBarcode(convertRawProp(context, rawProps, "scanBarcode", sourceProps.scanBarcode, {false})),
showFrame(convertRawProp(context, rawProps, "showFrame", sourceProps.showFrame, {false})),
laserColor(convertRawProp(context, rawProps, "laserColor", sourceProps.laserColor, {})),
frameColor(convertRawProp(context, rawProps, "frameColor", sourceProps.frameColor, {})),
ratioOverlay(convertRawProp(context, rawProps, "ratioOverlay", sourceProps.ratioOverlay, {})),
ratioOverlayColor(convertRawProp(context, rawProps, "ratioOverlayColor", sourceProps.ratioOverlayColor, {})),
resetFocusTimeout(convertRawProp(context, rawProps, "resetFocusTimeout", sourceProps.resetFocusTimeout, {-1})),
resetFocusWhenMotionDetected(convertRawProp(context, rawProps, "resetFocusWhenMotionDetected", sourceProps.resetFocusWhenMotionDetected, {false})),
resizeMode(convertRawProp(context, rawProps, "resizeMode", sourceProps.resizeMode, {})),
scanThrottleDelay(convertRawProp(context, rawProps, "scanThrottleDelay", sourceProps.scanThrottleDelay, {-1})),
barcodeFrameSize(convertRawProp(context, rawProps, "barcodeFrameSize", sourceProps.barcodeFrameSize, {})),
shutterPhotoSound(convertRawProp(context, rawProps, "shutterPhotoSound", sourceProps.shutterPhotoSound, {false})),
shutterAnimationDuration(convertRawProp(context, rawProps, "shutterAnimationDuration", sourceProps.shutterAnimationDuration, {-1})),
outputPath(convertRawProp(context, rawProps, "outputPath", sourceProps.outputPath, {}))
{}
} // namespace facebook::react

View File

@ -0,0 +1,71 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GeneratePropsH.js
*/
#pragma once
#include <react/renderer/components/view/ViewProps.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/propsConversions.h>
#include <react/renderer/graphics/Color.h>
namespace facebook::react {
struct CKCameraBarcodeFrameSizeStruct {
Float width{300.0};
Float height{150.0};
};
static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, CKCameraBarcodeFrameSizeStruct &result) {
auto map = (std::unordered_map<std::string, RawValue>)value;
auto tmp_width = map.find("width");
if (tmp_width != map.end()) {
fromRawValue(context, tmp_width->second, result.width);
}
auto tmp_height = map.find("height");
if (tmp_height != map.end()) {
fromRawValue(context, tmp_height->second, result.height);
}
}
static inline std::string toString(const CKCameraBarcodeFrameSizeStruct &value) {
return "[Object CKCameraBarcodeFrameSizeStruct]";
}
class CKCameraProps final : public ViewProps {
public:
CKCameraProps() = default;
CKCameraProps(const PropsParserContext& context, const CKCameraProps &sourceProps, const RawProps &rawProps);
#pragma mark - Props
std::string flashMode{};
std::string focusMode{};
std::string maxPhotoQualityPrioritization{};
std::string zoomMode{};
double zoom{-1.0};
double maxZoom{-1.0};
std::string torchMode{};
std::string cameraType{};
bool scanBarcode{false};
bool showFrame{false};
SharedColor laserColor{};
SharedColor frameColor{};
std::string ratioOverlay{};
SharedColor ratioOverlayColor{};
int resetFocusTimeout{-1};
bool resetFocusWhenMotionDetected{false};
std::string resizeMode{};
int scanThrottleDelay{-1};
CKCameraBarcodeFrameSizeStruct barcodeFrameSize{};
bool shutterPhotoSound{false};
int shutterAnimationDuration{-1};
std::string outputPath{};
};
} // namespace facebook::react

View File

@ -0,0 +1,20 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateComponentHObjCpp.js
*/
#import <Foundation/Foundation.h>
#import <React/RCTDefines.h>
#import <React/RCTLog.h>
NS_ASSUME_NONNULL_BEGIN
@protocol RCTCKCameraViewProtocol <NSObject>
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,17 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeCpp.js
*/
#include "ShadowNodes.h"
namespace facebook::react {
extern const char CKCameraComponentName[] = "CKCamera";
} // namespace facebook::react

View File

@ -0,0 +1,32 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateShadowNodeH.js
*/
#pragma once
#include "EventEmitters.h"
#include "Props.h"
#include "States.h"
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <jsi/jsi.h>
namespace facebook::react {
JSI_EXPORT extern const char CKCameraComponentName[];
/*
* `ShadowNode` for <CKCamera> component.
*/
using CKCameraShadowNode = ConcreteViewShadowNode<
CKCameraComponentName,
CKCameraProps,
CKCameraEventEmitter,
CKCameraState>;
} // namespace facebook::react

View File

@ -0,0 +1,16 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateCpp.js
*/
#include "States.h"
namespace facebook::react {
} // namespace facebook::react

View File

@ -0,0 +1,29 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateStateH.js
*/
#pragma once
#ifdef ANDROID
#include <folly/dynamic.h>
#endif
namespace facebook::react {
class CKCameraState {
public:
CKCameraState() = default;
#ifdef ANDROID
CKCameraState(CKCameraState const &previousState, folly::dynamic data){};
folly::dynamic getDynamic() const {
return {};
};
#endif
};
} // namespace facebook::react

View File

@ -0,0 +1,53 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleObjCpp
*
* We create an umbrella header (and corresponding implementation) here since
* Cxx compilation in BUCK has a limitation: source-code producing genrule()s
* must have a single output. More files => more genrule()s => slower builds.
*/
#import "rncamerakit_specs.h"
@implementation NativeCameraKitModuleSpecBase
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper
{
_eventEmitterCallback = std::move(eventEmitterCallbackWrapper->_eventEmitterCallback);
}
@end
namespace facebook::react {
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_capture(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "capture", @selector(capture:tag:resolve:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_requestDeviceCameraAuthorization(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "requestDeviceCameraAuthorization", @selector(requestDeviceCameraAuthorization:reject:), args, count);
}
static facebook::jsi::Value __hostFunction_NativeCameraKitModuleSpecJSI_checkDeviceCameraAuthorizationStatus(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, PromiseKind, "checkDeviceCameraAuthorizationStatus", @selector(checkDeviceCameraAuthorizationStatus:reject:), args, count);
}
NativeCameraKitModuleSpecJSI::NativeCameraKitModuleSpecJSI(const ObjCTurboModule::InitParams &params)
: ObjCTurboModule(params) {
methodMap_["capture"] = MethodMetadata {2, __hostFunction_NativeCameraKitModuleSpecJSI_capture};
methodMap_["requestDeviceCameraAuthorization"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleSpecJSI_requestDeviceCameraAuthorization};
methodMap_["checkDeviceCameraAuthorizationStatus"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleSpecJSI_checkDeviceCameraAuthorizationStatus};
}
} // namespace facebook::react

View File

@ -0,0 +1,69 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleObjCpp
*
* We create an umbrella header (and corresponding implementation) here since
* Cxx compilation in BUCK has a limitation: source-code producing genrule()s
* must have a single output. More files => more genrule()s => slower builds.
*/
#ifndef __cplusplus
#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm.
#endif
// Avoid multiple includes of rncamerakit_specs symbols
#ifndef rncamerakit_specs_H
#define rncamerakit_specs_H
#import <Foundation/Foundation.h>
#import <RCTRequired/RCTRequired.h>
#import <RCTTypeSafety/RCTConvertHelpers.h>
#import <RCTTypeSafety/RCTTypedModuleConstants.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTCxxConvert.h>
#import <React/RCTManagedPointer.h>
#import <ReactCommon/RCTTurboModule.h>
#import <optional>
#import <vector>
NS_ASSUME_NONNULL_BEGIN
@protocol NativeCameraKitModuleSpec <RCTBridgeModule, RCTTurboModule>
- (void)capture:(NSDictionary *)options
tag:(NSNumber *)tag
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void)requestDeviceCameraAuthorization:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
- (void)checkDeviceCameraAuthorizationStatus:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject;
@end
@interface NativeCameraKitModuleSpecBase : NSObject {
@protected
facebook::react::EventEmitterCallback _eventEmitterCallback;
}
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
@end
namespace facebook::react {
/**
* ObjC++ class for module 'NativeCameraKitModule'
*/
class JSI_EXPORT NativeCameraKitModuleSpecJSI : public ObjCTurboModule {
public:
NativeCameraKitModuleSpecJSI(const ObjCTurboModule::InitParams &params);
};
} // namespace facebook::react
NS_ASSUME_NONNULL_END
#endif // rncamerakit_specs_H

View File

@ -0,0 +1,40 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleCpp.js
*/
#include "rncamerakit_specsJSI.h"
namespace facebook::react {
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_capture(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->capture(
rt,
count <= 0 || args[0].isUndefined() ? std::nullopt : std::make_optional(args[0].asObject(rt)),
count <= 1 || args[1].isUndefined() ? std::nullopt : std::make_optional(args[1].asNumber())
);
}
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_requestDeviceCameraAuthorization(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->requestDeviceCameraAuthorization(
rt
);
}
static jsi::Value __hostFunction_NativeCameraKitModuleCxxSpecJSI_checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
return static_cast<NativeCameraKitModuleCxxSpecJSI *>(&turboModule)->checkDeviceCameraAuthorizationStatus(
rt
);
}
NativeCameraKitModuleCxxSpecJSI::NativeCameraKitModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule("RNCameraKitModule", jsInvoker) {
methodMap_["capture"] = MethodMetadata {2, __hostFunction_NativeCameraKitModuleCxxSpecJSI_capture};
methodMap_["requestDeviceCameraAuthorization"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleCxxSpecJSI_requestDeviceCameraAuthorization};
methodMap_["checkDeviceCameraAuthorizationStatus"] = MethodMetadata {0, __hostFunction_NativeCameraKitModuleCxxSpecJSI_checkDeviceCameraAuthorizationStatus};
}
} // namespace facebook::react

View File

@ -0,0 +1,177 @@
/**
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
*
* Do not edit this file as changes may cause incorrect behavior and will be lost
* once the code is regenerated.
*
* @generated by codegen project: GenerateModuleH.js
*/
#pragma once
#include <ReactCommon/TurboModule.h>
#include <react/bridging/Bridging.h>
namespace facebook::react {
#pragma mark - NativeCameraKitModuleCaptureData
template <typename P0, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct NativeCameraKitModuleCaptureData {
P0 uri;
P1 name;
P2 height;
P3 width;
P4 id;
P5 path;
P6 size;
bool operator==(const NativeCameraKitModuleCaptureData &other) const {
return uri == other.uri && name == other.name && height == other.height && width == other.width && id == other.id && path == other.path && size == other.size;
}
};
template <typename T>
struct NativeCameraKitModuleCaptureDataBridging {
static T types;
static T fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
T result{
bridging::fromJs<decltype(types.uri)>(rt, value.getProperty(rt, "uri"), jsInvoker),
bridging::fromJs<decltype(types.name)>(rt, value.getProperty(rt, "name"), jsInvoker),
bridging::fromJs<decltype(types.height)>(rt, value.getProperty(rt, "height"), jsInvoker),
bridging::fromJs<decltype(types.width)>(rt, value.getProperty(rt, "width"), jsInvoker),
bridging::fromJs<decltype(types.id)>(rt, value.getProperty(rt, "id"), jsInvoker),
bridging::fromJs<decltype(types.path)>(rt, value.getProperty(rt, "path"), jsInvoker),
bridging::fromJs<decltype(types.size)>(rt, value.getProperty(rt, "size"), jsInvoker)};
return result;
}
#ifdef DEBUG
static jsi::String uriToJs(jsi::Runtime &rt, decltype(types.uri) value) {
return bridging::toJs(rt, value);
}
static jsi::String nameToJs(jsi::Runtime &rt, decltype(types.name) value) {
return bridging::toJs(rt, value);
}
static int heightToJs(jsi::Runtime &rt, decltype(types.height) value) {
return bridging::toJs(rt, value);
}
static int widthToJs(jsi::Runtime &rt, decltype(types.width) value) {
return bridging::toJs(rt, value);
}
static jsi::String idToJs(jsi::Runtime &rt, decltype(types.id) value) {
return bridging::toJs(rt, value);
}
static jsi::String pathToJs(jsi::Runtime &rt, decltype(types.path) value) {
return bridging::toJs(rt, value);
}
static int sizeToJs(jsi::Runtime &rt, decltype(types.size) value) {
return bridging::toJs(rt, value);
}
#endif
static jsi::Object toJs(
jsi::Runtime &rt,
const T &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "uri", bridging::toJs(rt, value.uri, jsInvoker));
result.setProperty(rt, "name", bridging::toJs(rt, value.name, jsInvoker));
result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker));
result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker));
if (value.id) {
result.setProperty(rt, "id", bridging::toJs(rt, value.id.value(), jsInvoker));
}
if (value.path) {
result.setProperty(rt, "path", bridging::toJs(rt, value.path.value(), jsInvoker));
}
if (value.size) {
result.setProperty(rt, "size", bridging::toJs(rt, value.size.value(), jsInvoker));
}
return result;
}
};
class JSI_EXPORT NativeCameraKitModuleCxxSpecJSI : public TurboModule {
protected:
NativeCameraKitModuleCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
public:
virtual jsi::Value capture(jsi::Runtime &rt, std::optional<jsi::Object> options, std::optional<double> tag) = 0;
virtual jsi::Value requestDeviceCameraAuthorization(jsi::Runtime &rt) = 0;
virtual jsi::Value checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt) = 0;
};
template <typename T>
class JSI_EXPORT NativeCameraKitModuleCxxSpec : public TurboModule {
public:
jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
return delegate_.create(rt, propName);
}
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
return delegate_.getPropertyNames(runtime);
}
static constexpr std::string_view kModuleName = "RNCameraKitModule";
protected:
NativeCameraKitModuleCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
: TurboModule(std::string{NativeCameraKitModuleCxxSpec::kModuleName}, jsInvoker),
delegate_(reinterpret_cast<T*>(this), jsInvoker) {}
private:
class Delegate : public NativeCameraKitModuleCxxSpecJSI {
public:
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
NativeCameraKitModuleCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {
}
jsi::Value capture(jsi::Runtime &rt, std::optional<jsi::Object> options, std::optional<double> tag) override {
static_assert(
bridging::getParameterCount(&T::capture) == 3,
"Expected capture(...) to have 3 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::capture, jsInvoker_, instance_, std::move(options), std::move(tag));
}
jsi::Value requestDeviceCameraAuthorization(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::requestDeviceCameraAuthorization) == 1,
"Expected requestDeviceCameraAuthorization(...) to have 1 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::requestDeviceCameraAuthorization, jsInvoker_, instance_);
}
jsi::Value checkDeviceCameraAuthorizationStatus(jsi::Runtime &rt) override {
static_assert(
bridging::getParameterCount(&T::checkDeviceCameraAuthorizationStatus) == 1,
"Expected checkDeviceCameraAuthorizationStatus(...) to have 1 parameters");
return bridging::callFromJs<jsi::Value>(
rt, &T::checkDeviceCameraAuthorizationStatus, jsInvoker_, instance_);
}
private:
friend class NativeCameraKitModuleCxxSpec;
T *instance_;
};
Delegate delegate_;
};
} // namespace facebook::react

View File

@ -20,6 +20,7 @@
"release:beta": "yarn clean && yarn build && yarn publish --tag beta --verbose",
"release:local": "yarn clean && yarn build && tmp=$(mktemp) && yarn pack --filename $tmp.tar.gz && open -R $tmp.tar.gz",
"start": "watchman watch-del-all && node node_modules/react-native/local-cli/cli.js start",
"codegen": "react-native codegen --verbose --path . --platform ios --source library --outputPath ios/generated && react-native codegen --verbose --path . --platform android --source library --outputPath android/generated",
"bootstrap": "cd example/ && bundle install && yarn && cd ios/ && bundle exec pod install",
"bootstrap-linux": "cd example/ && yarn"
},
@ -31,24 +32,24 @@
"dependencies": {},
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.74.83",
"@react-native/eslint-config": "0.74.83",
"@react-native/metro-config": "0.74.83",
"@react-native/typescript-config": "0.74.83",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "20.0.0",
"@react-native-community/cli-platform-android": "20.0.0",
"@react-native-community/cli-platform-ios": "20.0.0",
"@react-native/babel-preset": "0.79.0",
"@react-native/eslint-config": "0.79.0",
"@react-native/metro-config": "0.79.0",
"@react-native/typescript-config": "0.79.0",
"@types/react": "^19.0.0",
"@types/react-test-renderer": "^19.0.0",
"eslint": "^8.19.0",
"eslint-plugin-import": "^2.22.1",
"jest": "^29.6.3",
"prettier": "2.8.8",
"react": "18.2.0",
"react-native": "0.74.1",
"react-test-renderer": "18.2.0",
"typescript": "5.0.4"
"react": "19.0.0",
"react-native": "0.79.0",
"react-test-renderer": "19.0.0",
"typescript": "^5.8.3"
},
"peerDependencies": {
"react": "*",
@ -60,9 +61,19 @@
"codegenConfig": {
"name": "rncamerakit_specs",
"type": "all",
"outputDir": {
"ios": "ios/generated",
"android": "android/generated"
},
"includesGeneratedCode": true,
"jsSrcsDir": "src/specs",
"android": {
"javaPackageName": "com.rncamerakit"
},
"ios": {
"componentProvider": {
"CKCamera": "CKCameraViewComponentView"
}
}
},
"packageManager": "yarn@1.22.22"

19
react-native.config.js Normal file
View File

@ -0,0 +1,19 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @noflow
*/
module.exports = {
dependency: {
platforms: {
android: {
cmakeListsPath: 'generated/jni/CMakeLists.txt',
},
},
},
};

View File

@ -8,6 +8,13 @@ import NativeCameraKitModule from './specs/NativeCameraKitModule';
const Camera = React.forwardRef<CameraApi, CameraProps>((props, ref) => {
const nativeRef = React.useRef(null);
// RN doesn't support optional view props yet (sigh)
// so we have to use -1 to indicate 'undefined'
// All int/float/double props from src/specs/CameraNativeComponent.ts need be mentioned here
props.zoom = props.zoom ?? -1;
props.maxZoom = props.maxZoom ?? -1;
props.scanThrottleDelay = props.scanThrottleDelay ?? -1;
React.useImperativeHandle(ref, () => ({
capture: async (options = {}) => {
return await NativeCameraKitModule.capture(options, findNodeHandle(nativeRef.current) ?? undefined);

View File

@ -8,6 +8,13 @@ import NativeCameraKitModule from './specs/NativeCameraKitModule';
const Camera = React.forwardRef<CameraApi, CameraProps>((props, ref) => {
const nativeRef = React.useRef(null);
// RN doesn't support optional view props yet (sigh)
// so we have to use -1 to indicate 'undefined'
// All int/float/double props from src/specs/CameraNativeComponent.ts need be mentioned here
props.zoom = props.zoom ?? -1;
props.maxZoom = props.maxZoom ?? -1;
props.scanThrottleDelay = props.scanThrottleDelay ?? -1;
props.resetFocusTimeout = props.resetFocusTimeout ?? 0;
props.resetFocusWhenMotionDetected = props.resetFocusWhenMotionDetected ?? true;

View File

@ -109,7 +109,7 @@ export interface CameraProps extends ViewProps {
resetFocusTimeout?: number;
resetFocusWhenMotionDetected?: boolean;
resizeMode?: ResizeMode;
/** **iOS Only**. Throttle how often the barcode scanner triggers a new scan */
/** Throttle how often the barcode scanner triggers a new scan */
scanThrottleDelay?: number;
/** **iOS Only**. 'speed' provides 60-80% faster image capturing */
maxPhotoQualityPrioritization?: 'balanced' | 'quality' | 'speed';

View File

@ -1,12 +1,16 @@
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
import type { ViewProps, ColorValue } from 'react-native';
import type {
ViewProps,
ColorValue,
HostComponent,
} from 'react-native';
import type {
DirectEventHandler,
Int32,
Double,
WithDefault,
Float,
Int32,
WithDefault
} from 'react-native/Libraries/Types/CodegenTypes';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
type OnReadCodeData = {
codeStringValue: string;
@ -21,38 +25,40 @@ type OnZoom = {
zoom: Double;
}
// We have to use -1 until RN Fabric (New Arch for view components) supports optional values:
// https://github.com/facebook/react-native/issues/49920#issuecomment-3237917813
export interface NativeProps extends ViewProps {
flashMode?: string;
focusMode?: string;
maxPhotoQualityPrioritization?: string;
zoomMode?: string;
zoom?: Double;
maxZoom?: Double;
zoom?: WithDefault<Double, -1>;
maxZoom?: WithDefault<Double, -1>;
torchMode?: string;
cameraType?: string;
onOrientationChange?: DirectEventHandler<OnOrientationChangeData>;
onZoom?: DirectEventHandler<OnZoom>;
onError?: DirectEventHandler<{errorMessage: string }>;
scanBarcode?: boolean;
showFrame?: boolean;
laserColor?: ColorValue;
frameColor?: ColorValue;
onReadCode?: DirectEventHandler<OnReadCodeData>;
ratioOverlay?: string;
ratioOverlayColor?: ColorValue;
resetFocusTimeout?: Int32;
resetFocusTimeout?: WithDefault<Int32, -1>;
resetFocusWhenMotionDetected?: boolean;
resizeMode?: string;
scanThrottleDelay?: Int32;
scanThrottleDelay?: WithDefault<Int32, -1>;
barcodeFrameSize?: { width?: WithDefault<Float, 300>; height?: WithDefault<Float, 150> };
shutterPhotoSound?: boolean;
onOrientationChange?: DirectEventHandler<OnOrientationChangeData>;
onZoom?: DirectEventHandler<OnZoom>;
onError?: DirectEventHandler<{errorMessage: string }>;
onReadCode?: DirectEventHandler<OnReadCodeData>;
onCaptureButtonPressIn?: DirectEventHandler<{}>;
onCaptureButtonPressOut?: DirectEventHandler<{}>;
// not mentioned in props but available on the native side
shutterAnimationDuration?: Int32;
shutterAnimationDuration?: WithDefault<Int32, -1>;
outputPath?: string;
onPictureTaken?: DirectEventHandler<{uri: string}>;
}
export default codegenNativeComponent<NativeProps>('CKCamera');
export default codegenNativeComponent<NativeProps>('CKCamera') as HostComponent<NativeProps>;

View File

@ -1,5 +1,3 @@
/* eslint-disable @typescript-eslint/ban-types */
// its needed for codegen to work
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
import type { Double, Int32, UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';

4779
yarn.lock

File diff suppressed because it is too large Load Diff