Files
Eric FELIXINE e30ae8ed09 feat(smart-app): implement complete mobile app MVP
- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
2026-06-01 18:00:35 -04:00

733 lines
33 KiB
Ruby

# 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.
require_relative "./helpers.rb"
# Utilities class for React Native Cocoapods
class ReactNativePodsUtils
def self.warn_if_not_on_arm64
if SysctlChecker.new().call_sysctl_arm64() == 1 && !Environment.new().ruby_platform().include?('arm64')
Pod::UI.warn 'Do not use "pod install" from inside Rosetta2 (x86_64 emulation on arm64).'
Pod::UI.warn ' - Emulated x86_64 is slower than native arm64'
Pod::UI.warn ' - May result in mixed architectures in rubygems (eg: ffi_c.bundle files may be x86_64 with an arm64 interpreter)'
Pod::UI.warn 'Run "env /usr/bin/arch -arm64 /bin/bash --login" then try again.'
end
end
# deprecated. These checks are duplicated in the react_native_pods function
# and we don't really need them. Removing this function will make it easy to
# move forward.
def self.get_default_flags
flags = {
:fabric_enabled => false,
:hermes_enabled => true,
}
if ENV['RCT_NEW_ARCH_ENABLED'] == '1'
flags[:fabric_enabled] = true
flags[:hermes_enabled] = true
end
if ENV['USE_HERMES'] == '0'
flags[:hermes_enabled] = false
end
return flags
end
def self.has_pod(installer, name)
installer.pods_project.pod_group(name) != nil
end
def self.set_gcc_preprocessor_definition_for_React_hermes(installer)
self.add_build_settings_to_pod(installer, "GCC_PREPROCESSOR_DEFINITIONS", "HERMES_ENABLE_DEBUGGER=1", "React-hermes", "Debug")
self.add_build_settings_to_pod(installer, "GCC_PREPROCESSOR_DEFINITIONS", "HERMES_ENABLE_DEBUGGER=1", "hermes-engine", "Debug")
end
def self.turn_off_resource_bundle_react_core(installer)
# this is needed for Xcode 14, see more details here https://github.com/facebook/react-native/issues/34673
# we should be able to remove this once CocoaPods catches up to it, see more details here https://github.com/CocoaPods/CocoaPods/issues/11402
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
if pod_name.to_s == 'React-Core'
target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
resource_bundle_target.build_configurations.each do |config|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
end
end
end
def self.set_use_hermes_build_setting(installer, hermes_enabled)
Pod::UI.puts("Setting USE_HERMES build settings")
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
config.build_settings["USE_HERMES"] = hermes_enabled
end
project.save()
end
end
def self.set_node_modules_user_settings(installer, react_native_path)
Pod::UI.puts("Setting REACT_NATIVE build settings")
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
config.build_settings["REACT_NATIVE_PATH"] = File.join("${PODS_ROOT}", "..", react_native_path)
end
project.save()
end
end
def self.set_ccache_compiler_and_linker_build_settings(installer, react_native_path, ccache_enabled)
projects = self.extract_projects(installer)
ccache_path = `command -v ccache`.strip
ccache_available = !ccache_path.empty?
message_prefix = "[Ccache]"
if ccache_available
Pod::UI.puts("#{message_prefix}: Ccache found at #{ccache_path}")
end
# Using scripts wrapping the ccache executable, to allow injection of configurations
ccache_clang_sh = File.join("$(REACT_NATIVE_PATH)", 'scripts', 'xcode', 'ccache-clang.sh')
ccache_clangpp_sh = File.join("$(REACT_NATIVE_PATH)", 'scripts', 'xcode', 'ccache-clang++.sh')
if ccache_available and ccache_enabled
Pod::UI.puts("#{message_prefix}: Setting CC, LD, CXX & LDPLUSPLUS build settings")
projects.each do |project|
project.build_configurations.each do |config|
# Using the un-qualified names means you can swap in different implementations, for example ccache
config.build_settings["CC"] = ccache_clang_sh
config.build_settings["LD"] = ccache_clang_sh
config.build_settings["CXX"] = ccache_clangpp_sh
config.build_settings["LDPLUSPLUS"] = ccache_clangpp_sh
end
project.save()
end
elsif ccache_available and !ccache_enabled
Pod::UI.puts("#{message_prefix}: Pass ':ccache_enabled => true' to 'react_native_post_install' in your Podfile or set environment variable 'USE_CCACHE=1' to increase the speed of subsequent builds")
elsif !ccache_available and ccache_enabled
Pod::UI.warn("#{message_prefix}: Install ccache or ensure your neither passing ':ccache_enabled => true' nor setting environment variable 'USE_CCACHE=1'")
else
Pod::UI.puts("#{message_prefix}: Removing Ccache from CC, LD, CXX & LDPLUSPLUS build settings")
projects.each do |project|
project.build_configurations.each do |config|
# Using the un-qualified names means you can swap in different implementations, for example ccache
config.build_settings["CC"] = config.build_settings["CC"] ? config.build_settings["CC"].gsub(/#{Regexp.escape(ccache_clang_sh)}/, '') : ""
config.build_settings["LD"] = config.build_settings["LD"] ? config.build_settings["LD"].gsub(/#{Regexp.escape(ccache_clang_sh)}/, "") : ""
config.build_settings["CXX"] = config.build_settings["CXX"] ? config.build_settings["CXX"].gsub(/#{Regexp.escape(ccache_clangpp_sh)}/, "") : ""
config.build_settings["LDPLUSPLUS"] = config.build_settings["LDPLUSPLUS"] ? config.build_settings["LDPLUSPLUS"].gsub(/#{Regexp.escape(ccache_clangpp_sh)}/, "") : ""
end
project.save()
end
end
end
def self.fix_library_search_paths(installer)
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
self.fix_library_search_path(config)
end
project.native_targets.each do |target|
target.build_configurations.each do |config|
self.fix_library_search_path(config)
end
end
project.save()
end
end
def self.apply_mac_catalyst_patches(installer)
# Fix bundle signing issues
installer.pods_project.targets.each do |target|
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
target.build_configurations.each do |config|
config.build_settings['CODE_SIGN_IDENTITY[sdk=macosx*]'] = '-'
end
end
end
installer.aggregate_targets.each do |aggregate_target|
aggregate_target.user_project.native_targets.each do |target|
target.build_configurations.each do |config|
# Explicitly set dead code stripping flags
config.build_settings['DEAD_CODE_STRIPPING'] = 'YES'
config.build_settings['PRESERVE_DEAD_CODE_INITS_AND_TERMS'] = 'YES'
# Modify library search paths
config.build_settings['LIBRARY_SEARCH_PATHS'] = ['$(SDKROOT)/usr/lib/swift', '$(SDKROOT)/System/iOSSupport/usr/lib/swift', '$(inherited)']
end
end
aggregate_target.user_project.save()
end
end
def self.apply_xcode_15_patch(installer, xcodebuild_manager: Xcodebuild)
projects = self.extract_projects(installer)
other_ld_flags_key = 'OTHER_LDFLAGS'
xcode15_compatibility_flags = '-Wl -ld_classic '
projects.each do |project|
project.build_configurations.each do |config|
# fix for weak linking
self.safe_init(config, other_ld_flags_key)
if self.is_using_xcode15_0(:xcodebuild_manager => xcodebuild_manager)
self.add_value_to_setting_if_missing(config, other_ld_flags_key, xcode15_compatibility_flags)
else
self.remove_value_from_setting_if_present(config, other_ld_flags_key, xcode15_compatibility_flags)
end
end
project.save()
end
end
private
def self.add_build_settings_to_pod(installer, settings_name, settings_value, target_pod_name, configuration)
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
if pod_name.to_s == target_pod_name
target_installation_result.native_target.build_configurations.each do |config|
if configuration == nil || (configuration != nil && config.name.include?(configuration))
config.build_settings[settings_name] ||= '$(inherited) '
config.build_settings[settings_name] << settings_value
end
end
end
end
end
def self.fix_library_search_path(config)
lib_search_paths = config.build_settings["LIBRARY_SEARCH_PATHS"]
if lib_search_paths == nil
# No search paths defined, return immediately
return
end
if lib_search_paths.include?("$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)") || lib_search_paths.include?("\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"")
# $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME) causes problem with Xcode 12.5 + arm64 (Apple Silicon)
# since the libraries there are only built for x86_64 and i386.
lib_search_paths.delete("$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)")
lib_search_paths.delete("\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"")
end
if !(lib_search_paths.include?("$(SDKROOT)/usr/lib/swift") || lib_search_paths.include?("\"$(SDKROOT)/usr/lib/swift\""))
# however, $(SDKROOT)/usr/lib/swift is required, at least if user is not running CocoaPods 1.11
lib_search_paths.insert(0, "$(SDKROOT)/usr/lib/swift")
end
end
def self.create_xcode_env_if_missing(file_manager: File)
relative_path = Pod::Config.instance.installation_root.relative_path_from(Pathname.pwd)
file_path = file_manager.join(relative_path, '.xcode.env')
if !file_manager.exist?(file_path)
system("echo 'export NODE_BINARY=$(command -v node)' > #{file_path}")
end
if !file_manager.exist?("#{file_path}.local")
node_binary = `command -v node`
system("echo 'export NODE_BINARY=#{node_binary}' > #{file_path}.local")
end
end
# It examines the target_definition property and sets the appropriate value for
# ENV['USE_FRAMEWORKS'] variable.
#
# - parameter target_definition: The current target definition
def self.detect_use_frameworks(target_definition)
if ENV['USE_FRAMEWORKS'] != nil
return
end
framework_build_type = target_definition.build_type.to_s
Pod::UI.puts("Framework build type is #{framework_build_type}")
if framework_build_type === "static framework"
ENV['USE_FRAMEWORKS'] = 'static'
elsif framework_build_type === "dynamic framework"
ENV['USE_FRAMEWORKS'] = 'dynamic'
else
ENV['USE_FRAMEWORKS'] = nil
end
end
def self.create_header_search_path_for_frameworks(base_folder, pod_name, framework_name, additional_paths, include_base_path = true)
platforms = $RN_PLATFORMS != nil ? $RN_PLATFORMS : []
search_paths = []
if platforms.empty?() || platforms.length() == 1
base_path = File.join("${#{base_folder}}", pod_name, "#{framework_name}.framework", "Headers")
self.add_search_path_to_result(search_paths, base_path, additional_paths, include_base_path)
else
platforms.each { |platform|
base_path = File.join("${#{base_folder}}", "#{pod_name}-#{platform}", "#{framework_name}.framework", "Headers")
self.add_search_path_to_result(search_paths, base_path, additional_paths, include_base_path)
}
end
return search_paths
end
# Add a new dependency to an existing spec, configuring also the headers search paths
def self.add_dependency(spec, dependency_name, base_folder_for_frameworks, framework_name, additional_paths: [], version: nil, subspec_dependency: nil)
# Update Search Path
optional_current_search_path = spec.to_hash["pod_target_xcconfig"]["HEADER_SEARCH_PATHS"]
current_search_paths = (optional_current_search_path != nil ? optional_current_search_path : "")
.split(" ")
create_header_search_path_for_frameworks(base_folder_for_frameworks, dependency_name, framework_name, additional_paths)
.each { |path|
wrapped_path = "\"#{path}\""
current_search_paths << wrapped_path
}
current_pod_target_xcconfig = spec.to_hash["pod_target_xcconfig"]
current_pod_target_xcconfig["HEADER_SEARCH_PATHS"] = current_search_paths.join(" ")
spec.pod_target_xcconfig = current_pod_target_xcconfig
actual_dependency = subspec_dependency != nil ? "#{dependency_name}/#{subspec_dependency}" : dependency_name
# Set Dependency
if !version
spec.dependency actual_dependency
else
spec.dependency actual_dependency, version
end
end
def self.update_search_paths(installer)
return if ENV['USE_FRAMEWORKS'] == nil
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
header_search_paths = config.build_settings["HEADER_SEARCH_PATHS"] ||= "$(inherited)"
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", "ReactCommon-Samples", "ReactCommon_Samples", ["platform/ios"]))
.concat(ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/components/view/platform/cxx"], false))
.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-graphics", "React_graphics", ["react/renderer/graphics/platform/ios"]))
.each{ |search_path|
header_search_paths = self.add_search_path_if_not_included(header_search_paths, search_path)
}
config.build_settings["HEADER_SEARCH_PATHS"] = header_search_paths
end
project.save()
end
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
if self.react_native_pods.include?(pod_name) || pod_name.include?("Pod") || pod_name.include?("Tests")
next
end
self.set_rctfolly_search_paths(target_installation_result)
self.set_codegen_search_paths(target_installation_result)
self.set_reactcommon_searchpaths(target_installation_result)
self.set_rctfabric_search_paths(target_installation_result)
self.set_imagemanager_search_path(target_installation_result)
end
end
def self.updateOSDeploymentTarget(installer)
installer.target_installation_results.pod_target_installation_results
.each do |pod_name, target_installation_result|
target_installation_result.native_target.build_configurations.each do |config|
old_iphone_deploy_target = config.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] ?
config.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] :
Helpers::Constants.min_ios_version_supported
config.build_settings["IPHONEOS_DEPLOYMENT_TARGET"] = [Helpers::Constants.min_ios_version_supported.to_f, old_iphone_deploy_target.to_f].max.to_s
end
end
end
def self.set_dynamic_frameworks_flags(installer)
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
# Set "RCT_DYNAMIC_FRAMEWORKS=1" if pod are installed with USE_FRAMEWORKS=dynamic
# This helps with backward compatibility.
if pod_name == 'React-RCTFabric' && ENV['USE_FRAMEWORKS'] == 'dynamic'
Pod::UI.puts "Setting -DRCT_DYNAMIC_FRAMEWORKS=1 to React-RCTFabric".green
rct_dynamic_framework_flag = " -DRCT_DYNAMIC_FRAMEWORKS=1"
target_installation_result.native_target.build_configurations.each do |config|
prev_build_settings = config.build_settings['OTHER_CPLUSPLUSFLAGS'] != nil ? config.build_settings['OTHER_CPLUSPLUSFLAGS'] : "$(inherithed)"
config.build_settings['OTHER_CPLUSPLUSFLAGS'] = prev_build_settings + rct_dynamic_framework_flag
end
end
end
end
# ========= #
# Utilities #
# ========= #
def self.extract_projects(installer)
return installer.aggregate_targets
.map{ |t| t.user_project }
.uniq{ |p| p.path }
.push(installer.pods_project)
end
def self.safe_init(config, setting_name)
old_config = config.build_settings[setting_name]
if old_config == nil
config.build_settings[setting_name] ||= '$(inherited) '
end
end
def self.add_value_to_setting_if_missing(config, setting_name, value)
old_config = config.build_settings[setting_name]
if old_config.is_a?(Array)
old_config = old_config.join(" ")
end
trimmed_value = value.strip()
if !old_config.include?(trimmed_value)
config.build_settings[setting_name] = "#{old_config.strip()} #{trimmed_value}".strip()
end
end
def self.remove_value_from_setting_if_present(config, setting_name, value)
old_config = config.build_settings[setting_name]
if old_config.is_a?(Array)
old_config = old_config.join(" ")
end
trimmed_value = value.strip()
if old_config.include?(trimmed_value)
new_config = old_config.gsub(trimmed_value, "")
config.build_settings[setting_name] = new_config.strip()
end
end
def self.is_using_xcode15_0(xcodebuild_manager: Xcodebuild)
xcodebuild_version = xcodebuild_manager.version
if version = self.parse_xcode_version(xcodebuild_version)
return version["major"] == 15 && version["minor"] == 0
end
return false
end
def self.parse_xcode_version(version_string)
# The output of xcodebuild -version is something like
# Xcode 15.0
# or
# Xcode 14.3.1
# We want to capture the version digits
match = version_string.match(/(\d+)\.(\d+)(?:\.(\d+))?/)
return nil if match.nil?
return {"str" => match[0], "major" => match[1].to_i, "minor" => match[2].to_i};
end
def self.check_minimum_required_xcode(xcodebuild_manager: Xcodebuild)
version = self.parse_xcode_version(xcodebuild_manager.version)
if (version.nil? || !Gem::Version::correct?(version["str"]))
Pod::UI.warn "Unexpected XCode version string '#{xcodebuild_manager.version}'"
return
end
current = version["str"]
min_required = Helpers::Constants.min_xcode_version_supported
if Gem::Version::new(current) < Gem::Version::new(min_required)
Pod::UI.puts "React Native requires XCode >= #{min_required}. Found #{current}.".red
raise "Please upgrade XCode"
end
end
def self.add_compiler_flag_to_project(installer, flag, configuration: nil)
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
self.set_flag_in_config(config, flag, configuration: configuration)
end
project.save()
end
end
def self.remove_compiler_flag_from_project(installer, flag, configuration: nil)
projects = self.extract_projects(installer)
projects.each do |project|
project.build_configurations.each do |config|
self.remove_flag_in_config(config, flag, configuration: configuration)
end
project.save()
end
end
def self.add_compiler_flag_to_pods(installer, flag, configuration: nil)
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
target_installation_result.native_target.build_configurations.each do |config|
self.set_flag_in_config(config, flag, configuration: configuration)
end
end
end
def self.set_flag_in_config(config, flag, configuration: nil)
if configuration == nil || config.name == configuration
self.add_flag_for_key(config, flag, "OTHER_CFLAGS")
self.add_flag_for_key(config, flag, "OTHER_CPLUSPLUSFLAGS")
end
end
def self.remove_flag_in_config(config, flag, configuration: nil)
if configuration == nil || config.name == configuration
self.remove_flag_for_key(config, flag, "OTHER_CFLAGS")
self.remove_flag_for_key(config, flag, "OTHER_CPLUSPLUSFLAGS")
end
end
def self.add_flag_for_key(config, flag, key)
current_setting = config.build_settings[key] ? config.build_settings[key] : "$(inherited)"
if current_setting.kind_of?(Array)
current_setting = current_setting
.map { |s| s.gsub('"', '') }
.map { |s| s.gsub('\"', '') }
.join(" ")
end
if !current_setting.include?(flag)
current_setting = "#{current_setting} #{flag}"
end
config.build_settings[key] = current_setting
end
def self.remove_flag_for_key(config, flag, key)
current_setting = config.build_settings[key] ? config.build_settings[key] : "$(inherited)"
if current_setting.kind_of?(Array)
current_setting = current_setting
.map { |s| s.gsub('"', '') }
.map { |s| s.gsub('\"', '') }
.join(" ")
end
if current_setting.include?(flag)
current_setting.slice! flag
end
config.build_settings[key] = current_setting
end
def self.add_search_path_if_not_included(current_search_paths, new_search_path)
if !current_search_paths.include?(new_search_path)
current_search_paths << " #{new_search_path}"
end
return current_search_paths
end
def self.update_header_paths_if_depends_on(target_installation_result, dependency_name, header_paths)
depends_on_framework = target_installation_result.native_target.dependencies.any? { |d| d.name == dependency_name }
if depends_on_framework
target_installation_result.native_target.build_configurations.each do |config|
header_search_path = config.build_settings["HEADER_SEARCH_PATHS"] != nil ? config.build_settings["HEADER_SEARCH_PATHS"] : "$(inherited)"
header_paths.each { |header| header_search_path = ReactNativePodsUtils.add_search_path_if_not_included(header_search_path, header) }
config.build_settings["HEADER_SEARCH_PATHS"] = header_search_path
end
end
end
def self.set_rctfolly_search_paths(target_installation_result)
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "RCT-Folly", [
"\"$(PODS_ROOT)/RCT-Folly\"",
"\"$(PODS_ROOT)/DoubleConversion\"",
"\"$(PODS_ROOT)/fmt/include\"",
"\"$(PODS_ROOT)/boost\""
])
end
def self.set_codegen_search_paths(target_installation_result)
header_search_paths = ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Codegen", "React_Codegen", [])
.map { |search_path| "\"#{search_path}\"" }
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "React-Codegen", header_search_paths)
end
def self.set_reactcommon_searchpaths(target_installation_result)
header_search_paths = ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "ReactCommon", "ReactCommon", ["react/nativemodule/core"])
.map { |search_path| "\"#{search_path}\"" }
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "ReactCommon", header_search_paths)
end
def self.set_rctfabric_search_paths(target_installation_result)
header_search_paths = 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-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"]))
.map { |search_path| "\"#{search_path}\"" }
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "React-RCTFabric", header_search_paths)
end
def self.set_imagemanager_search_path(target_installation_result)
header_search_paths = ReactNativePodsUtils.create_header_search_path_for_frameworks("PODS_CONFIGURATION_BUILD_DIR", "React-Fabric", "React_Fabric", ["react/renderer/imagemanager/platform/ios"])
.map { |search_path| "\"#{search_path}\"" }
ReactNativePodsUtils.update_header_paths_if_depends_on(target_installation_result, "React-ImageManager", header_search_paths)
end
def self.get_privacy_manifest_paths_from(user_project)
privacy_manifests = user_project
.files
.select { |p|
p.path&.end_with?('PrivacyInfo.xcprivacy')
}
return privacy_manifests
end
def self.add_privacy_manifest_if_needed(installer)
user_project = installer.aggregate_targets
.map{ |t| t.user_project }
.first
privacy_manifest = self.get_privacy_manifest_paths_from(user_project).first
if privacy_manifest.nil?
file_timestamp_reason = {
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryFileTimestamp",
"NSPrivacyAccessedAPITypeReasons" => ["C617.1"],
}
user_defaults_reason = {
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategoryUserDefaults",
"NSPrivacyAccessedAPITypeReasons" => ["CA92.1"],
}
boot_time_reason = {
"NSPrivacyAccessedAPIType" => "NSPrivacyAccessedAPICategorySystemBootTime",
"NSPrivacyAccessedAPITypeReasons" => ["35F9.1"],
}
privacy_manifest = {
"NSPrivacyCollectedDataTypes" => [],
"NSPrivacyTracking" => false,
"NSPrivacyAccessedAPITypes" => [file_timestamp_reason, user_defaults_reason, boot_time_reason]
}
path = File.join(user_project.path.parent, "PrivacyInfo.xcprivacy")
Xcodeproj::Plist.write_to_path(privacy_manifest, path)
Pod::UI.puts "Your app does not have a privacy manifest! A template has been generated containing Required Reasons API usage in the core React Native library. Please add the PrivacyInfo.xcprivacy file to your project and complete data use, tracking and any additional required reasons your app is using according to Apple's guidance: https://developer.apple.com/.../privacy_manifest_files. Then, you will need to manually add this file to your project in Xcode.".red
end
end
def self.react_native_pods
return [
"DoubleConversion",
"FBLazyVector",
"RCT-Folly",
"RCTRequired",
"RCTTypeSafety",
"React",
"React-Codegen",
"React-Core",
"React-CoreModules",
"React-Fabric",
"React-FabricImage",
"React-ImageManager",
"React-RCTActionSheet",
"React-RCTAnimation",
"React-RCTAppDelegate",
"React-RCTBlob",
"React-RCTFabric",
"React-RCTImage",
"React-RCTLinking",
"React-RCTNetwork",
"React-RCTPushNotification",
"React-RCTSettings",
"React-RCTText",
"React-RCTTest",
"React-RCTVibration",
"React-callinvoker",
"React-cxxreact",
"React-graphics",
"React-jsc",
"React-jsi",
"React-jsiexecutor",
"React-jsinspector",
"React-logger",
"React-perflogger",
"React-rncore",
"React-runtimeexecutor",
"ReactCommon",
"Yoga",
"boost",
"fmt",
"glog",
"hermes-engine",
"React-hermes",
]
end
def self.add_search_path_to_result(result, base_path, additional_paths, include_base_path)
if (include_base_path)
result << base_path
end
additional_paths.each { |extra_path|
result << File.join(base_path, extra_path)
}
return result
end
def self.add_ndebug_flag_to_pods_in_release(installer)
ndebug_flag = " -DNDEBUG"
installer.aggregate_targets.each do |aggregate_target|
aggregate_target.xcconfigs.each do |config_name, config_file|
is_release = config_name.downcase.include?("release") || config_name.downcase.include?("production")
unless is_release
next
end
self.add_flag_to_map_with_inheritance(config_file.attributes, 'OTHER_CPLUSPLUSFLAGS', ndebug_flag);
self.add_flag_to_map_with_inheritance(config_file.attributes, 'OTHER_CFLAGS', ndebug_flag);
xcconfig_path = aggregate_target.xcconfig_path(config_name)
config_file.save_as(xcconfig_path)
end
end
installer.target_installation_results.pod_target_installation_results.each do |pod_name, target_installation_result|
target_installation_result.native_target.build_configurations.each do |config|
is_release = config.name.downcase.include?("release") || config.name.downcase.include?("production")
unless is_release
next
end
self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CPLUSPLUSFLAGS', ndebug_flag);
self.add_flag_to_map_with_inheritance(config.build_settings, 'OTHER_CFLAGS', ndebug_flag);
end
end
end
def self.add_flag_to_map_with_inheritance(map, field, flag)
if map[field] == nil
map[field] = "$(inherited)" + flag
else
unless map[field].include?(flag)
map[field] = map[field] + flag
end
unless map[field].include?("$(inherited)")
map[field] = "$(inherited) " + map[field]
end
end
end
end