├── .gitignore ├── ReactNativeKit ├── ReactNativeKit │ ├── Logger.swift │ ├── EventEmitter │ │ ├── RNEventEmitter.m │ │ ├── EventEmitter.swift │ │ └── RNEventEmitter.swift │ └── React.swift ├── ReactNativeKit.xcodeproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── project.pbxproj ├── build.sh └── Podfile ├── .Package.template.swift ├── setup.sh ├── Package.swift ├── README.md └── .github └── workflows └── distribute-pinned.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | react-native 2 | **/.DS_Store 3 | **/xcuserdata 4 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit/Logger.swift: -------------------------------------------------------------------------------- 1 | import OSLog 2 | 3 | let logger = Logger(subsystem: "com.wafflestudio.ios-rn-prebuilt", category: "ReactNativeKit") 4 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit/EventEmitter/RNEventEmitter.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface RCT_EXTERN_MODULE(RNEventEmitter, RCTEventEmitter) 5 | RCT_EXTERN_METHOD(supportedEvents) 6 | RCT_EXTERN_METHOD(sendEventToNative:(NSString *)name payload:(NSDictionary *)payload) 7 | @end 8 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.Package.template.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.7 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "ReactNativeKit", 7 | platforms: [ 8 | .iOS(.v15) 9 | ], 10 | products: [ 11 | .library( 12 | name: "ReactNativeKit", 13 | targets: [<#releaseTargetNames#>] 14 | ), 15 | .library( 16 | name: "ReactNativeDevKit", 17 | targets: [<#debugTargetNames#>] 18 | ) 19 | ], 20 | targets: [ 21 | <#binaryTargets#> 22 | ] 23 | ) 24 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | ruby --version 3 | export NO_FLIPPER=1 4 | root=$(pwd) 5 | rm -rf ./react-native 6 | mkdir -p ./react-native 7 | cd ./react-native 8 | npx react-native init ReactNativeKit --version 0.72.3 9 | cd ./ReactNativeKit 10 | npm install \ 11 | @react-navigation/native@6.1.7 \ 12 | react-native-screens@3.23.0 \ 13 | react-native-safe-area-context@4.7.1 \ 14 | @react-navigation/native-stack@6.9.13 \ 15 | react-native-gesture-handler@2.12.0 \ 16 | react-native-reanimated@3.4.2 \ 17 | @react-navigation/drawer@6.6.3 \ 18 | @react-native-picker/picker@2.5.0 \ 19 | react-native-svg@13.11.0 \ 20 | @react-native-async-storage/async-storage@1.19.8 --save-exact 21 | 22 | cd $root 23 | rm -rf ./react-native/ReactNativeKit/ios/* 24 | cp -r ./ReactNativeKit/* ./react-native/ReactNativeKit/ios/ 25 | 26 | cd ./react-native/ReactNativeKit/ios 27 | pod install 28 | ./build.sh 29 | xed . 30 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.7 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "ReactNativeKit", 7 | platforms: [ 8 | .iOS(.v15) 9 | ], 10 | products: [ 11 | .library( 12 | name: "ReactNativeKit", 13 | targets: ["ReactNativeKit-Release"] 14 | ), 15 | .library( 16 | name: "ReactNativeDevKit", 17 | targets: ["ReactNativeKit-Debug"] 18 | ) 19 | ], 20 | targets: [ 21 | .binaryTarget(name: "ReactNativeKit-Debug", url: "https://github.com/wafflestudio/ios-rn-prebuilt/releases/download/0.23.0/ReactNativeKit-Debug.xcframework.zip", checksum: "a503b02d84e776185e2af827b9283fa2a1bb61e4f3971c25c1d8a9243acbdf07"), 22 | .binaryTarget(name: "ReactNativeKit-Release", url: "https://github.com/wafflestudio/ios-rn-prebuilt/releases/download/0.23.0/ReactNativeKit-Release.xcframework.zip", checksum: "41e5deb537d41e609e0d4c841ac50f807927abccf72d85424434d05a3bf6ccea"), 23 | 24 | ] 25 | ) 26 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit/React.swift: -------------------------------------------------------------------------------- 1 | @_implementationOnly import React 2 | import Foundation 3 | import UIKit 4 | 5 | /// Creates and returns a UIView configured with a React Native application. 6 | /// - Parameters: 7 | /// - bundleURL: The URL to the JavaScript bundle file that should be loaded in the React Native application. 8 | /// - moduleName: The name of the React Native module that should be run. This should correspond to a registered React Native module in your JavaScript bundle. 9 | /// - initialProperties: The initial properties that should be passed to the React Native module. These are made available in the React Native application via this.props. 10 | /// - backgroundColor: The background color for the React Native View. Default is .clear. 11 | /// - Returns: A UIView configured to run the specified React Native application. 12 | @MainActor 13 | public func makeReactView( 14 | bundleURL: URL, 15 | moduleName: String, 16 | initialProperties: [AnyHashable: Any]?, 17 | backgroundColor: UIColor = .clear 18 | ) -> UIView 19 | { 20 | let rootView = RCTRootView(bundleURL: bundleURL, moduleName: moduleName, initialProperties: initialProperties) 21 | rootView.backgroundColor = backgroundColor 22 | return rootView 23 | } 24 | -------------------------------------------------------------------------------- /ReactNativeKit/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define variables 4 | workspace="ReactNativeKit.xcworkspace" 5 | scheme="ReactNativeKit" 6 | outputDir="./output" 7 | podsDir="./Pods" 8 | 9 | # Declare environment variable 10 | ENV_CONFIG=$CONFIGURATION 11 | 12 | # Arrays of configurations and SDKs 13 | declare -a configs 14 | if [ -z "$ENV_CONFIG" ]; then 15 | configs=("Debug" "Release") 16 | else 17 | configs=("$ENV_CONFIG") 18 | fi 19 | declare -a sdks=("iphoneos" "iphonesimulator") 20 | 21 | find "${podsDir}" -name '*.xcframework' -print0 | while read -d $'\0' file 22 | do 23 | if [ "$(ls -A $file)" ]; then 24 | echo "Copying $file to ${outputDir}" 25 | rsync -a "$file" "${outputDir}" 26 | else 27 | echo "$file is empty or does not exist." 28 | fi 29 | done 30 | 31 | # Loop through configurations 32 | for config in "${configs[@]}"; do 33 | # Loop through SDKs 34 | for sdk in "${sdks[@]}"; do 35 | # Define platform based on SDK 36 | platform=$([ "$sdk" == "iphonesimulator" ] && echo "iOS Simulator" || echo "iOS") 37 | 38 | # Run xcodebuild command for current configuration and SDK 39 | xcodebuild \ 40 | -workspace $workspace \ 41 | -scheme $scheme \ 42 | -destination="generic/platform=${platform}" \ 43 | -configuration $config \ 44 | -sdk $sdk \ 45 | -archivePath "${outputDir}/${config}/${sdk}/${scheme}.xcarchive" \ 46 | archive \ 47 | SKIP_INSTALL=NO \ 48 | BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ 49 | EXCLUDED_ARCHS=i386 50 | done 51 | 52 | # Create xcframework 53 | xcodebuild -create-xcframework \ 54 | -framework "${outputDir}/${config}/iphoneos/${scheme}.xcarchive/Products/Library/Frameworks/${scheme}.framework" \ 55 | -framework "${outputDir}/${config}/iphonesimulator/${scheme}.xcarchive/Products/Library/Frameworks/${scheme}.framework" \ 56 | -output "${outputDir}/${scheme}-${config}.xcframework" 57 | done -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit/EventEmitter/EventEmitter.swift: -------------------------------------------------------------------------------- 1 | import Combine 2 | 3 | public actor EventEmitter { 4 | private var isRegistered = false 5 | public init() { 6 | Task { [weak self] in 7 | guard let stream = await self?.emitter.registerEventStream.stream else { return } 8 | for await registerEvent in stream { 9 | guard let self else { return } 10 | if registerEvent == .register { 11 | await setIsRegistered() 12 | } 13 | } 14 | } 15 | } 16 | 17 | private var emitter: RNEventEmitter { 18 | RNEventEmitter.shared 19 | } 20 | 21 | private func setIsRegistered() { 22 | isRegistered = true 23 | emitter.registerEventStream.continuation.finish() 24 | } 25 | 26 | public var jsEventStream: AsyncStream { 27 | emitter.jsEventStream.stream 28 | } 29 | 30 | public func emitEvent(_ event: EventType, payload: [AnyHashable: Any]? = [:]) async { 31 | if emitter.events.isEmpty { 32 | logger.debug("Event emitter does not have any supported events. Registering all events.") 33 | emitter.events = EventType.allEvents 34 | } 35 | if !isRegistered { 36 | logger.debug("Event emitter is not registered yet. Waiting for registration.") 37 | await waitForRegistration() 38 | } 39 | logger.debug("Emitting event: \(event.rawValue) with payload: \(String(describing: payload))") 40 | emitter.sendEvent(withName: event.rawValue, body: payload) 41 | } 42 | 43 | private func waitForRegistration() async { 44 | while !isRegistered { 45 | try? await Task.sleep(nanoseconds: 10_000_000) // 10ms 46 | } 47 | } 48 | } 49 | 50 | public protocol SupportedEvent: RawRepresentable, CaseIterable where RawValue == String {} 51 | extension SupportedEvent { 52 | fileprivate static var allEvents: [RawValue] { 53 | Self.allCases.map { $0.rawValue } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit/EventEmitter/RNEventEmitter.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Combine 3 | @_implementationOnly import React 4 | 5 | @objc(RNEventEmitter) 6 | class RNEventEmitter: RCTEventEmitter { 7 | let jsEventStream = AsyncStream.makeStream(of: JSEvent.self) 8 | let registerEventStream = AsyncStream.makeStream(of: RegisterEvent.self) 9 | 10 | private static var _shared: RNEventEmitter? 11 | static var shared: RNEventEmitter { 12 | if let shared = _shared { 13 | return shared 14 | } 15 | logger.debug("RNEventEmitter.shared is accessed but not initialized yet. Waiting for initialization.") 16 | initializationSemaphore.wait() 17 | return _shared! 18 | 19 | } 20 | private static let initializationSemaphore = DispatchSemaphore(value: 0) 21 | 22 | var events: [String] = [] 23 | override init() { 24 | super.init() 25 | RNEventEmitter._shared = self 26 | RNEventEmitter.initializationSemaphore.signal() 27 | jsEventStream.continuation.onTermination = { _ in 28 | logger.debug("JS event stream terminated") 29 | } 30 | logger.debug("RNEventEmitter initialized") 31 | } 32 | 33 | override func supportedEvents() -> [String] { 34 | logger.debug("\(#function) \(self.events)") 35 | return events 36 | } 37 | 38 | @objc func sendEventToNative(_ name: String, payload: [AnyHashable: Any]? = nil) { 39 | if let registerEvent = RegisterEvent(rawValue: name) { 40 | registerEventStream.continuation.yield(registerEvent) 41 | } 42 | let jsEvent = JSEvent(name: name, payload: payload) 43 | jsEventStream.continuation.yield(jsEvent) 44 | logger.debug("Event sent to native stream: \(name) with payload: \(String(describing: payload))") 45 | } 46 | } 47 | 48 | public struct JSEvent: @unchecked Sendable { 49 | public let name: String 50 | public let payload: [AnyHashable: Any]? 51 | } 52 | 53 | enum RegisterEvent: String, Sendable { 54 | case register 55 | case deregister 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ios-rn-prebuilt 2 | 3 | [![Build and Distribute](https://github.com/wafflestudio/ios-rn-prebuilt/actions/workflows/distribute.yaml/badge.svg)](https://github.com/wafflestudio/ios-rn-prebuilt/actions/workflows/distribute.yaml) 4 | 5 | This repository aims to alleviate some of the hurdles associated with the React Native project setup for existing iOS projects with SwiftPM, by providing a precompiled version of React Native as an xcframework. It encapsulates the React Native framework and its dependencies within an xcframework and publishes a new release whenever an update is available. This significantly simplifies the integration of React Native into existing iOS projects, allowing developers to focus more on the core functionality of their applications. 6 | 7 | > **Note** 8 | > Hermes engine is intentionally disabled at the moment due to its large binary size. This decision was taken in an effort to minimize the time required to download the package. However, we have identified a potential solution to reduce Hermes's size by disabling its bitcode, thanks to [this commit](https://github.com/facebook/react-native/pull/37868/commits/06a4d86218b83d8d2ad36f41351bc3f6887021ce). As such, we plan to reintegrate Hermes into the package once the commit gets included in the release. 9 | 10 | ## Getting Started 11 | 12 | To use the prebuilt frameworks in your iOS project, you should fetch the latest package using Swift Package Manager. You can do this by adding the following to your `Package.swift` file: 13 | 14 | ```swift 15 | let package = Package( 16 | ... 17 | dependencies: [ 18 | .package(url: "https://github.com/wafflestudio/ios-rn-prebuilt.git", .upToNextMajor(from: "0.72.3")) 19 | ], 20 | ... 21 | ) 22 | ``` 23 | 24 | ## Automation 25 | 26 | The ios-rn-prebuilt repository includes a GitHub workflow, defined in `distribute.yaml`, which automates the entire build and release process. This workflow is triggered daily at 12:00 UTC. It performs the following tasks: 27 | 28 | - Check for new versions of React Native 29 | - Set up the necessary environment (Node.js, Ruby, Xcode) 30 | - Generate the xcframework using the `build.sh` script 31 | - Zip the generated xcframework files 32 | - Update the `Package.swift` file with the new URLs and checksums for the xcframeworks 33 | - Commit, tag and push the changes to the repository 34 | - Publish a new release containing the zipped xcframeworks 35 | 36 | Please refer to the `distribute.yaml` file for the detailed steps involved in the workflow. 37 | 38 | ## Build Script 39 | 40 | The `build.sh` script is used to generate the xcframework. It performs the following operations: 41 | 42 | - It copies any existing xcframework files from the `Pods` directory to the `output` directory 43 | - It loops through various build configurations and SDKs to build the RN project for different targets (iOS and iOS Simulator) 44 | - It creates an xcframework from the built archives 45 | 46 | ## Contributions 47 | 48 | We encourage developers to contribute to this repository. Whether it's reporting bugs, proposing improvements, or adding new features, your contributions are always welcome. 49 | 50 | ## License 51 | 52 | This project is licensed under the MIT License. 53 | -------------------------------------------------------------------------------- /ReactNativeKit/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, '15.0' 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | def find_and_replace(dir, findstr, replacestr) 29 | Dir[dir].each do |name| 30 | text = File.read(name) 31 | replace = text.gsub(findstr,replacestr) 32 | if text != replace 33 | puts "Fix: " + name 34 | File.open(name, "w") { |file| file.puts replace } 35 | STDOUT.flush 36 | end 37 | end 38 | Dir[dir + '*/'].each(&method(:find_and_replace)) 39 | end 40 | 41 | target 'ReactNativeKit' do 42 | config = use_native_modules! 43 | 44 | # Flags change depending on the env values. 45 | flags = get_default_flags() 46 | 47 | use_react_native!( 48 | :path => config[:reactNativePath], 49 | # Hermes is now enabled by default. Disable by setting this flag to false. 50 | :hermes_enabled => false, 51 | :fabric_enabled => flags[:fabric_enabled], 52 | # Enables Flipper. 53 | # 54 | # Note that if you have use_frameworks! enabled, Flipper will not work and 55 | # you should disable the next line. 56 | :flipper_configuration => flipper_config, 57 | # An absolute path to your application root. 58 | :app_path => "#{Pod::Config.instance.installation_root}/.." 59 | ) 60 | 61 | post_install do |installer| 62 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 63 | react_native_post_install( 64 | installer, 65 | config[:reactNativePath], 66 | :mac_catalyst_enabled => false 67 | ) 68 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 69 | 70 | # Workaround for iOS non-public selectors issue 71 | # https://github.com/facebook/react-native/issues/31507 72 | find_and_replace("../node_modules/react-native/React/Base/RCTKeyCommands.m", 73 | "_modifierFlags", 74 | "_modifierEventFlags") 75 | find_and_replace("../node_modules/react-native/React/Base/RCTKeyCommands.m", 76 | "_modifiedInput", 77 | "_modifiedEventInput") 78 | find_and_replace("../node_modules/react-native/React/Base/RCTKeyCommands.m", 79 | "_isKeyDown", 80 | "_isKeyEventDown") 81 | find_and_replace("../node_modules/react-native/React/DevSupport/RCTPackagerClient.h", 82 | "handleNotification", 83 | "handlePackageNotification") 84 | 85 | find_and_replace("../node_modules/react-native/React/DevSupport/RCTPackagerConnection.mm", 86 | "handleNotification", 87 | "handlePackageNotification") 88 | 89 | PLIST_BUDDY_PATH = '/usr/libexec/PlistBuddy' 90 | 91 | targets_to_skip_verification = [ 92 | 'Yoga', 93 | 'YogaKit' 94 | ] 95 | 96 | installer.pods_project.targets.each do |target| 97 | target.build_configurations.each do |config| 98 | if target.name == "hermes-engine" 99 | installer.pods_project.files.each do |fileref| 100 | if fileref.path.end_with? "hermes.xcframework" 101 | hermes_plist_file = "#{fileref.real_path}/Info.plist" 102 | # Patch Hermes to remove the debug symbols entry from the Info.plist (as it's not shipped with it) 103 | # This might be removed once Hermes starts to ship with Debug symbols or we remove our 104 | # direct dependency from the Main iOS target on "hermes.xcframework" 105 | puts "Removing DebugSymbolsPath from info.plist for #{target.name}" 106 | Open3.capture3(PLIST_BUDDY_PATH, '-c', 'Delete :AvailableLibraries:0:DebugSymbolsPath', hermes_plist_file) 107 | Open3.capture3(PLIST_BUDDY_PATH, '-c', 'Delete :AvailableLibraries:1:DebugSymbolsPath', hermes_plist_file) 108 | Open3.capture3(PLIST_BUDDY_PATH, '-c', 'Delete :AvailableLibraries:2:DebugSymbolsPath', hermes_plist_file) 109 | end 110 | end 111 | end 112 | 113 | if targets_to_skip_verification.include?(target.name) 114 | target.build_configurations.each do |config| 115 | puts "Updating OTHER_SWIFT_FLAGS for target #{target.name} to include -no-verify-emitted-module-interface" 116 | 117 | # It's very important that the "$(inherited)" part is added, otherwise this will 118 | # overwrite all other flags and cause a whole separate set of issues 119 | config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -no-verify-emitted-module-interface' 120 | end 121 | end 122 | end 123 | end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /.github/workflows/distribute-pinned.yaml: -------------------------------------------------------------------------------- 1 | name: Build and Distribute (Pinned) 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | env: 9 | GITHUB_BOT_USERNAME: "github-actions" 10 | GITHUB_BOT_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com" 11 | REACT_NATIVE_VERSION: "0.72.3" 12 | NO_FLIPPER: "1" 13 | 14 | jobs: 15 | build: 16 | runs-on: macos-latest 17 | 18 | steps: 19 | - id: my_release 20 | uses: pozetroninc/github-action-get-latest-release@master 21 | with: 22 | repository: ${{ github.repository }} 23 | excludes: prerelease, draft 24 | token: ${{ secrets.GITHUB_TOKEN }} 25 | 26 | - uses: madhead/semver-utils@latest 27 | id: version 28 | with: 29 | version: ${{ steps.my_release.outputs.release }} 30 | 31 | - id: check_versions 32 | name: Terminate if version is not greater 33 | run: | 34 | echo "React Native version: ${{ env.REACT_NATIVE_VERSION }}" 35 | echo "Current version: ${{ steps.my_release.outputs.release }}" 36 | if [[ "${{ steps.compare_versions.outputs.comparison-result }}" == ">" ]]; then 37 | echo "::set-output name=bump::minor" 38 | elif [[ "${{ steps.compare_versions.outputs.comparison-result }}" == "==" ]]; then 39 | echo "::set-output name=bump::patch" 40 | else 41 | echo "::set-output name=bump::minor" 42 | fi 43 | 44 | - name: Determine target version 45 | id: target_version 46 | run: | 47 | if [[ "${{ steps.check_versions.outputs.bump }}" == "minor" ]]; then 48 | echo "::set-output name=target_version::${{ steps.version.outputs.inc-minor }}" 49 | elif [[ "${{ steps.check_versions.outputs.bump }}" == "patch" ]]; then 50 | echo "::set-output name=target_version::${{ steps.version.outputs.inc-patch }}" 51 | fi 52 | 53 | - name: Debug Print 54 | run: | 55 | echo "Bump: ${{ steps.check_versions.outputs.bump }}" 56 | echo "Target version: ${{ steps.target_version.outputs.target_version }}" 57 | echo "My latest Release: ${{ steps.my_release.outputs.release }}" 58 | echo "My latest RN version: ${{ steps.my_release.outputs.description }}" 59 | echo "RN latest version: ${{ env.REACT_NATIVE_VERSION }}" 60 | echo "Comparison result: ${{ steps.compare_versions.outputs.comparison-result }}" 61 | 62 | - name: Check out code 63 | uses: actions/checkout@v3 64 | 65 | - name: Set up Node.js 66 | uses: actions/setup-node@v3 67 | with: 68 | node-version: latest 69 | 70 | - uses: ruby/setup-ruby@v1 71 | with: 72 | ruby-version: "2.7.8" 73 | 74 | - name: Install react-native 75 | run: | 76 | mkdir -p ./react-native 77 | cd ./react-native 78 | npx react-native init ReactNativeKit --version ${{ env.REACT_NATIVE_VERSION }} 79 | cd ReactNativeKit 80 | npm install \ 81 | @react-navigation/native@6.1.7 \ 82 | react-native-screens@3.23.0 \ 83 | react-native-safe-area-context@4.7.1 \ 84 | @react-navigation/native-stack@6.9.13 \ 85 | react-native-gesture-handler@2.12.0 \ 86 | react-native-reanimated@3.4.2 \ 87 | @react-navigation/drawer@6.6.3 \ 88 | @react-native-picker/picker@2.5.0 \ 89 | react-native-svg@13.11.0 \ 90 | @react-native-async-storage/async-storage@1.19.8 --save-exact 91 | 92 | - name: Copy template projects 93 | run: | 94 | # Print current podfile for debugging 95 | cat ./react-native/ReactNativeKit/ios/Podfile 96 | # Clean up boilerplate xcode project 97 | rm -rf ./react-native/ReactNativeKit/ios/* 98 | # Copy my template project 99 | cp -r ./ReactNativeKit/* ./react-native/ReactNativeKit/ios/ 100 | 101 | - name: Install cocoapods dependencies 102 | working-directory: ./react-native/ReactNativeKit/ios 103 | run: | 104 | cat Podfile 105 | pod install 106 | 107 | - uses: maxim-lobanov/setup-xcode@v1 108 | with: 109 | xcode-version: latest-stable 110 | 111 | - name: Generate xcframework 112 | working-directory: ./react-native/ReactNativeKit/ios 113 | run: | 114 | ./build.sh 115 | 116 | - name: Create a zip archives for each xcframework 117 | working-directory: ./react-native/ReactNativeKit/ios/output 118 | run: | 119 | for dir in *.xcframework 120 | do 121 | zip -r -q -X "${dir}.zip" "$dir" 122 | done 123 | 124 | - name: Install utilities 125 | run: | 126 | # install string replace utility 127 | brew install sd 128 | 129 | - name: Prepare Package.swift 130 | working-directory: ./react-native/ReactNativeKit/ios/output 131 | run: | 132 | # Initialize targetNames and binaryTargets as empty arrays 133 | binaryTargets=() 134 | releaseTargetNames=() 135 | debugTargetNames=() 136 | 137 | for dir in *.xcframework 138 | do 139 | xcframework_name=$(basename $dir .xcframework) 140 | 141 | echo "Processing $dir ..." 142 | 143 | # Estimate release download url 144 | url=https://github.com/${{ github.repository }}/releases/download/${{ steps.target_version.outputs.target_version }}/${dir}.zip 145 | echo "url=$url" 146 | 147 | # Compute checksum 148 | checksum=$(swift package compute-checksum ${dir}.zip) 149 | echo "checksum=$checksum" 150 | 151 | binary_target=".binaryTarget(name: \"$xcframework_name\", url: \"$url\", checksum: \"$checksum\")," 152 | binaryTargets+=("$binary_target") 153 | 154 | # Add xcframework to appropriate targetName array 155 | if [[ "$xcframework_name" == *"Debug"* ]]; then 156 | debugTargetNames+=("\"$xcframework_name\"") 157 | elif [[ "$xcframework_name" == *"Release"* ]]; then 158 | releaseTargetNames+=("\"$xcframework_name\"") 159 | echo "releaseTargetNames=$releaseTargetNames" 160 | else 161 | releaseTargetNames+=("\"$xcframework_name\"") 162 | debugTargetNames+=("\"$xcframework_name\"") 163 | fi 164 | done 165 | 166 | # Convert arrays to string 167 | releaseTargetNamesString=$(IFS=,; echo "${releaseTargetNames[*]}") 168 | debugTargetNamesString=$(IFS=,; echo "${debugTargetNames[*]}") 169 | binaryTargetsString=$(printf "%s\n " "${binaryTargets[@]}") 170 | 171 | # Generate Package.swift with URL and checksum 172 | # The placeholders are replaced directly with the values 173 | sd '<#releaseTargetNames#>' "$releaseTargetNamesString" < "$GITHUB_WORKSPACE/.Package.template.swift" | sd '<#debugTargetNames#>' "$debugTargetNamesString" | sd '<#binaryTargets#>' "$binaryTargetsString" > "$GITHUB_WORKSPACE/Package.swift" 174 | 175 | cat "$GITHUB_WORKSPACE/Package.swift" 176 | 177 | - name: Setup Git configurations 178 | run: | 179 | git config user.name "${{ env.GITHUB_BOT_USERNAME }}" 180 | git config user.email "${{ env.GITHUB_BOT_EMAIL }}" 181 | 182 | - name: Add, commit and push to ${{ github.repository }} 183 | run: | 184 | git add -A 185 | git commit -m "Bump to ${{ steps.target_version.outputs.target_version }}" 186 | git tag ${{ steps.target_version.outputs.target_version }} 187 | git pull --rebase 188 | git push origin HEAD 189 | git push --tags origin HEAD 190 | echo "${{ github.ref }}" 191 | echo $(git rev-parse HEAD) 192 | 193 | - name: Release 194 | uses: softprops/action-gh-release@v1 195 | with: 196 | files: | 197 | ./react-native/ReactNativeKit/ios/output/*.xcframework.zip 198 | ./react-native/ReactNativeKit/package.json 199 | ./react-native/ReactNativeKit/package-lock.json 200 | tag_name: ${{ steps.target_version.outputs.target_version }} 201 | body: | 202 | ${{ env.REACT_NATIVE_VERSION }} 203 | -------------------------------------------------------------------------------- /ReactNativeKit/ReactNativeKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | CE1D00B82A5DB4C300C94550 /* React.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE1D00B72A5DB4C300C94550 /* React.swift */; }; 11 | CEAA84032BEBBACF004908B8 /* RNEventEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA84022BEBBACF004908B8 /* RNEventEmitter.swift */; }; 12 | CEAA84052BEBBB4E004908B8 /* RNEventEmitter.m in Sources */ = {isa = PBXBuildFile; fileRef = CEAA84042BEBBB4E004908B8 /* RNEventEmitter.m */; }; 13 | CEAA84072BEBC11C004908B8 /* EventEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEAA84062BEBC11C004908B8 /* EventEmitter.swift */; }; 14 | CEF992E12BF2604800F0FFA4 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF992E02BF2604800F0FFA4 /* Logger.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | CE1D00AD2A5DB49400C94550 /* ReactNativeKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactNativeKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | CE1D00B72A5DB4C300C94550 /* React.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = React.swift; sourceTree = ""; }; 20 | CEAA84022BEBBACF004908B8 /* RNEventEmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNEventEmitter.swift; sourceTree = ""; }; 21 | CEAA84042BEBBB4E004908B8 /* RNEventEmitter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNEventEmitter.m; sourceTree = ""; }; 22 | CEAA84062BEBC11C004908B8 /* EventEmitter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventEmitter.swift; sourceTree = ""; }; 23 | CEF992E02BF2604800F0FFA4 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; 24 | /* End PBXFileReference section */ 25 | 26 | /* Begin PBXFrameworksBuildPhase section */ 27 | CE1D00AA2A5DB49400C94550 /* Frameworks */ = { 28 | isa = PBXFrameworksBuildPhase; 29 | buildActionMask = 2147483647; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXFrameworksBuildPhase section */ 35 | 36 | /* Begin PBXGroup section */ 37 | CE1D00A32A5DB49400C94550 = { 38 | isa = PBXGroup; 39 | children = ( 40 | CE1D00AF2A5DB49400C94550 /* ReactNativeKit */, 41 | CE1D00AE2A5DB49400C94550 /* Products */, 42 | ); 43 | sourceTree = ""; 44 | }; 45 | CE1D00AE2A5DB49400C94550 /* Products */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | CE1D00AD2A5DB49400C94550 /* ReactNativeKit.framework */, 49 | ); 50 | name = Products; 51 | sourceTree = ""; 52 | }; 53 | CE1D00AF2A5DB49400C94550 /* ReactNativeKit */ = { 54 | isa = PBXGroup; 55 | children = ( 56 | CE1D00B72A5DB4C300C94550 /* React.swift */, 57 | CEAA84002BEBBABB004908B8 /* EventEmitter */, 58 | CEF992E02BF2604800F0FFA4 /* Logger.swift */, 59 | ); 60 | path = ReactNativeKit; 61 | sourceTree = ""; 62 | }; 63 | CEAA84002BEBBABB004908B8 /* EventEmitter */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | CEAA84062BEBC11C004908B8 /* EventEmitter.swift */, 67 | CEAA84022BEBBACF004908B8 /* RNEventEmitter.swift */, 68 | CEAA84042BEBBB4E004908B8 /* RNEventEmitter.m */, 69 | ); 70 | path = EventEmitter; 71 | sourceTree = ""; 72 | }; 73 | /* End PBXGroup section */ 74 | 75 | /* Begin PBXHeadersBuildPhase section */ 76 | CE1D00A82A5DB49400C94550 /* Headers */ = { 77 | isa = PBXHeadersBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | /* End PBXHeadersBuildPhase section */ 84 | 85 | /* Begin PBXNativeTarget section */ 86 | CE1D00AC2A5DB49400C94550 /* ReactNativeKit */ = { 87 | isa = PBXNativeTarget; 88 | buildConfigurationList = CE1D00B42A5DB49400C94550 /* Build configuration list for PBXNativeTarget "ReactNativeKit" */; 89 | buildPhases = ( 90 | CE1D00A82A5DB49400C94550 /* Headers */, 91 | CE1D00A92A5DB49400C94550 /* Sources */, 92 | CE1D00AA2A5DB49400C94550 /* Frameworks */, 93 | CE1D00AB2A5DB49400C94550 /* Resources */, 94 | ); 95 | buildRules = ( 96 | ); 97 | dependencies = ( 98 | ); 99 | name = ReactNativeKit; 100 | productName = ReactNativeKit; 101 | productReference = CE1D00AD2A5DB49400C94550 /* ReactNativeKit.framework */; 102 | productType = "com.apple.product-type.framework"; 103 | }; 104 | /* End PBXNativeTarget section */ 105 | 106 | /* Begin PBXProject section */ 107 | CE1D00A42A5DB49400C94550 /* Project object */ = { 108 | isa = PBXProject; 109 | attributes = { 110 | BuildIndependentTargetsInParallel = 1; 111 | LastUpgradeCheck = 1430; 112 | TargetAttributes = { 113 | CE1D00AC2A5DB49400C94550 = { 114 | CreatedOnToolsVersion = 14.3.1; 115 | LastSwiftMigration = 1430; 116 | }; 117 | }; 118 | }; 119 | buildConfigurationList = CE1D00A72A5DB49400C94550 /* Build configuration list for PBXProject "ReactNativeKit" */; 120 | compatibilityVersion = "Xcode 14.0"; 121 | developmentRegion = en; 122 | hasScannedForEncodings = 0; 123 | knownRegions = ( 124 | en, 125 | Base, 126 | ); 127 | mainGroup = CE1D00A32A5DB49400C94550; 128 | productRefGroup = CE1D00AE2A5DB49400C94550 /* Products */; 129 | projectDirPath = ""; 130 | projectRoot = ""; 131 | targets = ( 132 | CE1D00AC2A5DB49400C94550 /* ReactNativeKit */, 133 | ); 134 | }; 135 | /* End PBXProject section */ 136 | 137 | /* Begin PBXResourcesBuildPhase section */ 138 | CE1D00AB2A5DB49400C94550 /* Resources */ = { 139 | isa = PBXResourcesBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | /* End PBXResourcesBuildPhase section */ 146 | 147 | /* Begin PBXSourcesBuildPhase section */ 148 | CE1D00A92A5DB49400C94550 /* Sources */ = { 149 | isa = PBXSourcesBuildPhase; 150 | buildActionMask = 2147483647; 151 | files = ( 152 | CEF992E12BF2604800F0FFA4 /* Logger.swift in Sources */, 153 | CE1D00B82A5DB4C300C94550 /* React.swift in Sources */, 154 | CEAA84072BEBC11C004908B8 /* EventEmitter.swift in Sources */, 155 | CEAA84052BEBBB4E004908B8 /* RNEventEmitter.m in Sources */, 156 | CEAA84032BEBBACF004908B8 /* RNEventEmitter.swift in Sources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXSourcesBuildPhase section */ 161 | 162 | /* Begin XCBuildConfiguration section */ 163 | CE1D00B22A5DB49400C94550 /* Debug */ = { 164 | isa = XCBuildConfiguration; 165 | buildSettings = { 166 | ALWAYS_SEARCH_USER_PATHS = NO; 167 | CLANG_ANALYZER_NONNULL = YES; 168 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 169 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 170 | CLANG_ENABLE_MODULES = YES; 171 | CLANG_ENABLE_OBJC_ARC = YES; 172 | CLANG_ENABLE_OBJC_WEAK = YES; 173 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 174 | CLANG_WARN_BOOL_CONVERSION = YES; 175 | CLANG_WARN_COMMA = YES; 176 | CLANG_WARN_CONSTANT_CONVERSION = YES; 177 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 178 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 179 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 180 | CLANG_WARN_EMPTY_BODY = YES; 181 | CLANG_WARN_ENUM_CONVERSION = YES; 182 | CLANG_WARN_INFINITE_RECURSION = YES; 183 | CLANG_WARN_INT_CONVERSION = YES; 184 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 185 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 186 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 187 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 188 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 189 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 190 | CLANG_WARN_STRICT_PROTOTYPES = YES; 191 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 192 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 193 | CLANG_WARN_UNREACHABLE_CODE = YES; 194 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 195 | COPY_PHASE_STRIP = NO; 196 | CURRENT_PROJECT_VERSION = 1; 197 | DEBUG_INFORMATION_FORMAT = dwarf; 198 | ENABLE_STRICT_OBJC_MSGSEND = YES; 199 | ENABLE_TESTABILITY = YES; 200 | GCC_C_LANGUAGE_STANDARD = gnu11; 201 | GCC_DYNAMIC_NO_PIC = NO; 202 | GCC_NO_COMMON_BLOCKS = YES; 203 | GCC_OPTIMIZATION_LEVEL = 0; 204 | GCC_PREPROCESSOR_DEFINITIONS = ( 205 | "DEBUG=1", 206 | "$(inherited)", 207 | ); 208 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 209 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 210 | GCC_WARN_UNDECLARED_SELECTOR = YES; 211 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 212 | GCC_WARN_UNUSED_FUNCTION = YES; 213 | GCC_WARN_UNUSED_VARIABLE = YES; 214 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 215 | MACOSX_DEPLOYMENT_TARGET = 13.3; 216 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 217 | MTL_FAST_MATH = YES; 218 | ONLY_ACTIVE_ARCH = YES; 219 | SDKROOT = macosx; 220 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 221 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 222 | VERSIONING_SYSTEM = "apple-generic"; 223 | VERSION_INFO_PREFIX = ""; 224 | }; 225 | name = Debug; 226 | }; 227 | CE1D00B32A5DB49400C94550 /* Release */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | ALWAYS_SEARCH_USER_PATHS = NO; 231 | CLANG_ANALYZER_NONNULL = YES; 232 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 233 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 234 | CLANG_ENABLE_MODULES = YES; 235 | CLANG_ENABLE_OBJC_ARC = YES; 236 | CLANG_ENABLE_OBJC_WEAK = YES; 237 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 238 | CLANG_WARN_BOOL_CONVERSION = YES; 239 | CLANG_WARN_COMMA = YES; 240 | CLANG_WARN_CONSTANT_CONVERSION = YES; 241 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 243 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 244 | CLANG_WARN_EMPTY_BODY = YES; 245 | CLANG_WARN_ENUM_CONVERSION = YES; 246 | CLANG_WARN_INFINITE_RECURSION = YES; 247 | CLANG_WARN_INT_CONVERSION = YES; 248 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 249 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 250 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 251 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 252 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 253 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 254 | CLANG_WARN_STRICT_PROTOTYPES = YES; 255 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 256 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 257 | CLANG_WARN_UNREACHABLE_CODE = YES; 258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 259 | COPY_PHASE_STRIP = NO; 260 | CURRENT_PROJECT_VERSION = 1; 261 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 262 | ENABLE_NS_ASSERTIONS = NO; 263 | ENABLE_STRICT_OBJC_MSGSEND = YES; 264 | GCC_C_LANGUAGE_STANDARD = gnu11; 265 | GCC_NO_COMMON_BLOCKS = YES; 266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 268 | GCC_WARN_UNDECLARED_SELECTOR = YES; 269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 270 | GCC_WARN_UNUSED_FUNCTION = YES; 271 | GCC_WARN_UNUSED_VARIABLE = YES; 272 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 273 | MACOSX_DEPLOYMENT_TARGET = 13.3; 274 | MTL_ENABLE_DEBUG_INFO = NO; 275 | MTL_FAST_MATH = YES; 276 | SDKROOT = macosx; 277 | SWIFT_COMPILATION_MODE = wholemodule; 278 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 279 | VERSIONING_SYSTEM = "apple-generic"; 280 | VERSION_INFO_PREFIX = ""; 281 | }; 282 | name = Release; 283 | }; 284 | CE1D00B52A5DB49400C94550 /* Debug */ = { 285 | isa = XCBuildConfiguration; 286 | buildSettings = { 287 | BUILD_LIBRARY_FOR_DISTRIBUTION = NO; 288 | CLANG_ENABLE_MODULES = YES; 289 | CODE_SIGN_STYLE = Automatic; 290 | COMBINE_HIDPI_IMAGES = YES; 291 | CURRENT_PROJECT_VERSION = 1; 292 | DEFINES_MODULE = YES; 293 | DYLIB_COMPATIBILITY_VERSION = 1; 294 | DYLIB_CURRENT_VERSION = 1; 295 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 296 | ENABLE_MODULE_VERIFIER = YES; 297 | GENERATE_INFOPLIST_FILE = YES; 298 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 299 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 300 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 301 | LD_RUNPATH_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "@executable_path/../Frameworks", 304 | "@loader_path/Frameworks", 305 | ); 306 | MARKETING_VERSION = 1.0; 307 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 308 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; 309 | PRODUCT_BUNDLE_IDENTIFIER = com.wafflestudio.ReactNativeKit; 310 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 311 | SKIP_INSTALL = YES; 312 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; 313 | SUPPORTS_MACCATALYST = NO; 314 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; 315 | SWIFT_EMIT_LOC_STRINGS = YES; 316 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 317 | SWIFT_VERSION = 5.0; 318 | TARGETED_DEVICE_FAMILY = 1; 319 | }; 320 | name = Debug; 321 | }; 322 | CE1D00B62A5DB49400C94550 /* Release */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | BUILD_LIBRARY_FOR_DISTRIBUTION = NO; 326 | CLANG_ENABLE_MODULES = YES; 327 | CODE_SIGN_STYLE = Automatic; 328 | COMBINE_HIDPI_IMAGES = YES; 329 | CURRENT_PROJECT_VERSION = 1; 330 | DEFINES_MODULE = YES; 331 | DYLIB_COMPATIBILITY_VERSION = 1; 332 | DYLIB_CURRENT_VERSION = 1; 333 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 334 | ENABLE_MODULE_VERIFIER = YES; 335 | GENERATE_INFOPLIST_FILE = YES; 336 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 337 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 338 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 339 | LD_RUNPATH_SEARCH_PATHS = ( 340 | "$(inherited)", 341 | "@executable_path/../Frameworks", 342 | "@loader_path/Frameworks", 343 | ); 344 | MARKETING_VERSION = 1.0; 345 | MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; 346 | MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20"; 347 | PRODUCT_BUNDLE_IDENTIFIER = com.wafflestudio.ReactNativeKit; 348 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 349 | SKIP_INSTALL = YES; 350 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; 351 | SUPPORTS_MACCATALYST = NO; 352 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; 353 | SWIFT_EMIT_LOC_STRINGS = YES; 354 | SWIFT_VERSION = 5.0; 355 | TARGETED_DEVICE_FAMILY = 1; 356 | }; 357 | name = Release; 358 | }; 359 | /* End XCBuildConfiguration section */ 360 | 361 | /* Begin XCConfigurationList section */ 362 | CE1D00A72A5DB49400C94550 /* Build configuration list for PBXProject "ReactNativeKit" */ = { 363 | isa = XCConfigurationList; 364 | buildConfigurations = ( 365 | CE1D00B22A5DB49400C94550 /* Debug */, 366 | CE1D00B32A5DB49400C94550 /* Release */, 367 | ); 368 | defaultConfigurationIsVisible = 0; 369 | defaultConfigurationName = Release; 370 | }; 371 | CE1D00B42A5DB49400C94550 /* Build configuration list for PBXNativeTarget "ReactNativeKit" */ = { 372 | isa = XCConfigurationList; 373 | buildConfigurations = ( 374 | CE1D00B52A5DB49400C94550 /* Debug */, 375 | CE1D00B62A5DB49400C94550 /* Release */, 376 | ); 377 | defaultConfigurationIsVisible = 0; 378 | defaultConfigurationName = Release; 379 | }; 380 | /* End XCConfigurationList section */ 381 | }; 382 | rootObject = CE1D00A42A5DB49400C94550 /* Project object */; 383 | } 384 | --------------------------------------------------------------------------------