├── .circleci └── config.yml ├── .editorconfig ├── .gitattributes ├── .github ├── actions │ └── setup │ │ └── action.yml └── workflows │ └── ci.yml ├── .gitignore ├── .husky ├── .npmignore ├── commit-msg └── pre-commit ├── .nvmrc ├── .yarn ├── plugins │ └── @yarnpkg │ │ ├── plugin-interactive-tools.cjs │ │ └── plugin-workspace-tools.cjs └── releases │ └── yarn-3.6.1.cjs ├── .yarnrc.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle.properties └── src │ ├── main │ ├── AndroidManifest.xml │ ├── AndroidManifestNew.xml │ └── java │ │ └── com │ │ └── azesmwayreactnativeunity │ │ ├── ReactNativeUnity.java │ │ ├── ReactNativeUnityView.java │ │ ├── ReactNativeUnityViewManager.java │ │ ├── ReactNativeUnityViewPackage.java │ │ └── UPlayer.java │ ├── newarch │ └── com │ │ └── azesmwayreactnativeunity │ │ └── ReactNativeUnityViewManagerSpec.java │ └── oldarch │ └── com │ └── azesmwayreactnativeunity │ └── ReactNativeUnityViewManagerSpec.java ├── app.plugin.js ├── babel.config.js ├── docs ├── step1.jpg ├── step2.jpg ├── step3.jpg └── step4.jpg ├── example ├── .bundle │ └── config ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── .prettierrc.js ├── .watchmanconfig ├── Gemfile ├── Gemfile.lock ├── README.md ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ │ └── values │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── release │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── ReactNativeFlipper.java │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── example.xcscheme │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── main.m │ └── exampleTests │ │ ├── Info.plist │ │ └── exampleTests.m ├── jest.config.js ├── metro.config.js ├── package.json ├── src │ ├── App.tsx │ ├── Main.tsx │ └── Unity.tsx ├── tsconfig.json └── unity │ └── Assets │ ├── ButtonBehavior.cs │ └── Plugins │ └── iOS │ ├── NativeCallProxy.h │ └── NativeCallProxy.mm ├── ios ├── RNUnityView.h ├── RNUnityView.mm └── RNUnityViewManager.mm ├── lefthook.yml ├── package.json ├── plugin ├── src │ └── index.ts └── tsconfig.json ├── react-native-unity.podspec ├── scripts └── pod-install.cjs ├── src ├── UnityView.tsx ├── __tests__ │ └── index.test.tsx ├── index.ts └── specs │ └── UnityViewNativeComponent.ts ├── tsconfig.build.json ├── tsconfig.json ├── turbo.json ├── unity └── Assets │ ├── ButtonBehavior.cs │ └── Plugins │ └── iOS │ ├── NativeCallProxy.h │ └── NativeCallProxy.mm └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | executors: 4 | default: 5 | docker: 6 | - image: circleci/node:10 7 | working_directory: ~/project 8 | 9 | commands: 10 | attach_project: 11 | steps: 12 | - attach_workspace: 13 | at: ~/project 14 | 15 | jobs: 16 | install-dependencies: 17 | executor: default 18 | steps: 19 | - checkout 20 | - attach_project 21 | - restore_cache: 22 | keys: 23 | - dependencies-{{ checksum "package.json" }} 24 | - dependencies- 25 | - restore_cache: 26 | keys: 27 | - dependencies-example-{{ checksum "example/package.json" }} 28 | - dependencies-example- 29 | - run: 30 | name: Install dependencies 31 | command: | 32 | yarn install --cwd example --frozen-lockfile 33 | yarn install --frozen-lockfile 34 | - save_cache: 35 | key: dependencies-{{ checksum "package.json" }} 36 | paths: node_modules 37 | - save_cache: 38 | key: dependencies-example-{{ checksum "example/package.json" }} 39 | paths: example/node_modules 40 | - persist_to_workspace: 41 | root: . 42 | paths: . 43 | 44 | lint: 45 | executor: default 46 | steps: 47 | - attach_project 48 | - run: 49 | name: Lint files 50 | command: | 51 | yarn lint 52 | 53 | typescript: 54 | executor: default 55 | steps: 56 | - attach_project 57 | - run: 58 | name: Typecheck files 59 | command: | 60 | yarn typescript 61 | 62 | unit-tests: 63 | executor: default 64 | steps: 65 | - attach_project 66 | - run: 67 | name: Run unit tests 68 | command: | 69 | yarn test --coverage 70 | - store_artifacts: 71 | path: coverage 72 | destination: coverage 73 | 74 | build-package: 75 | executor: default 76 | steps: 77 | - attach_project 78 | - run: 79 | name: Build package 80 | command: | 81 | yarn prepare 82 | 83 | workflows: 84 | build-and-test: 85 | jobs: 86 | - install-dependencies 87 | - lint: 88 | requires: 89 | - install-dependencies 90 | - typescript: 91 | requires: 92 | - install-dependencies 93 | - unit-tests: 94 | requires: 95 | - install-dependencies 96 | - build-package: 97 | requires: 98 | - install-dependencies 99 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Setup Node.js and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup Node.js 8 | uses: actions/setup-node@v3 9 | with: 10 | node-version-file: .nvmrc 11 | 12 | - name: Cache dependencies 13 | id: yarn-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: | 17 | **/node_modules 18 | .yarn/install-state.gz 19 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ hashFiles('**/package.json') }} 20 | restore-keys: | 21 | ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 22 | ${{ runner.os }}-yarn- 23 | 24 | - name: Install dependencies 25 | if: steps.yarn-cache.outputs.cache-hit != 'true' 26 | run: yarn install --immutable 27 | shell: bash 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup 18 | uses: ./.github/actions/setup 19 | 20 | - name: Lint files 21 | run: yarn lint 22 | 23 | - name: Typecheck files 24 | run: yarn typecheck 25 | 26 | test: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | 32 | - name: Setup 33 | uses: ./.github/actions/setup 34 | 35 | - name: Run unit tests 36 | run: yarn test --maxWorkers=2 --coverage 37 | 38 | build-library: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v3 43 | 44 | - name: Setup 45 | uses: ./.github/actions/setup 46 | 47 | - name: Build package 48 | run: yarn prepare 49 | 50 | build-android: 51 | runs-on: ubuntu-latest 52 | env: 53 | TURBO_CACHE_DIR: .turbo/android 54 | steps: 55 | - name: Checkout 56 | uses: actions/checkout@v3 57 | 58 | - name: Setup 59 | uses: ./.github/actions/setup 60 | 61 | - name: Cache turborepo for Android 62 | uses: actions/cache@v3 63 | with: 64 | path: ${{ env.TURBO_CACHE_DIR }} 65 | key: ${{ runner.os }}-turborepo-android-${{ hashFiles('**/yarn.lock') }} 66 | restore-keys: | 67 | ${{ runner.os }}-turborepo-android- 68 | 69 | - name: Check turborepo cache for Android 70 | run: | 71 | TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:android').cache.status") 72 | 73 | if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then 74 | echo "turbo_cache_hit=1" >> $GITHUB_ENV 75 | fi 76 | 77 | - name: Install JDK 78 | if: env.turbo_cache_hit != 1 79 | uses: actions/setup-java@v3 80 | with: 81 | distribution: 'zulu' 82 | java-version: '11' 83 | 84 | - name: Finalize Android SDK 85 | if: env.turbo_cache_hit != 1 86 | run: | 87 | /bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null" 88 | 89 | - name: Cache Gradle 90 | if: env.turbo_cache_hit != 1 91 | uses: actions/cache@v3 92 | with: 93 | path: | 94 | ~/.gradle/wrapper 95 | ~/.gradle/caches 96 | key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/gradle/wrapper/gradle-wrapper.properties') }} 97 | restore-keys: | 98 | ${{ runner.os }}-gradle- 99 | 100 | - name: Build example for Android 101 | run: | 102 | yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" 103 | 104 | build-ios: 105 | runs-on: macos-latest 106 | env: 107 | TURBO_CACHE_DIR: .turbo/ios 108 | steps: 109 | - name: Checkout 110 | uses: actions/checkout@v3 111 | 112 | - name: Setup 113 | uses: ./.github/actions/setup 114 | 115 | - name: Cache turborepo for iOS 116 | uses: actions/cache@v3 117 | with: 118 | path: ${{ env.TURBO_CACHE_DIR }} 119 | key: ${{ runner.os }}-turborepo-ios-${{ hashFiles('**/yarn.lock') }} 120 | restore-keys: | 121 | ${{ runner.os }}-turborepo-ios- 122 | 123 | - name: Check turborepo cache for iOS 124 | run: | 125 | TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:ios').cache.status") 126 | 127 | if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then 128 | echo "turbo_cache_hit=1" >> $GITHUB_ENV 129 | fi 130 | 131 | - name: Cache cocoapods 132 | if: env.turbo_cache_hit != 1 133 | id: cocoapods-cache 134 | uses: actions/cache@v3 135 | with: 136 | path: | 137 | **/ios/Pods 138 | key: ${{ runner.os }}-cocoapods-${{ hashFiles('example/ios/Podfile.lock') }} 139 | restore-keys: | 140 | ${{ runner.os }}-cocoapods- 141 | 142 | - name: Install cocoapods 143 | if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' 144 | run: | 145 | yarn pod-install example/ios 146 | env: 147 | NO_FLIPPER: 1 148 | 149 | - name: Build example for iOS 150 | run: | 151 | yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" 152 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Yarn 64 | .yarn/* 65 | !.yarn/patches 66 | !.yarn/plugins 67 | !.yarn/releases 68 | !.yarn/sdks 69 | !.yarn/versions 70 | 71 | # Expo 72 | .expo/ 73 | 74 | # Turborepo 75 | .turbo/ 76 | 77 | # generated by bob 78 | lib/ 79 | -------------------------------------------------------------------------------- /.husky/.npmignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint -E HUSKY_GIT_PARAMS 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint && yarn typescript 5 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v18 2 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | nmHoistingLimits: workspaces 3 | 4 | plugins: 5 | - path: scripts/pod-install.cjs 6 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 7 | spec: "@yarnpkg/plugin-interactive-tools" 8 | - path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs 9 | spec: "@yarnpkg/plugin-workspace-tools" 10 | 11 | yarnPath: .yarn/releases/yarn-3.6.1.cjs 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. 4 | 5 | ## Development workflow 6 | 7 | To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: 8 | 9 | ```sh 10 | yarn 11 | ``` 12 | 13 | > While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. 14 | 15 | While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app. 16 | 17 | To start the packager: 18 | 19 | ```sh 20 | yarn example start 21 | ``` 22 | 23 | To run the example app on Android: 24 | 25 | ```sh 26 | yarn example android 27 | ``` 28 | 29 | To run the example app on iOS: 30 | 31 | ```sh 32 | yarn example ios 33 | ``` 34 | 35 | Make sure your code passes TypeScript and ESLint. Run the following to verify: 36 | 37 | ```sh 38 | yarn typescript 39 | yarn lint 40 | ``` 41 | 42 | To fix formatting errors, run the following: 43 | 44 | ```sh 45 | yarn lint --fix 46 | ``` 47 | 48 | Remember to add tests for your change if possible. Run the unit tests by: 49 | 50 | ```sh 51 | yarn test 52 | ``` 53 | 54 | To edit the Objective-C files, open `example/ios/ReactNativeUnityExample.xcworkspace` in XCode and find the source files at `Pods > Development Pods > @azesmway/react-native-unity`. 55 | 56 | To edit the Kotlin files, open `example/android` in Android studio and find the source files at `azesmwayreactnativeunity` under `Android`. 57 | 58 | ### Commit message convention 59 | 60 | We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: 61 | 62 | - `fix`: bug fixes, e.g. fix crash due to deprecated method. 63 | - `feat`: new features, e.g. add new method to the module. 64 | - `refactor`: code refactor, e.g. migrate from class components to hooks. 65 | - `docs`: changes into documentation, e.g. add usage example for the module.. 66 | - `test`: adding or updating tests, e.g. add integration tests using detox. 67 | - `chore`: tooling changes, e.g. change CI config. 68 | 69 | Our pre-commit hooks verify that your commit message matches this format when committing. 70 | 71 | ### Linting and tests 72 | 73 | [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/) 74 | 75 | We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. 76 | 77 | Our pre-commit hooks verify that the linter and tests pass when committing. 78 | 79 | ### Publishing to npm 80 | 81 | We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc. 82 | 83 | To publish new versions, run the following: 84 | 85 | ```sh 86 | yarn release 87 | ``` 88 | 89 | ### Scripts 90 | 91 | The `package.json` file contains various scripts for common tasks: 92 | 93 | - `yarn bootstrap`: setup project by installing all dependencies and pods. 94 | - `yarn typescript`: type-check files with TypeScript. 95 | - `yarn lint`: lint files with ESLint. 96 | - `yarn test`: run unit tests with Jest. 97 | - `yarn example start`: start the Metro server for the example app. 98 | - `yarn example android`: run the example app on Android. 99 | - `yarn example ios`: run the example app on iOS. 100 | 101 | ### Sending a pull request 102 | 103 | > **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github). 104 | 105 | When you're sending a pull request: 106 | 107 | - Prefer small pull requests focused on one change. 108 | - Verify that linters and tests are passing. 109 | - Review the documentation to make sure it looks good. 110 | - Follow the pull request template when opening a pull request. 111 | - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. 112 | 113 | ## Code of Conduct 114 | 115 | ### Our Pledge 116 | 117 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 118 | 119 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 120 | 121 | ### Our Standards 122 | 123 | Examples of behavior that contributes to a positive environment for our community include: 124 | 125 | - Demonstrating empathy and kindness toward other people 126 | - Being respectful of differing opinions, viewpoints, and experiences 127 | - Giving and gracefully accepting constructive feedback 128 | - Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience 129 | - Focusing on what is best not just for us as individuals, but for the overall community 130 | 131 | Examples of unacceptable behavior include: 132 | 133 | - The use of sexualized language or imagery, and sexual attention or 134 | advances of any kind 135 | - Trolling, insulting or derogatory comments, and personal or political attacks 136 | - Public or private harassment 137 | - Publishing others' private information, such as a physical or email 138 | address, without their explicit permission 139 | - Other conduct which could reasonably be considered inappropriate in a 140 | professional setting 141 | 142 | ### Enforcement Responsibilities 143 | 144 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 145 | 146 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 147 | 148 | ### Scope 149 | 150 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 151 | 152 | ### Enforcement 153 | 154 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly. 155 | 156 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 157 | 158 | ### Enforcement Guidelines 159 | 160 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 161 | 162 | #### 1. Correction 163 | 164 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 165 | 166 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 167 | 168 | #### 2. Warning 169 | 170 | **Community Impact**: A violation through a single incident or series of actions. 171 | 172 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 173 | 174 | #### 3. Temporary Ban 175 | 176 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 177 | 178 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 179 | 180 | #### 4. Permanent Ban 181 | 182 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 183 | 184 | **Consequence**: A permanent ban from any sort of public interaction within the community. 185 | 186 | ### Attribution 187 | 188 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, 189 | available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 190 | 191 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 192 | 193 | [homepage]: https://www.contributor-covenant.org 194 | 195 | For answers to common questions about this code of conduct, see the FAQ at 196 | https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. 197 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 azesm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # @azesmway/react-native-unity 2 | 3 | The plugin that allows you to embed a Unity project into React Native as a full-fledged component. The plugin now supports the new architecture. 4 | 5 | ### Android 6 | Attention! Added support for Unity 2023 and above 7 | 8 | > [!IMPORTANT] 9 | > For iOS, it is no longer necessary to embed a project created with Unity. Only the built `UnityFramework` is used. It should be placed in the plugin folder at the path - `/unity/builds/ios` 10 | 11 | ## Device Support: 12 | 13 | | Platform | Supported | 14 | | ---------------- | --------- | 15 | | iOS Simulator | ❌ | 16 | | iOS Device | ✅ | 17 | | Android Emulator | ✅ | 18 | | Android Device | ✅ | 19 | 20 | # Installation 21 | 22 | ## Install this package in your react-native project: 23 | 24 | ```sh 25 | npm install @azesmway/react-native-unity 26 | 27 | or 28 | 29 | yarn add @azesmway/react-native-unity 30 | ``` 31 | 32 | ## Configure your Unity project: 33 | 34 | 1. Copy the contents of the folder `unity` to the root of your Unity project. This folder contains the necessary scripts and settings for the Unity project. You can find these files in your react-native project under `node_modules/@azesmway/react-native-unity/unity`. This is necessary to ensure iOS has access to the `NativeCallProxy` class from this library. 35 | 36 | 2. (optional) If you're following along with the example, you can add the following code to the `ButtonBehavior.cs` script in your Unity project. This allows the button press in Unity to communicate with your react-native app. 37 | 38 |
39 | ButtonBehavior.cs 40 | 41 | ```csharp 42 | using System; 43 | using System.Collections; 44 | using System.Collections.Generic; 45 | using System.Runtime.InteropServices; 46 | using UnityEngine.UI; 47 | using UnityEngine; 48 | 49 | public class NativeAPI { 50 | #if UNITY_IOS && !UNITY_EDITOR 51 | [DllImport("__Internal")] 52 | public static extern void sendMessageToMobileApp(string message); 53 | #endif 54 | } 55 | 56 | public class ButtonBehavior : MonoBehaviour 57 | { 58 | public void ButtonPressed() 59 | { 60 | if (Application.platform == RuntimePlatform.Android) 61 | { 62 | using (AndroidJavaClass jc = new AndroidJavaClass("com.azesmwayreactnativeunity.ReactNativeUnityViewManager")) 63 | { 64 | jc.CallStatic("sendMessageToMobileApp", "The button has been tapped!"); 65 | } 66 | } 67 | else if (Application.platform == RuntimePlatform.IPhonePlayer) 68 | { 69 | #if UNITY_IOS && !UNITY_EDITOR 70 | NativeAPI.sendMessageToMobileApp("The button has been tapped!"); 71 | #endif 72 | } 73 | } 74 | } 75 | ``` 76 | 77 |
78 | 79 | ## Export iOS Unity Project: 80 | 81 | After you've moved the files from the `unity` folder to your Unity project, you can export the iOS unity project by following these steps: 82 | 83 | 1. Open your Unity project 84 | 2. Build Unity project for ios in ANY folder - just not the main RN project folder!!! 85 | 3. Open the created project in XCode 86 | 4. Select Data folder and set a checkbox in the "Target Membership" section to "UnityFramework" ![image info](./docs/step1.jpg) 87 | 5. You need to select the NativeCallProxy.h inside the `Unity-iPhone/Libraries/Plugins/iOS` folder of the Unity-iPhone project and change UnityFramework’s target membership from Project to Public. Don’t forget this step! (if you don't see these files in your Xcode project, you didn't copy over the `unity` folder to your Unity project correctly in previous steps) ![image info](./docs/step2.jpg) 88 | 6. If required - sign the project `UnityFramework.framework` and build a framework ![image info](./docs/step3.jpg) 89 | 7. Open the folder with the built framework (by right-clicking) and move it to the plugin folder (`/unity/builds/ios`) ![image info](./docs/step4.jpg) 90 | 8. Remove your `Pods` cache and lockfile with this command in the root of the main RN project `rm -rf ios/Pods && rm -f ios/Podfile.lock && npx pod-install` 91 | 92 | ### Android 93 | 94 | 1. Open your Unity project 95 | 2. Export Unity app to `/unity/builds/android` 96 | 3. Remove `...` from `/unity/builds/android/unityLibrary/src/main/AndroidManifest.xml` at unityLibrary to leave only integrated version. 97 | 98 | If you're using expo, you're done. The built-in expo plugin will handle the rest. If you're not using expo, you'll need to follow the steps below. 99 | 100 | 1. Add the following lines to `android/settings.gradle`: 101 | ```groovy 102 | include ':unityLibrary' 103 | project(':unityLibrary').projectDir=new File('..\\unity\\builds\\android\\unityLibrary') 104 | ``` 105 | 2. Add into `android/build.gradle` 106 | ```groovy 107 | allprojects { 108 | repositories { 109 | // this 110 | flatDir { 111 | dirs "${project(':unityLibrary').projectDir}/libs" 112 | } 113 | // ... 114 | } 115 | } 116 | ``` 117 | 3. Add into `android/gradle.properties` 118 | ```gradle 119 | unityStreamingAssets=.unity3d 120 | ``` 121 | 4. Add strings to `android/app/src/main/res/values/strings.xml` 122 | 123 | ```javascript 124 | Game view 125 | ``` 126 | 127 | # Known issues 128 | 129 | - Does not work on the iOS simulator. 130 | - On iOS the Unity view is waiting for a parent with dimensions greater than 0 (from RN side). Please take care of this because if it is not the case, your app will crash with the native message `MTLTextureDescriptor has width of zero`. 131 | 132 | # Usage 133 | 134 | ## Sample code 135 | 136 | ```jsx 137 | import React, { useRef, useEffect } from 'react'; 138 | 139 | import UnityView from '@azesmway/react-native-unity'; 140 | import { View } from 'react-native'; 141 | 142 | interface IMessage { 143 | gameObject: string; 144 | methodName: string; 145 | message: string; 146 | } 147 | 148 | const Unity = () => { 149 | const unityRef = useRef(null); 150 | 151 | useEffect(() => { 152 | if (unityRef?.current) { 153 | const message: IMessage = { 154 | gameObject: 'gameObject', 155 | methodName: 'methodName', 156 | message: 'message', 157 | }; 158 | unityRef.current.postMessage( 159 | message.gameObject, 160 | message.methodName, 161 | message.message 162 | ); 163 | } 164 | }, []); 165 | 166 | return ( 167 | 168 | { 172 | console.log('onUnityMessage', result.nativeEvent.message); 173 | }} 174 | /> 175 | 176 | ); 177 | }; 178 | 179 | export default Unity; 180 | ``` 181 | 182 | ## Props 183 | 184 | - `style: ViewStyle` - styles the UnityView. (Won't show on Android without dimensions. Recommended to give it `flex: 1` as in the example) 185 | - `onUnityMessage?: (event: NativeSyntheticEvent)` - receives a message from a Unity 186 | - `androidKeepPlayerMounted?: boolean` - if set to true, keep the player mounted even when the view that contains it has lost focus. The player will be paused on blur and resumed on focus. **ANDROID ONLY** 187 | - `fullScreen?: boolean` - defaults to true. If set to false, will not request full screen access. **ANDROID ONLY** 188 | 189 | ## Methods 190 | 191 | - `postMessage(gameObject, methodName, message)` - sends a message to the Unity. **FOR IOS:** The native method of unity is used to send a message 192 | `sendMessageToGOWithName:(const char*)goName functionName:(const char*)name message:(const char*)msg;`, more details can be found in the [documentation](https://docs.unity3d.com/2021.1/Documentation/Manual/UnityasaLibrary-iOS.html) 193 | - `unloadUnity()` - the Unity is unloaded automatically when the react-native component is unmounted, but if you want to unload the Unity, you can call this method 194 | - `pauseUnity?: (pause: boolean)` - pause the Unity 195 | - `windowFocusChanged(hasFocus: boolean = false)` - simulate focus change (intended to be used to recover from black screen (not rendering) after remounting Unity view when `resumeUnity` does not work) **ANDROID ONLY** 196 | 197 | # Contributing 198 | 199 | See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow. 200 | 201 | # License 202 | 203 | MIT 204 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:7.4.2" 9 | } 10 | } 11 | 12 | def isNewArchitectureEnabled() { 13 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true" 14 | } 15 | 16 | apply plugin: "com.android.library" 17 | 18 | if (isNewArchitectureEnabled()) { 19 | apply plugin: "com.facebook.react" 20 | } 21 | 22 | def getExtOrDefault(name) { 23 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Unity_" + name] 24 | } 25 | 26 | def getExtOrIntegerDefault(name) { 27 | return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Unity_" + name]).toInteger() 28 | } 29 | 30 | def supportsNamespace() { 31 | def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.') 32 | def major = parsed[0].toInteger() 33 | def minor = parsed[1].toInteger() 34 | 35 | // Namespace support was added in 7.3.0 36 | return (major == 7 && minor >= 3) || major >= 8 37 | } 38 | 39 | android { 40 | if (supportsNamespace()) { 41 | namespace "com.azesmwayreactnativeunity" 42 | 43 | sourceSets { 44 | main { 45 | manifest.srcFile "src/main/AndroidManifestNew.xml" 46 | } 47 | } 48 | } 49 | 50 | compileSdkVersion getExtOrIntegerDefault("compileSdkVersion") 51 | 52 | defaultConfig { 53 | minSdkVersion getExtOrIntegerDefault("minSdkVersion") 54 | targetSdkVersion getExtOrIntegerDefault("targetSdkVersion") 55 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() 56 | 57 | } 58 | 59 | buildFeatures { 60 | buildConfig true 61 | } 62 | 63 | buildTypes { 64 | release { 65 | minifyEnabled false 66 | } 67 | } 68 | 69 | lintOptions { 70 | disable "GradleCompatible" 71 | } 72 | 73 | compileOptions { 74 | sourceCompatibility JavaVersion.VERSION_1_8 75 | targetCompatibility JavaVersion.VERSION_1_8 76 | } 77 | 78 | sourceSets { 79 | main { 80 | if (isNewArchitectureEnabled()) { 81 | java.srcDirs += [ 82 | "src/newarch", 83 | // This is needed to build Kotlin project with NewArch enabled 84 | "${project.buildDir}/generated/source/codegen/java" 85 | ] 86 | } else { 87 | java.srcDirs += ["src/oldarch"] 88 | } 89 | } 90 | } 91 | } 92 | 93 | repositories { 94 | mavenLocal() 95 | maven { 96 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 97 | url("$rootDir/../node_modules/react-native/android") 98 | } 99 | google() 100 | mavenCentral() 101 | jcenter() 102 | } 103 | 104 | 105 | dependencies { 106 | // For < 0.71, this will be from the local maven repo 107 | // For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin 108 | //noinspection GradleDynamicVersion 109 | implementation "com.facebook.react:react-native:+" 110 | implementation project(':unityLibrary') 111 | implementation files("${project(':unityLibrary').projectDir}/libs/unity-classes.jar") 112 | } 113 | 114 | if (isNewArchitectureEnabled()) { 115 | react { 116 | jsRootDir = file("../src/") 117 | libraryName = "RNUnityView" 118 | codegenJavaPackageName = "com.azesmwayreactnativeunity" 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | Unity_kotlinVersion=1.8.0 2 | Unity_minSdkVersion=26 3 | Unity_targetSdkVersion=33 4 | Unity_compileSdkVersion=33 5 | Unity_ndkversion=23.1.7779620 6 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifestNew.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/src/main/java/com/azesmwayreactnativeunity/ReactNativeUnity.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import android.app.Activity; 4 | import android.graphics.PixelFormat; 5 | import android.os.Build; 6 | import android.view.ViewGroup; 7 | import android.view.WindowManager; 8 | 9 | import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; 10 | 11 | import java.lang.reflect.InvocationTargetException; 12 | 13 | public class ReactNativeUnity { 14 | private static UPlayer unityPlayer; 15 | public static boolean _isUnityReady; 16 | public static boolean _isUnityPaused; 17 | public static boolean _fullScreen; 18 | 19 | public static UPlayer getPlayer() { 20 | if (!_isUnityReady) { 21 | return null; 22 | } 23 | return unityPlayer; 24 | } 25 | 26 | public static boolean isUnityReady() { 27 | return _isUnityReady; 28 | } 29 | 30 | public static boolean isUnityPaused() { 31 | return _isUnityPaused; 32 | } 33 | 34 | public static void createPlayer(final Activity activity, final UnityPlayerCallback callback) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 35 | if (unityPlayer != null) { 36 | callback.onReady(); 37 | 38 | return; 39 | } 40 | 41 | if (activity != null) { 42 | activity.runOnUiThread(new Runnable() { 43 | @Override 44 | public void run() { 45 | activity.getWindow().setFormat(PixelFormat.RGBA_8888); 46 | int flag = activity.getWindow().getAttributes().flags; 47 | boolean fullScreen = false; 48 | if ((flag & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN) { 49 | fullScreen = true; 50 | } 51 | 52 | try { 53 | unityPlayer = new UPlayer(activity, callback); 54 | } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException e) {} 55 | 56 | try { 57 | // wait a moment. fix unity cannot start when startup. 58 | Thread.sleep(1000); 59 | } catch (Exception e) {} 60 | 61 | // start unity 62 | try { 63 | addUnityViewToBackground(); 64 | } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {} 65 | 66 | unityPlayer.windowFocusChanged(true); 67 | 68 | try { 69 | unityPlayer.requestFocusPlayer(); 70 | } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {} 71 | 72 | unityPlayer.resume(); 73 | 74 | if (!fullScreen) { 75 | activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); 76 | activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 77 | } 78 | 79 | _isUnityReady = true; 80 | 81 | try { 82 | callback.onReady(); 83 | } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {} 84 | } 85 | }); 86 | } 87 | } 88 | 89 | public static void pause() { 90 | if (unityPlayer != null) { 91 | unityPlayer.pause(); 92 | _isUnityPaused = true; 93 | } 94 | } 95 | 96 | public static void resume() { 97 | if (unityPlayer != null) { 98 | unityPlayer.resume(); 99 | _isUnityPaused = false; 100 | } 101 | } 102 | 103 | public static void unload() { 104 | if (unityPlayer != null) { 105 | unityPlayer.unload(); 106 | _isUnityPaused = false; 107 | } 108 | } 109 | 110 | public static void addUnityViewToBackground() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 111 | if (unityPlayer == null) { 112 | return; 113 | } 114 | 115 | if (unityPlayer.getParentPlayer() != null) { 116 | // NOTE: If we're being detached as part of the transition, make sure 117 | // to explicitly finish the transition first, as it might still keep 118 | // the view's parent around despite calling `removeView()` here. This 119 | // prevents a crash on an `addContentView()` later on. 120 | // Otherwise, if there's no transition, it's a no-op. 121 | // See https://stackoverflow.com/a/58247331 122 | ((ViewGroup) unityPlayer.getParentPlayer()).endViewTransition(unityPlayer.requestFrame()); 123 | ((ViewGroup) unityPlayer.getParentPlayer()).removeView(unityPlayer.requestFrame()); 124 | } 125 | 126 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 127 | unityPlayer.setZ(-1f); 128 | } 129 | 130 | final Activity activity = ((Activity) unityPlayer.getContextPlayer()); 131 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(1, 1); 132 | activity.addContentView(unityPlayer.requestFrame(), layoutParams); 133 | } 134 | 135 | public static void addUnityViewToGroup(ViewGroup group) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 136 | if (unityPlayer == null) { 137 | return; 138 | } 139 | 140 | if (unityPlayer.getParentPlayer() != null) { 141 | ((ViewGroup) unityPlayer.getParentPlayer()).removeView(unityPlayer.requestFrame()); 142 | } 143 | 144 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT); 145 | group.addView(unityPlayer.requestFrame(), 0, layoutParams); 146 | unityPlayer.windowFocusChanged(true); 147 | unityPlayer.requestFocusPlayer(); 148 | unityPlayer.resume(); 149 | } 150 | 151 | public interface UnityPlayerCallback { 152 | void onReady() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException; 153 | 154 | void onUnload(); 155 | 156 | void onQuit(); 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /android/src/main/java/com/azesmwayreactnativeunity/ReactNativeUnityView.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import static com.azesmwayreactnativeunity.ReactNativeUnity.*; 4 | 5 | import android.content.Context; 6 | 7 | import android.annotation.SuppressLint; 8 | import android.content.res.Configuration; 9 | import android.widget.FrameLayout; 10 | 11 | import java.lang.reflect.InvocationTargetException; 12 | 13 | @SuppressLint("ViewConstructor") 14 | public class ReactNativeUnityView extends FrameLayout { 15 | private UPlayer view; 16 | public boolean keepPlayerMounted = false; 17 | 18 | public ReactNativeUnityView(Context context) { 19 | super(context); 20 | } 21 | 22 | public void setUnityPlayer(UPlayer player) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 23 | this.view = player; 24 | addUnityViewToGroup(this); 25 | } 26 | 27 | @Override 28 | public void onWindowFocusChanged(boolean hasWindowFocus) { 29 | super.onWindowFocusChanged(hasWindowFocus); 30 | 31 | if (view == null) { 32 | return; 33 | } 34 | 35 | view.windowFocusChanged(hasWindowFocus); 36 | 37 | if (!keepPlayerMounted || !_isUnityReady) { 38 | return; 39 | } 40 | 41 | // pause Unity on blur, resume on focus 42 | if (hasWindowFocus && _isUnityPaused) { 43 | // view.requestFocus(); 44 | view.resume(); 45 | } else if (!hasWindowFocus && !_isUnityPaused) { 46 | view.pause(); 47 | } 48 | } 49 | 50 | @Override 51 | protected void onConfigurationChanged(Configuration newConfig) { 52 | super.onConfigurationChanged(newConfig); 53 | 54 | if (view != null) { 55 | view.configurationChanged(newConfig); 56 | } 57 | } 58 | 59 | @Override 60 | protected void onDetachedFromWindow() { 61 | if (!this.keepPlayerMounted) { 62 | try { 63 | addUnityViewToBackground(); 64 | } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { 65 | throw new RuntimeException(e); 66 | } 67 | } 68 | 69 | super.onDetachedFromWindow(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /android/src/main/java/com/azesmwayreactnativeunity/ReactNativeUnityViewManager.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import static com.azesmwayreactnativeunity.ReactNativeUnity.*; 4 | 5 | import android.os.Handler; 6 | import android.view.View; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | 11 | import com.facebook.infer.annotation.Assertions; 12 | import com.facebook.react.bridge.Arguments; 13 | import com.facebook.react.bridge.LifecycleEventListener; 14 | import com.facebook.react.bridge.ReactApplicationContext; 15 | import com.facebook.react.bridge.ReactContext; 16 | import com.facebook.react.bridge.ReadableArray; 17 | import com.facebook.react.bridge.WritableMap; 18 | import com.facebook.react.common.MapBuilder; 19 | import com.facebook.react.module.annotations.ReactModule; 20 | import com.facebook.react.uimanager.ThemedReactContext; 21 | import com.facebook.react.uimanager.annotations.ReactProp; 22 | import com.facebook.react.uimanager.events.RCTEventEmitter; 23 | 24 | import java.lang.reflect.InvocationTargetException; 25 | import java.util.Map; 26 | 27 | @ReactModule(name = ReactNativeUnityViewManager.NAME) 28 | public class ReactNativeUnityViewManager extends ReactNativeUnityViewManagerSpec implements LifecycleEventListener, View.OnAttachStateChangeListener { 29 | ReactApplicationContext context; 30 | static ReactNativeUnityView view; 31 | public static final String NAME = "RNUnityView"; 32 | 33 | public ReactNativeUnityViewManager(ReactApplicationContext context) { 34 | super(); 35 | this.context = context; 36 | context.addLifecycleEventListener(this); 37 | } 38 | 39 | @NonNull 40 | @Override 41 | public String getName() { 42 | return NAME; 43 | } 44 | 45 | @NonNull 46 | @Override 47 | public ReactNativeUnityView createViewInstance(@NonNull ThemedReactContext context) { 48 | view = new ReactNativeUnityView(this.context); 49 | view.addOnAttachStateChangeListener(this); 50 | 51 | if (getPlayer() != null) { 52 | try { 53 | view.setUnityPlayer(getPlayer()); 54 | } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {} 55 | } else { 56 | try { 57 | createPlayer(context.getCurrentActivity(), new UnityPlayerCallback() { 58 | @Override 59 | public void onReady() throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { 60 | view.setUnityPlayer(getPlayer()); 61 | } 62 | 63 | @Override 64 | public void onUnload() { 65 | WritableMap data = Arguments.createMap(); 66 | data.putString("message", "MyMessage"); 67 | ReactContext reactContext = (ReactContext) view.getContext(); 68 | reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "onPlayerUnload", data); 69 | } 70 | 71 | @Override 72 | public void onQuit() { 73 | WritableMap data = Arguments.createMap(); 74 | data.putString("message", "MyMessage"); 75 | ReactContext reactContext = (ReactContext) view.getContext(); 76 | reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "onPlayerQuit", data); 77 | } 78 | }); 79 | } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {} 80 | } 81 | 82 | return view; 83 | } 84 | 85 | @Override 86 | public Map getExportedCustomDirectEventTypeConstants() { 87 | Map export = super.getExportedCustomDirectEventTypeConstants(); 88 | 89 | if (export == null) { 90 | export = MapBuilder.newHashMap(); 91 | } 92 | 93 | export.put("onUnityMessage", MapBuilder.of("registrationName", "onUnityMessage")); 94 | export.put("onPlayerUnload", MapBuilder.of("registrationName", "onPlayerUnload")); 95 | export.put("onPlayerQuit", MapBuilder.of("registrationName", "onPlayerQuit")); 96 | 97 | return export; 98 | } 99 | 100 | @Override 101 | public void receiveCommand(@NonNull ReactNativeUnityView view, String commandType, @Nullable ReadableArray args) { 102 | Assertions.assertNotNull(view); 103 | Assertions.assertNotNull(args); 104 | 105 | switch (commandType) { 106 | case "postMessage": 107 | assert args != null; 108 | postMessage(view, args.getString(0), args.getString(1), args.getString(2)); 109 | return; 110 | case "unloadUnity": 111 | unloadUnity(view); 112 | return; 113 | case "pauseUnity": 114 | assert args != null; 115 | pauseUnity(view, args.getBoolean(0)); 116 | return; 117 | case "resumeUnity": 118 | resumeUnity(view); 119 | return; 120 | case "windowFocusChanged": 121 | assert args != null; 122 | windowFocusChanged(view, args.getBoolean(0)); 123 | return; 124 | default: 125 | throw new IllegalArgumentException(String.format( 126 | "Unsupported command %s received by %s.", 127 | commandType, 128 | getClass().getSimpleName())); 129 | } 130 | } 131 | 132 | @Override 133 | public void unloadUnity(ReactNativeUnityView view) { 134 | if (isUnityReady()) { 135 | unload(); 136 | } 137 | } 138 | 139 | @Override 140 | public void pauseUnity(ReactNativeUnityView view, boolean pause) { 141 | if (isUnityReady()) { 142 | assert getPlayer() != null; 143 | getPlayer().pause(); 144 | } 145 | } 146 | 147 | @Override 148 | public void resumeUnity(ReactNativeUnityView view) { 149 | if (isUnityReady()) { 150 | assert getPlayer() != null; 151 | getPlayer().resume(); 152 | } 153 | } 154 | 155 | @Override 156 | public void windowFocusChanged(ReactNativeUnityView view, boolean hasFocus) { 157 | if (isUnityReady()) { 158 | assert getPlayer() != null; 159 | getPlayer().windowFocusChanged(hasFocus); 160 | } 161 | } 162 | 163 | public static void sendMessageToMobileApp(String message) { 164 | WritableMap data = Arguments.createMap(); 165 | data.putString("message", message); 166 | ReactContext reactContext = (ReactContext) view.getContext(); 167 | reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(view.getId(), "onUnityMessage", data); 168 | } 169 | 170 | @Override 171 | public void onDropViewInstance(ReactNativeUnityView view) { 172 | view.removeOnAttachStateChangeListener(this); 173 | super.onDropViewInstance(view); 174 | } 175 | 176 | @Override 177 | public void onHostResume() { 178 | if (isUnityReady()) { 179 | assert getPlayer() != null; 180 | getPlayer().resume(); 181 | restoreUnityUserState(); 182 | } 183 | } 184 | 185 | @Override 186 | public void onHostPause() { 187 | if (isUnityReady()) { 188 | assert getPlayer() != null; 189 | getPlayer().pause(); 190 | } 191 | } 192 | 193 | @Override 194 | public void onHostDestroy() { 195 | if (isUnityReady()) { 196 | assert getPlayer() != null; 197 | getPlayer().destroy(); 198 | } 199 | } 200 | 201 | private void restoreUnityUserState() { 202 | // restore the unity player state 203 | if (isUnityPaused()) { 204 | Handler handler = new Handler(); 205 | handler.postDelayed(new Runnable() { 206 | @Override 207 | public void run() { 208 | if (getPlayer() != null) { 209 | getPlayer().pause(); 210 | } 211 | } 212 | }, 300); 213 | } 214 | } 215 | 216 | @Override 217 | public void onViewAttachedToWindow(View v) { 218 | restoreUnityUserState(); 219 | } 220 | 221 | @Override 222 | public void onViewDetachedFromWindow(View v) {} 223 | 224 | @ReactProp(name = "androidKeepPlayerMounted", defaultBoolean = false) 225 | public void setAndroidKeepPlayerMounted(ReactNativeUnityView view, boolean keepPlayerMounted) { 226 | view.keepPlayerMounted = keepPlayerMounted; 227 | } 228 | 229 | @ReactProp(name = "fullScreen", defaultBoolean = true) 230 | public void setFullScreen(ReactNativeUnityView view, boolean fullScreen) { 231 | _fullScreen = fullScreen; 232 | } 233 | 234 | @Override 235 | public void postMessage(ReactNativeUnityView view, String gameObject, String methodName, String message) { 236 | if (isUnityReady()) { 237 | assert getPlayer() != null; 238 | UPlayer.UnitySendMessage(gameObject, methodName, message); 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /android/src/main/java/com/azesmwayreactnativeunity/ReactNativeUnityViewPackage.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.NativeModule; 5 | import com.facebook.react.bridge.ReactApplicationContext; 6 | import com.facebook.react.uimanager.ViewManager; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class ReactNativeUnityViewPackage implements ReactPackage { 13 | @Override 14 | public List createViewManagers(ReactApplicationContext reactContext) { 15 | List viewManagers = new ArrayList<>(); 16 | viewManagers.add(new ReactNativeUnityViewManager(reactContext)); 17 | return viewManagers; 18 | } 19 | 20 | @Override 21 | public List createNativeModules(ReactApplicationContext reactContext) { 22 | return Collections.emptyList(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/src/main/java/com/azesmwayreactnativeunity/UPlayer.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import android.app.Activity; 4 | import android.content.res.Configuration; 5 | import android.widget.FrameLayout; 6 | 7 | import com.unity3d.player.*; 8 | 9 | import java.lang.reflect.Constructor; 10 | import java.lang.reflect.InvocationTargetException; 11 | import java.lang.reflect.Method; 12 | 13 | public class UPlayer { 14 | private static UnityPlayer unityPlayer; 15 | 16 | public UPlayer(final Activity activity, final ReactNativeUnity.UnityPlayerCallback callback) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException { 17 | super(); 18 | Class _player = null; 19 | 20 | try { 21 | _player = Class.forName("com.unity3d.player.UnityPlayerForActivityOrService"); 22 | } catch (ClassNotFoundException e) { 23 | _player = Class.forName("com.unity3d.player.UnityPlayer"); 24 | } 25 | 26 | Constructor constructor = _player.getConstructors()[1]; 27 | unityPlayer = (UnityPlayer) constructor.newInstance(activity, new IUnityPlayerLifecycleEvents() { 28 | @Override 29 | public void onUnityPlayerUnloaded() { 30 | callback.onUnload(); 31 | } 32 | 33 | @Override 34 | public void onUnityPlayerQuitted() { 35 | callback.onQuit(); 36 | } 37 | }); 38 | } 39 | 40 | public static void UnitySendMessage(String gameObject, String methodName, String message) { 41 | UnityPlayer.UnitySendMessage(gameObject, methodName, message); 42 | } 43 | 44 | public void pause() { 45 | unityPlayer.pause(); 46 | } 47 | 48 | public void windowFocusChanged(boolean b) { 49 | unityPlayer.windowFocusChanged(b); 50 | } 51 | 52 | public void resume() { 53 | unityPlayer.resume(); 54 | } 55 | 56 | public void unload() { 57 | unityPlayer.unload(); 58 | } 59 | 60 | public Object getParentPlayer() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 61 | try { 62 | Method getFrameLayout = unityPlayer.getClass().getMethod("getFrameLayout"); 63 | FrameLayout frame = (FrameLayout) this.requestFrame(); 64 | 65 | return frame.getParent(); 66 | } catch (NoSuchMethodException e) { 67 | Method getParent = unityPlayer.getClass().getMethod("getParent"); 68 | 69 | return getParent.invoke(unityPlayer); 70 | } 71 | } 72 | 73 | public void configurationChanged(Configuration newConfig) { 74 | unityPlayer.configurationChanged(newConfig); 75 | } 76 | 77 | public void destroy() { 78 | unityPlayer.destroy(); 79 | } 80 | 81 | public void requestFocusPlayer() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 82 | try { 83 | Method getFrameLayout = unityPlayer.getClass().getMethod("getFrameLayout"); 84 | 85 | FrameLayout frame = (FrameLayout) this.requestFrame(); 86 | frame.requestFocus(); 87 | } catch (NoSuchMethodException e) { 88 | Method requestFocus = unityPlayer.getClass().getMethod("requestFocus"); 89 | 90 | requestFocus.invoke(unityPlayer); 91 | } 92 | } 93 | 94 | public FrameLayout requestFrame() throws NoSuchMethodException { 95 | try { 96 | Method getFrameLayout = unityPlayer.getClass().getMethod("getFrameLayout"); 97 | 98 | return (FrameLayout) getFrameLayout.invoke(unityPlayer); 99 | } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 100 | return unityPlayer; 101 | } 102 | } 103 | 104 | public void setZ(float v) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { 105 | try { 106 | Method setZ = unityPlayer.getClass().getMethod("setZ"); 107 | 108 | setZ.invoke(unityPlayer, v); 109 | } catch (NoSuchMethodException e) {} 110 | } 111 | 112 | public Object getContextPlayer() { 113 | return unityPlayer.getContext(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /android/src/newarch/com/azesmwayreactnativeunity/ReactNativeUnityViewManagerSpec.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.Nullable; 6 | 7 | import com.facebook.react.uimanager.SimpleViewManager; 8 | import com.facebook.react.uimanager.ViewManagerDelegate; 9 | import com.facebook.react.viewmanagers.RNUnityViewManagerDelegate; 10 | import com.facebook.react.viewmanagers.RNUnityViewManagerInterface; 11 | 12 | public abstract class ReactNativeUnityViewManagerSpec extends SimpleViewManager implements RNUnityViewManagerInterface { 13 | private final ViewManagerDelegate mDelegate; 14 | 15 | public ReactNativeUnityViewManagerSpec() { 16 | mDelegate = new RNUnityViewManagerDelegate<>(this); 17 | } 18 | 19 | @Nullable 20 | @Override 21 | protected ViewManagerDelegate getDelegate() { 22 | return mDelegate; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /android/src/oldarch/com/azesmwayreactnativeunity/ReactNativeUnityViewManagerSpec.java: -------------------------------------------------------------------------------- 1 | package com.azesmwayreactnativeunity; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.Nullable; 6 | 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.SimpleViewManager; 9 | 10 | public abstract class ReactNativeUnityViewManagerSpec extends SimpleViewManager { 11 | public abstract void postMessage(T view, String gameObject, String methodName, String message); 12 | public abstract void setAndroidKeepPlayerMounted(T view, boolean value); 13 | public abstract void setFullScreen(T view, boolean value); 14 | public abstract void unloadUnity(T view); 15 | public abstract void pauseUnity(T view, boolean pause); 16 | public abstract void resumeUnity(T view); 17 | public abstract void windowFocusChanged(T view, boolean hasFocus); 18 | } 19 | -------------------------------------------------------------------------------- /app.plugin.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./plugin/build'); -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/step1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/docs/step1.jpg -------------------------------------------------------------------------------- /docs/step2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/docs/step2.jpg -------------------------------------------------------------------------------- /docs/step3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/docs/step3.jpg -------------------------------------------------------------------------------- /docs/step4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/docs/step4.jpg -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | ignorePatterns: ['**/*.d.ts'], 4 | extends: ['@react-native', 'eslint:recommended', 'plugin:@typescript-eslint/eslint-recommended', 'plugin:ft-flow/recommended'], 5 | parser: '@typescript-eslint/parser', 6 | plugins: ['@typescript-eslint', 'simple-import-sort', 'jest', 'ft-flow'], 7 | overrides: [ 8 | { 9 | files: ['*.ts', '*.tsx'], 10 | rules: { 11 | '@typescript-eslint/no-shadow': ['error'], 12 | 'no-shadow': 'off', 13 | 'no-undef': 'off' 14 | } 15 | } 16 | ], 17 | rules: { 18 | eqeqeq: 'off', 19 | 'prettier/prettier': 'error', 20 | 'comma-dangle': ['error', 'never'], 21 | semi: ['error', 'never'], 22 | 'max-len': [ 23 | 'error', 24 | { 25 | code: 200 26 | } 27 | ], 28 | 'react-hooks/exhaustive-deps': 'off', 29 | 'simple-import-sort/exports': 'error', 30 | 'simple-import-sort/imports': 'error', 31 | 'no-unused-vars': 'off', 32 | '@typescript-eslint/no-unused-vars': 'off', 33 | '@typescript-eslint/ban-ts-ignore': 'off', 34 | 'no-unsafe-optional-chaining': 'off', 35 | 'ft-flow/boolean-style': [2, 'boolean'] 36 | }, 37 | env: { 38 | node: true, 39 | 'jest/globals': true 40 | }, 41 | settings: { 42 | 'ft-flow': { 43 | onlyFilesWithFlowAnnotation: false 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /example/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "none", 4 | "semi": false, 5 | "printWidth": 200 6 | } 7 | -------------------------------------------------------------------------------- /example/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: true, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'none', 6 | semi: false, 7 | arrowParens: 'avoid' 8 | }; 9 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (7.0.8) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | addressable (2.8.5) 12 | public_suffix (>= 2.0.2, < 6.0) 13 | algoliasearch (1.27.5) 14 | httpclient (~> 2.8, >= 2.8.3) 15 | json (>= 1.5.1) 16 | atomos (0.1.3) 17 | claide (1.1.0) 18 | cocoapods (1.14.2) 19 | addressable (~> 2.8) 20 | claide (>= 1.0.2, < 2.0) 21 | cocoapods-core (= 1.14.2) 22 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 23 | cocoapods-downloader (>= 2.0) 24 | cocoapods-plugins (>= 1.0.0, < 2.0) 25 | cocoapods-search (>= 1.0.0, < 2.0) 26 | cocoapods-trunk (>= 1.6.0, < 2.0) 27 | cocoapods-try (>= 1.1.0, < 2.0) 28 | colored2 (~> 3.1) 29 | escape (~> 0.0.4) 30 | fourflusher (>= 2.3.0, < 3.0) 31 | gh_inspector (~> 1.0) 32 | molinillo (~> 0.8.0) 33 | nap (~> 1.0) 34 | ruby-macho (>= 2.3.0, < 3.0) 35 | xcodeproj (>= 1.23.0, < 2.0) 36 | cocoapods-core (1.14.2) 37 | activesupport (>= 5.0, < 8) 38 | addressable (~> 2.8) 39 | algoliasearch (~> 1.0) 40 | concurrent-ruby (~> 1.1) 41 | fuzzy_match (~> 2.0.4) 42 | nap (~> 1.0) 43 | netrc (~> 0.11) 44 | public_suffix (~> 4.0) 45 | typhoeus (~> 1.0) 46 | cocoapods-deintegrate (1.0.5) 47 | cocoapods-downloader (2.0) 48 | cocoapods-plugins (1.0.0) 49 | nap 50 | cocoapods-search (1.0.1) 51 | cocoapods-trunk (1.6.0) 52 | nap (>= 0.8, < 2.0) 53 | netrc (~> 0.11) 54 | cocoapods-try (1.2.0) 55 | colored2 (3.1.2) 56 | concurrent-ruby (1.2.2) 57 | escape (0.0.4) 58 | ethon (0.16.0) 59 | ffi (>= 1.15.0) 60 | ffi (1.16.3) 61 | fourflusher (2.3.1) 62 | fuzzy_match (2.0.4) 63 | gh_inspector (1.1.3) 64 | httpclient (2.8.3) 65 | i18n (1.14.1) 66 | concurrent-ruby (~> 1.0) 67 | json (2.6.3) 68 | minitest (5.20.0) 69 | molinillo (0.8.0) 70 | nanaimo (0.3.0) 71 | nap (1.1.0) 72 | netrc (0.11.0) 73 | public_suffix (4.0.7) 74 | rexml (3.2.6) 75 | ruby-macho (2.5.1) 76 | typhoeus (1.4.1) 77 | ethon (>= 0.9.0) 78 | tzinfo (2.0.6) 79 | concurrent-ruby (~> 1.0) 80 | xcodeproj (1.23.0) 81 | CFPropertyList (>= 2.3.3, < 4.0) 82 | atomos (~> 0.1.3) 83 | claide (>= 1.0.2, < 2.0) 84 | colored2 (~> 3.1) 85 | nanaimo (~> 0.3.0) 86 | rexml (~> 3.2.4) 87 | 88 | PLATFORMS 89 | ruby 90 | 91 | DEPENDENCIES 92 | activesupport (>= 6.1.7.3, < 7.1.0) 93 | cocoapods (~> 1.13) 94 | 95 | RUBY VERSION 96 | ruby 2.7.7p221 97 | 98 | BUNDLED WITH 99 | 2.1.4 100 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | >**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding. 6 | 7 | ## Step 1: Start the Metro Server 8 | 9 | First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 10 | 11 | To start Metro, run the following command from the _root_ of your React Native project: 12 | 13 | ```bash 14 | # using npm 15 | npm start 16 | 17 | # OR using Yarn 18 | yarn start 19 | ``` 20 | 21 | ## Step 2: Start your Application 22 | 23 | Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app: 24 | 25 | ### For Android 26 | 27 | ```bash 28 | # using npm 29 | npm run android 30 | 31 | # OR using Yarn 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | # using npm 39 | npm run ios 40 | 41 | # OR using Yarn 42 | yarn ios 43 | ``` 44 | 45 | If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly. 46 | 47 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 48 | 49 | ## Step 3: Modifying your App 50 | 51 | Now that you have successfully run the app, let's modify it. 52 | 53 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 54 | 2. For **Android**: Press the R key twice or select **"Reload"** from the **Developer Menu** (Ctrl + M (on Window and Linux) or Cmd ⌘ + M (on macOS)) to see your changes! 55 | 56 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 57 | 58 | ## Congratulations! :tada: 59 | 60 | You've successfully run and modified your React Native App. :partying_face: 61 | 62 | ### Now what? 63 | 64 | - If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps). 65 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 66 | 67 | # Troubleshooting 68 | 69 | If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. 70 | 71 | # Learn More 72 | 73 | To learn more about React Native, take a look at the following resources: 74 | 75 | - [React Native Website](https://reactnative.dev) - learn more about React Native. 76 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. 77 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. 78 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. 79 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. 80 | -------------------------------------------------------------------------------- /example/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native' 6 | 7 | // Note: import explicitly to use the types shiped with jest. 8 | import { it } from '@jest/globals' 9 | import React from 'react' 10 | // Note: test renderer must be required after react-native. 11 | import renderer from 'react-test-renderer' 12 | 13 | import App from '../src/App' 14 | 15 | it('renders correctly', () => { 16 | renderer.create() 17 | }) 18 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | 4 | /** 5 | * This is the configuration block to customize your React Native Android app. 6 | * By default you don't need to apply any configuration, just uncomment the lines you need. 7 | */ 8 | react { 9 | /* Folders */ 10 | // The root of your project, i.e. where "package.json" lives. Default is '..' 11 | // root = file("../") 12 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 13 | // reactNativeDir = file("../node_modules/react-native") 14 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 15 | // codegenDir = file("../node_modules/@react-native/codegen") 16 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 17 | // cliFile = file("../node_modules/react-native/cli.js") 18 | 19 | /* Variants */ 20 | // The list of variants to that are debuggable. For those we're going to 21 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 22 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 23 | // debuggableVariants = ["liteDebug", "prodDebug"] 24 | 25 | /* Bundling */ 26 | // A list containing the node command and its flags. Default is just 'node'. 27 | // nodeExecutableAndArgs = ["node"] 28 | // 29 | // The command to run when bundling. By default is 'bundle' 30 | // bundleCommand = "ram-bundle" 31 | // 32 | // The path to the CLI configuration file. Default is empty. 33 | // bundleConfig = file(../rn-cli.config.js) 34 | // 35 | // The name of the generated asset file containing your JS bundle 36 | // bundleAssetName = "MyApplication.android.bundle" 37 | // 38 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 39 | // entryFile = file("../js/MyApplication.android.js") 40 | // 41 | // A list of extra flags to pass to the 'bundle' commands. 42 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 43 | // extraPackagerArgs = [] 44 | 45 | /* Hermes Commands */ 46 | // The hermes compiler command to run. By default it is 'hermesc' 47 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 48 | // 49 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 50 | // hermesFlags = ["-O", "-output-source-map"] 51 | } 52 | 53 | /** 54 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 55 | */ 56 | def enableProguardInReleaseBuilds = false 57 | 58 | /** 59 | * The preferred build flavor of JavaScriptCore (JSC) 60 | * 61 | * For example, to use the international variant, you can use: 62 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 63 | * 64 | * The international variant includes ICU i18n library and necessary data 65 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 66 | * give correct results when using with locales other than en-US. Note that 67 | * this variant is about 6MiB larger per architecture than default. 68 | */ 69 | def jscFlavor = 'org.webkit:android-jsc:+' 70 | 71 | configurations.all { 72 | resolutionStrategy { 73 | eachDependency { 74 | if ((requested.group == "org.jetbrains.kotlin") && (requested.name.startsWith("kotlin-stdlib"))) { 75 | useVersion("1.8.0") 76 | } 77 | } 78 | } 79 | } 80 | 81 | android { 82 | ndkVersion rootProject.ext.ndkVersion 83 | 84 | compileSdkVersion rootProject.ext.compileSdkVersion 85 | 86 | namespace "com.example" 87 | defaultConfig { 88 | applicationId "com.example" 89 | minSdkVersion rootProject.ext.minSdkVersion 90 | targetSdkVersion rootProject.ext.targetSdkVersion 91 | versionCode 1 92 | versionName "1.0" 93 | ndk { 94 | abiFilters 'arm64-v8a' 95 | } 96 | } 97 | splits { 98 | abi { 99 | reset() 100 | // enable enableSeparateBuildPerCPUArchitecture 101 | universalApk false // If true, also generate a universal APK 102 | include "arm64-v8a" 103 | } 104 | } 105 | signingConfigs { 106 | debug { 107 | storeFile file('debug.keystore') 108 | storePassword 'android' 109 | keyAlias 'androiddebugkey' 110 | keyPassword 'android' 111 | } 112 | } 113 | buildTypes { 114 | debug { 115 | signingConfig signingConfigs.debug 116 | } 117 | release { 118 | // Caution! In production, you need to generate your own keystore file. 119 | // see https://reactnative.dev/docs/signed-apk-android. 120 | signingConfig signingConfigs.debug 121 | minifyEnabled enableProguardInReleaseBuilds 122 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 123 | } 124 | } 125 | } 126 | 127 | dependencies { 128 | // The version of react-native is set by the React Native Gradle Plugin 129 | implementation("com.facebook.react:react-android") 130 | 131 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 132 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 133 | exclude group:'com.squareup.okhttp3', module:'okhttp' 134 | } 135 | 136 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 137 | if (hermesEnabled.toBoolean()) { 138 | implementation("com.facebook.react:hermes-android") 139 | } else { 140 | implementation jscFlavor 141 | } 142 | } 143 | 144 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 145 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 33 | 36 | 39 | 42 | 45 | 48 | 51 | 52 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 75 | 76 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "example"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | import com.facebook.react.PackageList; 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactNativeHost; 10 | import com.facebook.soloader.SoLoader; 11 | import java.util.List; 12 | 13 | public class MainApplication extends Application implements ReactApplication { 14 | 15 | private final ReactNativeHost mReactNativeHost = 16 | new DefaultReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | @SuppressWarnings("UnnecessaryLocalVariable") 25 | List packages = new PackageList(this).getPackages(); 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages; 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | 36 | @Override 37 | protected boolean isNewArchEnabled() { 38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 39 | } 40 | 41 | @Override 42 | protected Boolean isHermesEnabled() { 43 | return BuildConfig.IS_HERMES_ENABLED; 44 | } 45 | }; 46 | 47 | @Override 48 | public ReactNativeHost getReactNativeHost() { 49 | return mReactNativeHost; 50 | } 51 | 52 | @Override 53 | public void onCreate() { 54 | super.onCreate(); 55 | SoLoader.init(this, /* native exopackage */ false); 56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 57 | // If you opted-in for the New Architecture, we load the native entry point for this app. 58 | DefaultNewArchitectureEntryPoint.load(); 59 | } 60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | Game view 4 | 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/app/src/release/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 26 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | 13 | kotlinVersion = "1.8.0" 14 | } 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | dependencies { 20 | classpath("com.android.tools.build:gradle") 21 | classpath("com.facebook.react:react-native-gradle-plugin") 22 | } 23 | } 24 | 25 | allprojects { 26 | repositories { 27 | flatDir { 28 | dirs "${project(':unityLibrary').projectDir}/libs" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.182.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=arm64-v8a 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=true 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | 46 | unityStreamingAssets=.unity3d 47 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azesmway/react-native-unity/7bed75580a69acdaa9a7ce8ac49746fa2110332e/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | # Collect all arguments for the java command; 201 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 202 | # shell script including quotes and variable substitutions, so put them in 203 | # double quotes to make sure that they get re-expanded; and 204 | # * put everything else in single quotes, so that it's not re-expanded. 205 | 206 | set -- \ 207 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 208 | -classpath "$CLASSPATH" \ 209 | org.gradle.wrapper.GradleWrapperMain \ 210 | "$@" 211 | 212 | # Stop when "xargs" is not available. 213 | if ! command -v xargs >/dev/null 2>&1 214 | then 215 | die "xargs is not available" 216 | fi 217 | 218 | # Use "xargs" to parse quoted args. 219 | # 220 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 221 | # 222 | # In Bash we could simply go: 223 | # 224 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 225 | # set -- "${ARGS[@]}" "$@" 226 | # 227 | # but POSIX shell has neither arrays nor command substitution, so instead we 228 | # post-process each arg (as a line of input to sed) to backslash-escape any 229 | # character that might be a shell metacharacter, then use eval to reverse 230 | # that process (while maintaining the separation between arguments), and wrap 231 | # the whole thing up as a single "set" statement. 232 | # 233 | # This will of course break if any of these variables contains a newline or 234 | # an unmatched quote. 235 | # 236 | 237 | eval "set -- $( 238 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 239 | xargs -n1 | 240 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 241 | tr '\n' ' ' 242 | )" '"$@"' 243 | 244 | exec "$JAVACMD" "$@" 245 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | 3 | include ':unityLibrary' 4 | project(':unityLibrary').projectDir=new File('..\\unity\\builds\\android\\unityLibrary') 5 | 6 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 7 | include ':app' 8 | includeBuild('../node_modules/@react-native/gradle-plugin') 9 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } 5 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset', '@babel/preset-typescript'], 3 | env: { 4 | production: {} 5 | }, 6 | plugins: [ 7 | 'module:react-native-dotenv', 8 | '@babel/plugin-proposal-export-namespace-from', 9 | [ 10 | 'module-resolver', 11 | { 12 | root: ['./src'], 13 | alias: { '^~(.+)': './src/\\1' }, 14 | extensions: ['.ios.js', '.android.js', '.ios.ts', '.android.ts', '.ios.tsx', '.android.tsx', '.js', '.ts', '.tsx', '.json'] 15 | } 16 | ], 17 | 'react-native-reanimated/plugin' 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import { AppRegistry } from 'react-native' 6 | 7 | import { name as appName } from './app.json' 8 | import App from './src/App' 9 | 10 | AppRegistry.registerComponent(appName, () => App) 11 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/ios/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, min_ios_version_supported 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 = FlipperConfiguration.disabled 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 | target 'example' do 29 | config = use_native_modules! 30 | 31 | # Flags change depending on the env values. 32 | flags = get_default_flags() 33 | 34 | use_react_native!( 35 | :path => config[:reactNativePath], 36 | # Hermes is now enabled by default. Disable by setting this flag to false. 37 | :hermes_enabled => flags[:hermes_enabled], 38 | :fabric_enabled => flags[:fabric_enabled], 39 | # Enables Flipper. 40 | # 41 | # Note that if you have use_frameworks! enabled, Flipper will not work and 42 | # you should disable the next line. 43 | :flipper_configuration => flipper_config, 44 | # An absolute path to your application root. 45 | :app_path => "#{Pod::Config.instance.installation_root}/.." 46 | ) 47 | 48 | target 'exampleTests' do 49 | inherit! :complete 50 | # Pods for testing 51 | end 52 | 53 | post_install do |installer| 54 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 55 | react_native_post_install( 56 | installer, 57 | config[:reactNativePath], 58 | :mac_catalyst_enabled => false 59 | ) 60 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost (1.76.0) 3 | - DoubleConversion (1.1.6) 4 | - FBLazyVector (0.72.7) 5 | - FBReactNativeSpec (0.72.7): 6 | - RCT-Folly (= 2021.07.22.00) 7 | - RCTRequired (= 0.72.7) 8 | - RCTTypeSafety (= 0.72.7) 9 | - React-Core (= 0.72.7) 10 | - React-jsi (= 0.72.7) 11 | - ReactCommon/turbomodule/core (= 0.72.7) 12 | - fmt (6.2.1) 13 | - glog (0.3.5) 14 | - hermes-engine (0.72.7): 15 | - hermes-engine/Pre-built (= 0.72.7) 16 | - hermes-engine/Pre-built (0.72.7) 17 | - libevent (2.1.12) 18 | - RCT-Folly (2021.07.22.00): 19 | - boost 20 | - DoubleConversion 21 | - fmt (~> 6.2.1) 22 | - glog 23 | - RCT-Folly/Default (= 2021.07.22.00) 24 | - RCT-Folly/Default (2021.07.22.00): 25 | - boost 26 | - DoubleConversion 27 | - fmt (~> 6.2.1) 28 | - glog 29 | - RCT-Folly/Futures (2021.07.22.00): 30 | - boost 31 | - DoubleConversion 32 | - fmt (~> 6.2.1) 33 | - glog 34 | - libevent 35 | - RCTRequired (0.72.7) 36 | - RCTTypeSafety (0.72.7): 37 | - FBLazyVector (= 0.72.7) 38 | - RCTRequired (= 0.72.7) 39 | - React-Core (= 0.72.7) 40 | - React (0.72.7): 41 | - React-Core (= 0.72.7) 42 | - React-Core/DevSupport (= 0.72.7) 43 | - React-Core/RCTWebSocket (= 0.72.7) 44 | - React-RCTActionSheet (= 0.72.7) 45 | - React-RCTAnimation (= 0.72.7) 46 | - React-RCTBlob (= 0.72.7) 47 | - React-RCTImage (= 0.72.7) 48 | - React-RCTLinking (= 0.72.7) 49 | - React-RCTNetwork (= 0.72.7) 50 | - React-RCTSettings (= 0.72.7) 51 | - React-RCTText (= 0.72.7) 52 | - React-RCTVibration (= 0.72.7) 53 | - React-callinvoker (0.72.7) 54 | - React-Codegen (0.72.7): 55 | - DoubleConversion 56 | - FBReactNativeSpec 57 | - glog 58 | - hermes-engine 59 | - RCT-Folly 60 | - RCTRequired 61 | - RCTTypeSafety 62 | - React-Core 63 | - React-jsi 64 | - React-jsiexecutor 65 | - React-NativeModulesApple 66 | - React-rncore 67 | - ReactCommon/turbomodule/bridging 68 | - ReactCommon/turbomodule/core 69 | - React-Core (0.72.7): 70 | - glog 71 | - hermes-engine 72 | - RCT-Folly (= 2021.07.22.00) 73 | - React-Core/Default (= 0.72.7) 74 | - React-cxxreact 75 | - React-hermes 76 | - React-jsi 77 | - React-jsiexecutor 78 | - React-perflogger 79 | - React-runtimeexecutor 80 | - React-utils 81 | - SocketRocket (= 0.6.1) 82 | - Yoga 83 | - React-Core/CoreModulesHeaders (0.72.7): 84 | - glog 85 | - hermes-engine 86 | - RCT-Folly (= 2021.07.22.00) 87 | - React-Core/Default 88 | - React-cxxreact 89 | - React-hermes 90 | - React-jsi 91 | - React-jsiexecutor 92 | - React-perflogger 93 | - React-runtimeexecutor 94 | - React-utils 95 | - SocketRocket (= 0.6.1) 96 | - Yoga 97 | - React-Core/Default (0.72.7): 98 | - glog 99 | - hermes-engine 100 | - RCT-Folly (= 2021.07.22.00) 101 | - React-cxxreact 102 | - React-hermes 103 | - React-jsi 104 | - React-jsiexecutor 105 | - React-perflogger 106 | - React-runtimeexecutor 107 | - React-utils 108 | - SocketRocket (= 0.6.1) 109 | - Yoga 110 | - React-Core/DevSupport (0.72.7): 111 | - glog 112 | - hermes-engine 113 | - RCT-Folly (= 2021.07.22.00) 114 | - React-Core/Default (= 0.72.7) 115 | - React-Core/RCTWebSocket (= 0.72.7) 116 | - React-cxxreact 117 | - React-hermes 118 | - React-jsi 119 | - React-jsiexecutor 120 | - React-jsinspector (= 0.72.7) 121 | - React-perflogger 122 | - React-runtimeexecutor 123 | - React-utils 124 | - SocketRocket (= 0.6.1) 125 | - Yoga 126 | - React-Core/RCTActionSheetHeaders (0.72.7): 127 | - glog 128 | - hermes-engine 129 | - RCT-Folly (= 2021.07.22.00) 130 | - React-Core/Default 131 | - React-cxxreact 132 | - React-hermes 133 | - React-jsi 134 | - React-jsiexecutor 135 | - React-perflogger 136 | - React-runtimeexecutor 137 | - React-utils 138 | - SocketRocket (= 0.6.1) 139 | - Yoga 140 | - React-Core/RCTAnimationHeaders (0.72.7): 141 | - glog 142 | - hermes-engine 143 | - RCT-Folly (= 2021.07.22.00) 144 | - React-Core/Default 145 | - React-cxxreact 146 | - React-hermes 147 | - React-jsi 148 | - React-jsiexecutor 149 | - React-perflogger 150 | - React-runtimeexecutor 151 | - React-utils 152 | - SocketRocket (= 0.6.1) 153 | - Yoga 154 | - React-Core/RCTBlobHeaders (0.72.7): 155 | - glog 156 | - hermes-engine 157 | - RCT-Folly (= 2021.07.22.00) 158 | - React-Core/Default 159 | - React-cxxreact 160 | - React-hermes 161 | - React-jsi 162 | - React-jsiexecutor 163 | - React-perflogger 164 | - React-runtimeexecutor 165 | - React-utils 166 | - SocketRocket (= 0.6.1) 167 | - Yoga 168 | - React-Core/RCTImageHeaders (0.72.7): 169 | - glog 170 | - hermes-engine 171 | - RCT-Folly (= 2021.07.22.00) 172 | - React-Core/Default 173 | - React-cxxreact 174 | - React-hermes 175 | - React-jsi 176 | - React-jsiexecutor 177 | - React-perflogger 178 | - React-runtimeexecutor 179 | - React-utils 180 | - SocketRocket (= 0.6.1) 181 | - Yoga 182 | - React-Core/RCTLinkingHeaders (0.72.7): 183 | - glog 184 | - hermes-engine 185 | - RCT-Folly (= 2021.07.22.00) 186 | - React-Core/Default 187 | - React-cxxreact 188 | - React-hermes 189 | - React-jsi 190 | - React-jsiexecutor 191 | - React-perflogger 192 | - React-runtimeexecutor 193 | - React-utils 194 | - SocketRocket (= 0.6.1) 195 | - Yoga 196 | - React-Core/RCTNetworkHeaders (0.72.7): 197 | - glog 198 | - hermes-engine 199 | - RCT-Folly (= 2021.07.22.00) 200 | - React-Core/Default 201 | - React-cxxreact 202 | - React-hermes 203 | - React-jsi 204 | - React-jsiexecutor 205 | - React-perflogger 206 | - React-runtimeexecutor 207 | - React-utils 208 | - SocketRocket (= 0.6.1) 209 | - Yoga 210 | - React-Core/RCTSettingsHeaders (0.72.7): 211 | - glog 212 | - hermes-engine 213 | - RCT-Folly (= 2021.07.22.00) 214 | - React-Core/Default 215 | - React-cxxreact 216 | - React-hermes 217 | - React-jsi 218 | - React-jsiexecutor 219 | - React-perflogger 220 | - React-runtimeexecutor 221 | - React-utils 222 | - SocketRocket (= 0.6.1) 223 | - Yoga 224 | - React-Core/RCTTextHeaders (0.72.7): 225 | - glog 226 | - hermes-engine 227 | - RCT-Folly (= 2021.07.22.00) 228 | - React-Core/Default 229 | - React-cxxreact 230 | - React-hermes 231 | - React-jsi 232 | - React-jsiexecutor 233 | - React-perflogger 234 | - React-runtimeexecutor 235 | - React-utils 236 | - SocketRocket (= 0.6.1) 237 | - Yoga 238 | - React-Core/RCTVibrationHeaders (0.72.7): 239 | - glog 240 | - hermes-engine 241 | - RCT-Folly (= 2021.07.22.00) 242 | - React-Core/Default 243 | - React-cxxreact 244 | - React-hermes 245 | - React-jsi 246 | - React-jsiexecutor 247 | - React-perflogger 248 | - React-runtimeexecutor 249 | - React-utils 250 | - SocketRocket (= 0.6.1) 251 | - Yoga 252 | - React-Core/RCTWebSocket (0.72.7): 253 | - glog 254 | - hermes-engine 255 | - RCT-Folly (= 2021.07.22.00) 256 | - React-Core/Default (= 0.72.7) 257 | - React-cxxreact 258 | - React-hermes 259 | - React-jsi 260 | - React-jsiexecutor 261 | - React-perflogger 262 | - React-runtimeexecutor 263 | - React-utils 264 | - SocketRocket (= 0.6.1) 265 | - Yoga 266 | - React-CoreModules (0.72.7): 267 | - RCT-Folly (= 2021.07.22.00) 268 | - RCTTypeSafety (= 0.72.7) 269 | - React-Codegen (= 0.72.7) 270 | - React-Core/CoreModulesHeaders (= 0.72.7) 271 | - React-jsi (= 0.72.7) 272 | - React-RCTBlob 273 | - React-RCTImage (= 0.72.7) 274 | - ReactCommon/turbomodule/core (= 0.72.7) 275 | - SocketRocket (= 0.6.1) 276 | - React-cxxreact (0.72.7): 277 | - boost (= 1.76.0) 278 | - DoubleConversion 279 | - glog 280 | - hermes-engine 281 | - RCT-Folly (= 2021.07.22.00) 282 | - React-callinvoker (= 0.72.7) 283 | - React-debug (= 0.72.7) 284 | - React-jsi (= 0.72.7) 285 | - React-jsinspector (= 0.72.7) 286 | - React-logger (= 0.72.7) 287 | - React-perflogger (= 0.72.7) 288 | - React-runtimeexecutor (= 0.72.7) 289 | - React-debug (0.72.7) 290 | - React-hermes (0.72.7): 291 | - DoubleConversion 292 | - glog 293 | - hermes-engine 294 | - RCT-Folly (= 2021.07.22.00) 295 | - RCT-Folly/Futures (= 2021.07.22.00) 296 | - React-cxxreact (= 0.72.7) 297 | - React-jsi 298 | - React-jsiexecutor (= 0.72.7) 299 | - React-jsinspector (= 0.72.7) 300 | - React-perflogger (= 0.72.7) 301 | - React-jsi (0.72.7): 302 | - boost (= 1.76.0) 303 | - DoubleConversion 304 | - glog 305 | - hermes-engine 306 | - RCT-Folly (= 2021.07.22.00) 307 | - React-jsiexecutor (0.72.7): 308 | - DoubleConversion 309 | - glog 310 | - hermes-engine 311 | - RCT-Folly (= 2021.07.22.00) 312 | - React-cxxreact (= 0.72.7) 313 | - React-jsi (= 0.72.7) 314 | - React-perflogger (= 0.72.7) 315 | - React-jsinspector (0.72.7) 316 | - React-logger (0.72.7): 317 | - glog 318 | - react-native-safe-area-context (4.7.4): 319 | - React-Core 320 | - react-native-unity (0.4.0): 321 | - React-Core 322 | - React-NativeModulesApple (0.72.7): 323 | - hermes-engine 324 | - React-callinvoker 325 | - React-Core 326 | - React-cxxreact 327 | - React-jsi 328 | - React-runtimeexecutor 329 | - ReactCommon/turbomodule/bridging 330 | - ReactCommon/turbomodule/core 331 | - React-perflogger (0.72.7) 332 | - React-RCTActionSheet (0.72.7): 333 | - React-Core/RCTActionSheetHeaders (= 0.72.7) 334 | - React-RCTAnimation (0.72.7): 335 | - RCT-Folly (= 2021.07.22.00) 336 | - RCTTypeSafety (= 0.72.7) 337 | - React-Codegen (= 0.72.7) 338 | - React-Core/RCTAnimationHeaders (= 0.72.7) 339 | - React-jsi (= 0.72.7) 340 | - ReactCommon/turbomodule/core (= 0.72.7) 341 | - React-RCTAppDelegate (0.72.7): 342 | - RCT-Folly 343 | - RCTRequired 344 | - RCTTypeSafety 345 | - React-Core 346 | - React-CoreModules 347 | - React-hermes 348 | - React-NativeModulesApple 349 | - React-RCTImage 350 | - React-RCTNetwork 351 | - React-runtimescheduler 352 | - ReactCommon/turbomodule/core 353 | - React-RCTBlob (0.72.7): 354 | - hermes-engine 355 | - RCT-Folly (= 2021.07.22.00) 356 | - React-Codegen (= 0.72.7) 357 | - React-Core/RCTBlobHeaders (= 0.72.7) 358 | - React-Core/RCTWebSocket (= 0.72.7) 359 | - React-jsi (= 0.72.7) 360 | - React-RCTNetwork (= 0.72.7) 361 | - ReactCommon/turbomodule/core (= 0.72.7) 362 | - React-RCTImage (0.72.7): 363 | - RCT-Folly (= 2021.07.22.00) 364 | - RCTTypeSafety (= 0.72.7) 365 | - React-Codegen (= 0.72.7) 366 | - React-Core/RCTImageHeaders (= 0.72.7) 367 | - React-jsi (= 0.72.7) 368 | - React-RCTNetwork (= 0.72.7) 369 | - ReactCommon/turbomodule/core (= 0.72.7) 370 | - React-RCTLinking (0.72.7): 371 | - React-Codegen (= 0.72.7) 372 | - React-Core/RCTLinkingHeaders (= 0.72.7) 373 | - React-jsi (= 0.72.7) 374 | - ReactCommon/turbomodule/core (= 0.72.7) 375 | - React-RCTNetwork (0.72.7): 376 | - RCT-Folly (= 2021.07.22.00) 377 | - RCTTypeSafety (= 0.72.7) 378 | - React-Codegen (= 0.72.7) 379 | - React-Core/RCTNetworkHeaders (= 0.72.7) 380 | - React-jsi (= 0.72.7) 381 | - ReactCommon/turbomodule/core (= 0.72.7) 382 | - React-RCTSettings (0.72.7): 383 | - RCT-Folly (= 2021.07.22.00) 384 | - RCTTypeSafety (= 0.72.7) 385 | - React-Codegen (= 0.72.7) 386 | - React-Core/RCTSettingsHeaders (= 0.72.7) 387 | - React-jsi (= 0.72.7) 388 | - ReactCommon/turbomodule/core (= 0.72.7) 389 | - React-RCTText (0.72.7): 390 | - React-Core/RCTTextHeaders (= 0.72.7) 391 | - React-RCTVibration (0.72.7): 392 | - RCT-Folly (= 2021.07.22.00) 393 | - React-Codegen (= 0.72.7) 394 | - React-Core/RCTVibrationHeaders (= 0.72.7) 395 | - React-jsi (= 0.72.7) 396 | - ReactCommon/turbomodule/core (= 0.72.7) 397 | - React-rncore (0.72.7) 398 | - React-runtimeexecutor (0.72.7): 399 | - React-jsi (= 0.72.7) 400 | - React-runtimescheduler (0.72.7): 401 | - glog 402 | - hermes-engine 403 | - RCT-Folly (= 2021.07.22.00) 404 | - React-callinvoker 405 | - React-debug 406 | - React-jsi 407 | - React-runtimeexecutor 408 | - React-utils (0.72.7): 409 | - glog 410 | - RCT-Folly (= 2021.07.22.00) 411 | - React-debug 412 | - ReactCommon/turbomodule/bridging (0.72.7): 413 | - DoubleConversion 414 | - glog 415 | - hermes-engine 416 | - RCT-Folly (= 2021.07.22.00) 417 | - React-callinvoker (= 0.72.7) 418 | - React-cxxreact (= 0.72.7) 419 | - React-jsi (= 0.72.7) 420 | - React-logger (= 0.72.7) 421 | - React-perflogger (= 0.72.7) 422 | - ReactCommon/turbomodule/core (0.72.7): 423 | - DoubleConversion 424 | - glog 425 | - hermes-engine 426 | - RCT-Folly (= 2021.07.22.00) 427 | - React-callinvoker (= 0.72.7) 428 | - React-cxxreact (= 0.72.7) 429 | - React-jsi (= 0.72.7) 430 | - React-logger (= 0.72.7) 431 | - React-perflogger (= 0.72.7) 432 | - RNReanimated (3.5.4): 433 | - DoubleConversion 434 | - FBLazyVector 435 | - glog 436 | - hermes-engine 437 | - RCT-Folly 438 | - RCTRequired 439 | - RCTTypeSafety 440 | - React-callinvoker 441 | - React-Core 442 | - React-Core/DevSupport 443 | - React-Core/RCTWebSocket 444 | - React-CoreModules 445 | - React-cxxreact 446 | - React-hermes 447 | - React-jsi 448 | - React-jsiexecutor 449 | - React-jsinspector 450 | - React-RCTActionSheet 451 | - React-RCTAnimation 452 | - React-RCTAppDelegate 453 | - React-RCTBlob 454 | - React-RCTImage 455 | - React-RCTLinking 456 | - React-RCTNetwork 457 | - React-RCTSettings 458 | - React-RCTText 459 | - ReactCommon/turbomodule/core 460 | - Yoga 461 | - RNScreens (3.27.0): 462 | - RCT-Folly (= 2021.07.22.00) 463 | - React-Core 464 | - SocketRocket (0.6.1) 465 | - Yoga (1.14.0) 466 | 467 | DEPENDENCIES: 468 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 469 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 470 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 471 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 472 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 473 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 474 | - libevent (~> 2.1.12) 475 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 476 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 477 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 478 | - React (from `../node_modules/react-native/`) 479 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 480 | - React-Codegen (from `build/generated/ios`) 481 | - React-Core (from `../node_modules/react-native/`) 482 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 483 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 484 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 485 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) 486 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 487 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 488 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 489 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 490 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 491 | - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) 492 | - "react-native-unity (from `../node_modules/@azesmway/react-native-unity`)" 493 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) 494 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 495 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 496 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 497 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 498 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 499 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 500 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 501 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 502 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 503 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 504 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 505 | - React-rncore (from `../node_modules/react-native/ReactCommon`) 506 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 507 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) 508 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) 509 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 510 | - RNReanimated (from `../node_modules/react-native-reanimated`) 511 | - RNScreens (from `../node_modules/react-native-screens`) 512 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 513 | 514 | SPEC REPOS: 515 | trunk: 516 | - fmt 517 | - libevent 518 | - SocketRocket 519 | 520 | EXTERNAL SOURCES: 521 | boost: 522 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 523 | DoubleConversion: 524 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 525 | FBLazyVector: 526 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 527 | FBReactNativeSpec: 528 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 529 | glog: 530 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 531 | hermes-engine: 532 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 533 | :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 534 | RCT-Folly: 535 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 536 | RCTRequired: 537 | :path: "../node_modules/react-native/Libraries/RCTRequired" 538 | RCTTypeSafety: 539 | :path: "../node_modules/react-native/Libraries/TypeSafety" 540 | React: 541 | :path: "../node_modules/react-native/" 542 | React-callinvoker: 543 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 544 | React-Codegen: 545 | :path: build/generated/ios 546 | React-Core: 547 | :path: "../node_modules/react-native/" 548 | React-CoreModules: 549 | :path: "../node_modules/react-native/React/CoreModules" 550 | React-cxxreact: 551 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 552 | React-debug: 553 | :path: "../node_modules/react-native/ReactCommon/react/debug" 554 | React-hermes: 555 | :path: "../node_modules/react-native/ReactCommon/hermes" 556 | React-jsi: 557 | :path: "../node_modules/react-native/ReactCommon/jsi" 558 | React-jsiexecutor: 559 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 560 | React-jsinspector: 561 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 562 | React-logger: 563 | :path: "../node_modules/react-native/ReactCommon/logger" 564 | react-native-safe-area-context: 565 | :path: "../node_modules/react-native-safe-area-context" 566 | react-native-unity: 567 | :path: "../node_modules/@azesmway/react-native-unity" 568 | React-NativeModulesApple: 569 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" 570 | React-perflogger: 571 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 572 | React-RCTActionSheet: 573 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 574 | React-RCTAnimation: 575 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 576 | React-RCTAppDelegate: 577 | :path: "../node_modules/react-native/Libraries/AppDelegate" 578 | React-RCTBlob: 579 | :path: "../node_modules/react-native/Libraries/Blob" 580 | React-RCTImage: 581 | :path: "../node_modules/react-native/Libraries/Image" 582 | React-RCTLinking: 583 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 584 | React-RCTNetwork: 585 | :path: "../node_modules/react-native/Libraries/Network" 586 | React-RCTSettings: 587 | :path: "../node_modules/react-native/Libraries/Settings" 588 | React-RCTText: 589 | :path: "../node_modules/react-native/Libraries/Text" 590 | React-RCTVibration: 591 | :path: "../node_modules/react-native/Libraries/Vibration" 592 | React-rncore: 593 | :path: "../node_modules/react-native/ReactCommon" 594 | React-runtimeexecutor: 595 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 596 | React-runtimescheduler: 597 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" 598 | React-utils: 599 | :path: "../node_modules/react-native/ReactCommon/react/utils" 600 | ReactCommon: 601 | :path: "../node_modules/react-native/ReactCommon" 602 | RNReanimated: 603 | :path: "../node_modules/react-native-reanimated" 604 | RNScreens: 605 | :path: "../node_modules/react-native-screens" 606 | Yoga: 607 | :path: "../node_modules/react-native/ReactCommon/yoga" 608 | 609 | SPEC CHECKSUMS: 610 | boost: 57d2868c099736d80fcd648bf211b4431e51a558 611 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 612 | FBLazyVector: 5fbbff1d7734827299274638deb8ba3024f6c597 613 | FBReactNativeSpec: 638095fe8a01506634d77b260ef8a322019ac671 614 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 615 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 616 | hermes-engine: 9180d43df05c1ed658a87cc733dc3044cf90c00a 617 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 618 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 619 | RCTRequired: 83bca1c184feb4d2e51c72c8369b83d641443f95 620 | RCTTypeSafety: 13c4a87a16d7db6cd66006ce9759f073402ef85b 621 | React: e67aa9f99957c7611c392b5e49355d877d6525e2 622 | React-callinvoker: 2790c09d964c2e5404b5410cde91b152e3746b7b 623 | React-Codegen: e6e05e105ca7cdb990f4d609985a2a689d8d0653 624 | React-Core: 9283f1e7d0d5e3d33ad298547547b1b43912534c 625 | React-CoreModules: 6312c9b2fec4329d9ae6a2b8c350032d1664c51b 626 | React-cxxreact: 7da72565656c8ac7f97c9a031d0b199bbdec0640 627 | React-debug: 4accb2b9dc09b575206d2c42f4082990a52ae436 628 | React-hermes: 1299a94f255f59a72d5baa54a2ca2e1eee104947 629 | React-jsi: 2208de64c3a41714ac04e86975386fc49116ea13 630 | React-jsiexecutor: c49502e5d02112247ee4526bc3ccfc891ae3eb9b 631 | React-jsinspector: 8baadae51f01d867c3921213a25ab78ab4fbcd91 632 | React-logger: 8edc785c47c8686c7962199a307015e2ce9a0e4f 633 | react-native-safe-area-context: 2cd91d532de12acdb0a9cbc8d43ac72a8e4c897c 634 | react-native-unity: 1f1d89026c30330545b146123b7a7a0ffe7a3843 635 | React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a 636 | React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a 637 | React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d 638 | React-RCTAnimation: 4b3cc6a29474bc0d78c4f04b52ab59bf760e8a9b 639 | React-RCTAppDelegate: 89b015b29885109addcabecdf3b2e833905437c7 640 | React-RCTBlob: 3e23dcbe6638897b5605e46d0d62955d78e8d27b 641 | React-RCTImage: 8a5d339d614a90a183fc1b8b6a7eb44e2e703943 642 | React-RCTLinking: b37dfbf646d77c326f9eae094b1fcd575b1c24c7 643 | React-RCTNetwork: 8bed9b2461c7d8a7d14e63df9b16181c448beebc 644 | React-RCTSettings: 506a5f09a455123a8873801b70aa7b4010b76b01 645 | React-RCTText: 3c71ecaad8ee010b79632ea2590f86c02f5cce17 646 | React-RCTVibration: d1b78ca38f61ea4b3e9ebb2ddbd0b5662631d99b 647 | React-rncore: bfc2f6568b6fecbae6f2f774e95c60c3c9e95bf2 648 | React-runtimeexecutor: 47b0a2d5bbb416db65ef881a6f7bdcfefa0001ab 649 | React-runtimescheduler: 7649c3b46c8dee1853691ecf60146a16ae59253c 650 | React-utils: 56838edeaaf651220d1e53cd0b8934fb8ce68415 651 | ReactCommon: 5f704096ccf7733b390f59043b6fa9cc180ee4f6 652 | RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87 653 | RNScreens: 3c2d122f5e08c192e254c510b212306da97d2581 654 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 655 | Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 656 | 657 | PODFILE CHECKSUM: b8f41d35042dd0b300ea17543a9f95b281f136ae 658 | 659 | COCOAPODS: 1.15.2 660 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"example"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationAlwaysAndWhenInUseUsageDescription 39 | Приложение будет использовать локацию для прокладки маршрутов для туров. 40 | NSLocationAlwaysUsageDescription 41 | Приложение будет использовать локацию для прокладки маршрутов для туров. 42 | NSLocationTemporaryUsageDescriptionDictionary 43 | 44 | wantAccurateLocation 45 | Приложение будет использовать локацию для прокладки маршрутов для туров. 46 | 47 | NSLocationWhenInUseUsageDescription 48 | Приложение будет использовать локацию для прокладки маршрутов для туров. 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | NSCameraUsageDescription 62 | sdfsdfbd jsgdjfg sjhfd sjhdf hsjg df 63 | UIViewControllerBasedStatusBarAppearance 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /example/ios/example/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /example/ios/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /example/ios/exampleTests/exampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface exampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation exampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | clearMocks: true, 3 | 4 | globals: { 5 | 'ts-jest': { 6 | tsconfig: 'tsconfig.spec.json', // as specified by ts-jest 7 | babelConfig: true 8 | } 9 | }, 10 | 11 | moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'node'], 12 | 13 | moduleNameMapper: { 14 | '^.+.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2|webp)$': 'jest-transform-stub' 15 | }, 16 | 17 | preset: 'react-native', 18 | 19 | testEnvironment: 'jsdom', 20 | 21 | transform: { 22 | '^.+\\.jsx$': 'babel-jest', 23 | '^.+\\.tsx?$': 'ts-jest', 24 | '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub' 25 | }, 26 | 27 | transformIgnorePatterns: ['/node_modules/(?!(@react-native|react-native)).*/'], 28 | 29 | verbose: true 30 | } 31 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config') 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {} 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config) 12 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@azesmway/react-native-unity": "^0.4.0", 14 | "@react-navigation/native": "^6.1.9", 15 | "@react-navigation/native-stack": "^6.9.17", 16 | "react": "18.2.0", 17 | "react-native": "0.72.7", 18 | "react-native-reanimated": "^3.5.4", 19 | "react-native-safe-area-context": "^4.7.4", 20 | "react-native-screens": "^3.27.0" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.23.3", 24 | "@babel/plugin-proposal-class-properties": "^7.18.6", 25 | "@babel/plugin-proposal-export-namespace-from": "^7.18.9", 26 | "@babel/plugin-proposal-private-methods": "^7.18.6", 27 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 28 | "@babel/plugin-syntax-jsx": "^7.23.3", 29 | "@babel/plugin-transform-flow-strip-types": "^7.23.3", 30 | "@babel/preset-react": "^7.23.3", 31 | "@babel/preset-typescript": "^7.23.3", 32 | "@babel/runtime": "^7.23.2", 33 | "@react-native/eslint-config": "^0.74.0", 34 | "@react-native/metro-config": "^0.74.0", 35 | "@tsconfig/react-native": "^3.0.2", 36 | "@types/i18n-js": "^3.8.8", 37 | "@types/jest": "^29.5.8", 38 | "@types/lodash": "^4.14.201", 39 | "@types/metro-config": "^0.76.3", 40 | "@types/react": "^18.2.37", 41 | "@types/react-native": "^0.72.6", 42 | "@types/react-native-actionsheet": "^2.4.6", 43 | "@types/react-test-renderer": "^18.0.6", 44 | "@typescript-eslint/eslint-plugin": "^6.10.0", 45 | "@typescript-eslint/parser": "^6.10.0", 46 | "babel-jest": "^29.7.0", 47 | "babel-plugin-module-resolver": "^5.0.0", 48 | "babel-plugin-transform-remove-console": "^6.9.4", 49 | "eslint": "8.53.0", 50 | "eslint-plugin-ft-flow": "^3.0.1", 51 | "eslint-plugin-jest": "^27.6.0", 52 | "eslint-plugin-prettier": "5.0.1", 53 | "eslint-plugin-simple-import-sort": "^10.0.0", 54 | "husky": "^8.0.3", 55 | "jest": "^29.7.0", 56 | "jest-environment-jsdom": "^29.7.0", 57 | "jest-transform-stub": "^2.0.0", 58 | "metro-react-native-babel-preset": "^0.77.0", 59 | "npm-check-updates": "^16.14.6", 60 | "patch-package": "^8.0.0", 61 | "prettier": "^3.0.3", 62 | "react-native-dotenv": "^3.4.9", 63 | "react-test-renderer": "18.2.0", 64 | "ts-interface-builder": "^0.3.3", 65 | "ts-jest": "^29.1.1", 66 | "typescript": "^5.2.2" 67 | }, 68 | "engines": { 69 | "node": ">=16" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { NavigationContainer } from '@react-navigation/native' 2 | import { createNativeStackNavigator } from '@react-navigation/native-stack' 3 | import React from 'react' 4 | 5 | import Main from './Main' 6 | import Unity from './Unity' 7 | 8 | const Stack = createNativeStackNavigator() 9 | 10 | export default function App() { 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | ) 19 | } 20 | -------------------------------------------------------------------------------- /example/src/Main.tsx: -------------------------------------------------------------------------------- 1 | import { StackActions, useNavigation } from '@react-navigation/native' 2 | import * as React from 'react' 3 | import { Button, Text, View } from 'react-native' 4 | 5 | const Main = () => { 6 | const navigation = useNavigation() 7 | 8 | return ( 9 | 10 | Unity Screen 11 |