Skip to content

Commit

Permalink
feat: Separate VisionCamera into two subspecs (#2761)
Browse files Browse the repository at this point in the history
* feat: Separate VisionCamera into two subspecs

* Swift

* update podspec

* fix: Refactor

* some fixes

* hmm

* fix: Only export ObjC/Swift visible headers

* fix: Also drop C++ sources

* fix: Move to correct folder

* fix: Fix any remaining C++ includes

* chore: Format

* fix: Fix missingg Swift include

* fix: Add PluginRegistry Swift include

* Update FrameProcessorPluginRegistry.h

* fix: Disable location

* fix: Use `public_header_files` instead of `preserve_paths`

* Disable FP if needed

* fix Podfile

* fix: Fix `dispatch_queue_t` in Swift

* fix: Disable FPs if not built

* Revert "fix: Disable FPs if not built"

This reverts commit 82cb560.

* Remove Example Plugins from source code
  • Loading branch information
mrousavy authored Apr 21, 2024
1 parent 9fcb61a commit f7dbb24
Show file tree
Hide file tree
Showing 19 changed files with 331 additions and 175 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ jobs:
run: yarn install --frozen-lockfile --cwd ..
- name: Remove worklets, skia and reanimated
run: yarn remove react-native-worklets-core @shopify/react-native-skia react-native-reanimated --cwd ..
- name: Remove Example Plugins
run: rm -rf "Frame Processor Plugins/"

- name: Restore buildcache
uses: mikehardy/buildcache-action@v2
Expand Down
115 changes: 69 additions & 46 deletions package/VisionCamera.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json")))

nodeModules = File.join(File.dirname(`cd "#{Pod::Config.instance.installation_root.to_s}" && node --print "require.resolve('react-native/package.json')"`), '..')

enableFrameProcessors = true
if defined?($VCEnableFrameProcessors)
Pod::UI.puts "[VisionCamera] $VCEnableFrameProcessors is set to #{$VCEnableFrameProcessors}!"
enableFrameProcessors = $VCEnableFrameProcessors
end
Pod::UI.puts "[VisionCamera] Thank you for using VisionCamera ❤️"

enableLocation = true
if defined?($VCEnableLocation)
Pod::UI.puts "[VisionCamera] $VCEnableLocation is set to #{$VCEnableLocation}!"
enableLocation = $VCEnableLocation
else
Pod::UI.puts "[VisionCamera] Building with CLLocation APIs as $VCEnableLocation is not set.."
Pod::UI.puts "[VisionCamera] $VCEnableLocation is not set, enabling CLLocation APIs by default..."
end

enableFrameProcessors = true
if defined?($VCEnableFrameProcessors)
Pod::UI.puts "[VisionCamera] $VCEnableFrameProcessors is set to #{$VCEnableFrameProcessors}!"
enableFrameProcessors = $VCEnableFrameProcessors
else
Pod::UI.puts "[VisionCamera] $VCEnableFrameProcessors is not set, enabling Frame Processors if Worklets is installed..."
end

Pod::UI.puts("[VisionCamera] node modules #{Dir.exist?(nodeModules) ? "found at #{nodeModules}" : "not found!"}")
workletsPath = File.join(nodeModules, "react-native-worklets-core")
hasWorklets = File.exist?(workletsPath) && enableFrameProcessors
Pod::UI.puts("[VisionCamera] react-native-worklets-core #{hasWorklets ? "found" : "not found"}, Frame Processors #{hasWorklets ? "enabled" : "disabled"}!")
hasWorklets = File.exist?(workletsPath)
if hasWorklets
Pod::UI.puts("[VisionCamera] react-native-worklets-core found, Frame Processors #{enableFrameProcessors ? "enabled" : "disabled"}!")
else
Pod::UI.puts("[VisionCamera] react-native-worklets-core not found - Frame Processors are #{hasWorklets ? "enabled" : "disabled"}!")
enableFrameProcessors = false
end

Pod::Spec.new do |s|
s.name = "VisionCamera"
Expand All @@ -36,49 +45,63 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/mrousavy/react-native-vision-camera.git", :tag => "#{s.version}" }

s.pod_target_xcconfig = {
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) VISION_CAMERA_ENABLE_FRAME_PROCESSORS=#{hasWorklets}",
"SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "$(inherited) #{hasWorklets ? "VISION_CAMERA_ENABLE_FRAME_PROCESSORS" : ""} #{enableLocation ? "VISION_CAMERA_ENABLE_LOCATION" : ""}",
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/cpp/\"/** "
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) VISION_CAMERA_ENABLE_FRAME_PROCESSORS=#{enableFrameProcessors}",
"SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "$(inherited) #{enableFrameProcessors ? "VISION_CAMERA_ENABLE_FRAME_PROCESSORS" : ""}",
}

s.requires_arc = true

# All source files that should be publicly visible
# Note how this does not include headers, since those can nameclash.
s.source_files = [
# Core
"ios/*.{m,mm,swift}",
"ios/Core/*.{m,mm,swift}",
"ios/Extensions/*.{m,mm,swift}",
"ios/Parsers/*.{m,mm,swift}",
"ios/React Utils/*.{m,mm,swift}",
"ios/Types/*.{m,mm,swift}",
"ios/CameraBridge.h",

# Frame Processors
hasWorklets ? "ios/Frame Processor/*.{m,mm,swift}" : "",
hasWorklets ? "ios/Frame Processor/Frame.h" : "",
hasWorklets ? "ios/Frame Processor/FrameProcessor.h" : "",
hasWorklets ? "ios/Frame Processor/FrameProcessorPlugin.h" : "",
hasWorklets ? "ios/Frame Processor/FrameProcessorPluginRegistry.h" : "",
hasWorklets ? "ios/Frame Processor/SharedArray.h" : "",
hasWorklets ? "ios/Frame Processor/VisionCameraProxy.h" : "",
hasWorklets ? "cpp/**/*.{cpp}" : "",
]
# Any private headers that are not globally unique should be mentioned here.
# Otherwise there will be a nameclash, since CocoaPods flattens out any header directories
# See https://github.com/firebase/firebase-ios-sdk/issues/4035 for more details.
s.preserve_paths = [
"cpp/**/*.h",
"ios/**/*.h"
]

s.dependency "React"
s.dependency "React-Core"
s.dependency "React-callinvoker"

if hasWorklets
s.dependency "react-native-worklets-core"
s.subspec 'Core' do |core|
# VisionCamera Core Swift codebase
core.source_files = [
"ios/*.{m,mm,swift}",
"ios/Core/*.{m,mm,swift}",
"ios/Extensions/*.{m,mm,swift}",
"ios/Parsers/*.{m,mm,swift}",
"ios/React Utils/*.{m,mm,swift}",
"ios/Types/*.{m,mm,swift}",
"ios/CameraBridge.h",
]

core.pod_target_xcconfig = {
"SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "$(inherited) #{enableLocation ? "VISION_CAMERA_ENABLE_LOCATION" : ""}",
}

if enableFrameProcessors
core.dependency "VisionCamera/FrameProcessors"
end
end

if enableFrameProcessors
s.subspec 'FrameProcessors' do |fp|
# VisionCamera Frame Processors C++ codebase (optional)
fp.dependency "React"
fp.dependency "React-callinvoker"
fp.dependency "react-native-worklets-core"

fp.source_files = [
# C++ sources
"ios/Frame Processor/*.{h,m,mm,cpp}",
"cpp/**/*.{h,cpp}",
]
fp.public_header_files = [
# Swift/Objective-C visible headers
"ios/Frame Processor/Frame.h",
"ios/Frame Processor/FrameProcessor.h",
"ios/Frame Processor/FrameProcessorPlugin.h",
"ios/Frame Processor/FrameProcessorPluginRegistry.h",
"ios/Frame Processor/SharedArray.h",
"ios/Frame Processor/VisionCameraProxyDelegate.h",
"ios/Frame Processor/VisionCameraProxyHolder.h",
"ios/Frame Processor/VisionCameraInstaller.h",
]

fp.pod_target_xcconfig = {
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
"HEADER_SEARCH_PATHS" => "$(inherited) \"$(PODS_TARGET_SRCROOT)/cpp/\"/** "
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#if __has_include(<VisionCamera/FrameProcessorPlugin.h>)
#import <Foundation/Foundation.h>
#import <VisionCamera/FrameProcessorPlugin.h>
#import <VisionCamera/FrameProcessorPluginRegistry.h>
#import <VisionCamera/Frame.h>
#import <VisionCamera/SharedArray.h>

Expand Down
15 changes: 11 additions & 4 deletions package/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,14 @@ PODS:
- RCT-Folly (= 2021.07.22.00)
- React-Core
- SocketRocket (0.6.1)
- VisionCamera (4.0.0-beta.15):
- VisionCamera (4.0.0-beta.16):
- React-Core
- VisionCamera/Core (= 4.0.0-beta.16)
- VisionCamera/FrameProcessors (= 4.0.0-beta.16)
- VisionCamera/Core (4.0.0-beta.16):
- React-Core
- VisionCamera/FrameProcessors
- VisionCamera/FrameProcessors (4.0.0-beta.16):
- React
- React-callinvoker
- React-Core
Expand Down Expand Up @@ -701,9 +708,9 @@ SPEC CHECKSUMS:
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
RNVectorIcons: 23b6e11af4aaf104d169b1b0afa7e5cf96c676ce
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
VisionCamera: e31119ce6f25cf982100e62db2846bee6653f52b
VisionCamera: 129f7e33050d9f45660e4510565ebbd1a0c15126
Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5

PODFILE CHECKSUM: 299b350392623e1b01615935e236438d90fd2cff
PODFILE CHECKSUM: 29d07573cd9f2aa1ecf53c481819da07fd66822e

COCOAPODS: 1.11.3
COCOAPODS: 1.14.3
7 changes: 5 additions & 2 deletions package/ios/CameraBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,16 @@

#import <React/RCTEventEmitter.h>
#import <React/RCTFPSGraph.h>
#import <React/RCTLog.h>
#import <React/RCTUIManager.h>
#import <React/RCTViewManager.h>

#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS
#import "Frame.h"
#import "FrameProcessor.h"
#import "FrameProcessorPlugin.h"
#import "FrameProcessorPluginRegistry.h"
#import "SharedArray.h"
#import "VisionCameraProxy.h"
#import "VisionCameraInstaller.h"
#import "VisionCameraProxyDelegate.h"
#import "VisionCameraProxyHolder.h"
#endif
36 changes: 36 additions & 0 deletions package/ios/CameraViewManager+VisionCameraProxyDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// CameraViewManager+VisionCameraProxyDelegate.swift
// VisionCamera
//
// Created by Marc Rousavy on 20.04.24.
//

import Foundation

#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS

extension CameraViewManager: VisionCameraProxyDelegate {
func getDispatchQueue() -> DispatchQueue {
return CameraQueues.videoQueue
}

func getBridge() -> RCTBridge {
return bridge
}

func setFrameProcessor(_ frameProcessor: FrameProcessor, forView viewTag: NSNumber) {
DispatchQueue.main.async {
let view = self.getCameraView(withTag: viewTag)
view.frameProcessor = frameProcessor
}
}

func removeFrameProcessor(forView viewTag: NSNumber) {
DispatchQueue.main.async {
let view = self.getCameraView(withTag: viewTag)
view.frameProcessor = nil
}
}
}

#endif
4 changes: 2 additions & 2 deletions package/ios/CameraViewManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class CameraViewManager: RCTViewManager {
final func installFrameProcessorBindings() -> NSNumber {
#if VISION_CAMERA_ENABLE_FRAME_PROCESSORS
// Called on JS Thread (blocking sync method)
let result = VisionCameraInstaller.install(to: bridge)
let result = VisionCameraInstaller.install(with: self)
return NSNumber(value: result)
#else
return false as NSNumber
Expand Down Expand Up @@ -148,7 +148,7 @@ final class CameraViewManager: RCTViewManager {

// MARK: Private

private func getCameraView(withTag tag: NSNumber) -> CameraView {
func getCameraView(withTag tag: NSNumber) -> CameraView {
// swiftlint:disable force_cast
return bridge.uiManager.view(forReactTag: tag) as! CameraView
// swiftlint:enable force_cast
Expand Down
14 changes: 9 additions & 5 deletions package/ios/Core/LocationProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ class LocationProvider {
}

private var authorizationStatus: CLAuthorizationStatus {
if #available(iOS 14.0, *) {
return locationManager.authorizationStatus
} else {
return CLLocationManager.authorizationStatus()
}
#if VISION_CAMERA_ENABLE_LOCATION
if #available(iOS 14.0, *) {
return locationManager.authorizationStatus
} else {
return CLLocationManager.authorizationStatus()
}
#else
return .restricted
#endif
}

var hasPermission: Bool {
Expand Down
3 changes: 2 additions & 1 deletion package/ios/Frame Processor/FrameProcessorPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#pragma once

#import "Frame.h"
#import "VisionCameraProxy.h"
#import "FrameProcessorPluginRegistry.h"
#import "VisionCameraProxyHolder.h"
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
Expand Down
5 changes: 4 additions & 1 deletion package/ios/Frame Processor/FrameProcessorPluginRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@

#import "Frame.h"
#import "FrameProcessorPlugin.h"
#import "VisionCameraProxy.h"
#import "VisionCameraProxyHolder.h"
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

// forward-declare the Plugin - caller should always include anyways.
@class FrameProcessorPlugin;

@interface FrameProcessorPluginRegistry : NSObject

typedef FrameProcessorPlugin* _Nonnull (^PluginInitializerFunction)(VisionCameraProxyHolder* proxy, NSDictionary* _Nullable options);
Expand Down
6 changes: 3 additions & 3 deletions package/ios/Frame Processor/JSINSObjectConversion.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
//

#import "JSINSObjectConversion.h"
#import "../Frame Processor/Frame.h"
#import "../Frame Processor/FrameHostObject.h"
#import "../Frame Processor/SharedArray.h"
#import "Frame.h"
#import "FrameHostObject.h"
#import "SharedArray.h"
#import <Foundation/Foundation.h>
#import <React/RCTBridge.h>
#import <ReactCommon/CallInvoker.h>
Expand Down
2 changes: 1 addition & 1 deletion package/ios/Frame Processor/SharedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#pragma once

#import "VisionCameraProxy.h"
#import "VisionCameraProxyHolder.h"
#import <Foundation/Foundation.h>

#ifdef __cplusplus
Expand Down
23 changes: 23 additions & 0 deletions package/ios/Frame Processor/VisionCameraInstaller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// VisionCameraInstaller.h
// Pods
//
// Created by Marc Rousavy on 20.04.24.
//

#pragma once

#import "VisionCameraProxyDelegate.h"

NS_ASSUME_NONNULL_BEGIN

/**
A static class to install/inject the VisionCameraProxy into the global JS runtime.
*/
@interface VisionCameraInstaller : NSObject

+ (BOOL)installWithDelegate:(id<VisionCameraProxyDelegate>)delegate;

@end

NS_ASSUME_NONNULL_END
35 changes: 35 additions & 0 deletions package/ios/Frame Processor/VisionCameraInstaller.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// VisionCameraInstaller.mm
// DoubleConversion
//
// Created by Marc Rousavy on 20.04.24.
//

#import "VisionCameraInstaller.h"
#import "VisionCameraProxy.h"
#import <Foundation/Foundation.h>

#import <React/RCTBridge+Private.h>
#import <React/RCTBridge.h>
#import <ReactCommon/RCTTurboModuleManager.h>

@implementation VisionCameraInstaller

+ (BOOL)installWithDelegate:(id<VisionCameraProxyDelegate>)delegate {
// TODO: Migrate away from RCTBridge to support new arch.
RCTBridge* bridge = delegate.getBridge;
RCTCxxBridge* cxxBridge = (RCTCxxBridge*)bridge;
if (!cxxBridge.runtime) {
return NO;
}

jsi::Runtime& runtime = *(jsi::Runtime*)cxxBridge.runtime;

// global.VisionCameraProxy
auto visionCameraProxy = std::make_shared<VisionCameraProxy>(runtime, bridge.jsCallInvoker, delegate);
runtime.global().setProperty(runtime, "VisionCameraProxy", jsi::Object::createFromHostObject(runtime, visionCameraProxy));

return YES;
}

@end
Loading

0 comments on commit f7dbb24

Please sign in to comment.