1
0
mirror of https://gitcode.com/gh_mirrors/re/react-native-pushy.git synced 2025-09-16 13:01:38 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee

Compare commits

...

97 Commits

Author SHA1 Message Date
sunnylqm
a564770597 v9.2.0 2024-07-27 21:59:25 +08:00
sunnylqm
7229f8847a chore: indent 2023-12-31 17:05:37 +08:00
sunnylqm
1daafb0142 v9.1.6 2023-12-20 10:38:18 +08:00
sunnylqm
c1679a4cea fix: support gradle namespace 2023-12-20 10:37:43 +08:00
sunnylqm
7ab7dffb0f v9.1.5 2023-12-12 23:08:11 +08:00
sunnylqm
8622935bdf fix: zipslip 2023-12-12 23:07:11 +08:00
sunnylqm
b747b1f356 v9.1.4 2023-10-30 22:58:41 +08:00
sunnylqm
7752581470 chore: throttle switchversion 2023-10-30 22:58:09 +08:00
sunnylqm
33eb89d2a7 v9.1.3 2023-10-28 18:28:54 +08:00
sunnylqm
d111bf5a9c chore: rename onPushyEvents 2023-10-28 18:28:23 +08:00
sunnylqm
23346a5f1d v9.1.2 2023-10-28 17:26:19 +08:00
sunnylqm
5aca2104c2 fix: simpleUpdate for web 2023-10-28 17:25:54 +08:00
sunnylqm
fe0a05db3d v9.1.0 2023-10-28 17:01:54 +08:00
sunnylqm
2b287786ff chore: remove permissions 2023-10-28 14:37:26 +08:00
sunnylqm
7d128900cd feat: improve backup endpoints 2023-10-28 14:36:04 +08:00
sunnylqm
189e3ec78e v9.0.5 2023-09-24 21:18:11 +08:00
sunnylqm
821722165a v9.0.4 2023-09-15 16:16:48 +08:00
sunnylqm
6cb53ac655 fix: lastChecking 2023-09-15 16:16:13 +08:00
sunnylqm
7b9a24168a v9.0.3 2023-09-06 23:18:07 +08:00
sunnylqm
c6354bbedc fix: return type 2023-09-06 23:16:42 +08:00
sunnylqm
b53878c291 chore: cleanup 2023-09-06 22:56:41 +08:00
sunnylqm
ab01312f8d v9.0.2 2023-09-06 22:53:54 +08:00
sunnylqm
44784b6d3e feat: return cached result 2023-09-06 11:20:31 +08:00
sunnylqm
30c21fed91 v9.0.1 2023-09-05 22:50:53 +08:00
sunnylqm
15af7802ad fix: type 2023-09-05 22:47:47 +08:00
sunnylqm
8bed6ef979 chore: cleanup 2023-09-05 22:01:13 +08:00
Sunny Luo
7d03dc24b7 Update README.md 2023-09-02 23:02:15 +08:00
sunnylqm
18849ee441 v9.0.0 2023-09-02 22:54:26 +08:00
sunnylqm
3ba1df2020 revert ios bundle detect 2023-09-02 22:52:58 +08:00
sunnylqm
7152ef7304 v9.0.0-beta.3 2023-09-02 22:49:12 +08:00
sunnylqm
094eb3f267 chore: cleanup 2023-09-02 22:40:55 +08:00
sunnylqm
6d01ce5152 chore: cleanup 2023-09-02 22:35:45 +08:00
sunnylqm
8bf1fed3f8 v9.0.0-beta.2 2023-09-02 21:07:04 +08:00
sunnylqm
39c4a6d339 feat: onEvents 2023-08-31 19:24:00 +08:00
sunnylqm
f1e9244a14 v9.0.0-beta.0 2023-07-01 12:11:28 +08:00
Sunny Luo
546f287b6c Merge pull request #409 from bozaigao/master
ci: remove testHotUpdate workflows
2023-04-03 15:58:38 +08:00
steven
175e43d524 ci: remove testHotUpdate workflows 2023-04-03 15:48:02 +08:00
Sunny Luo
b200766aa3 Merge pull request #408 from bozaigao/master
添加Detox e2e测试功能
2023-04-03 15:28:33 +08:00
Sunny Luo
7e65457cc1 Update .gitignore 2023-04-03 15:28:19 +08:00
Sunny Luo
6c5ccd98b7 Delete Example/testHotUpdate/artifacts directory 2023-04-03 15:27:41 +08:00
steven
d7abd590b0 feat: CI测试 2023-04-03 11:21:15 +08:00
steven
ffb2bf4afa feat: CI测试 2023-04-03 11:18:31 +08:00
steven
94c177512e feat: CI测试 2023-04-03 10:30:12 +08:00
steven
a16a73e754 feat: CI测试 2023-04-03 10:28:04 +08:00
steven
40df51db0f feat: CI测试 2023-04-03 08:18:19 +08:00
steven
97fec1e79e feat: CI测试 2023-04-02 23:53:28 +08:00
steven
75b4447437 feat: CI测试 2023-04-02 23:05:16 +08:00
steven
f9c6a97a50 feat: CI测试 2023-04-02 15:35:25 +08:00
steven
90aa07cc55 feat: CI测试 2023-04-02 14:47:05 +08:00
steven
26cda39451 feat: CI测试 2023-04-02 13:25:58 +08:00
steven
3d5012fced feat: CI测试 2023-04-02 12:51:43 +08:00
steven
533696e34d feat: fix 2023-03-31 22:03:42 +08:00
steven
9c98aaa899 feat: fix 2023-03-31 22:01:53 +08:00
steven
706cd8c415 feat: fix 2023-03-31 22:01:16 +08:00
steven
e76747f7d3 feat: fix 2023-03-31 21:47:22 +08:00
steven
65a2477932 feat: fix 2023-03-31 21:42:13 +08:00
steven
581cd3310e feat: fix 2023-03-31 21:41:18 +08:00
steven
f24bfd6f2a feat: fix 2023-03-31 21:37:13 +08:00
steven
c57802e2d2 feat: fix 2023-03-31 21:35:25 +08:00
steven
ca4f363e6d feat: fix 2023-03-31 08:52:11 +08:00
steven
6fcfa0b505 feat: fix 2023-03-30 12:50:33 +08:00
steven
12edc1df7a feat: fix 2023-03-30 11:24:44 +08:00
steven
4acba40f6c feat: fix 2023-03-26 20:45:08 +08:00
steven
0adda18b50 feat: e2e测试 2023-03-18 14:43:17 +08:00
steven
6cd256b7f4 feat: e2e测试 2023-03-17 16:16:58 +08:00
steven
bd04badbe8 feat: project init 2023-03-16 21:45:04 +08:00
steven
f0c52b0acd feat: project init 2023-03-16 15:40:10 +08:00
steven
76e5c6c59b feat: project init 2023-03-16 14:45:36 +08:00
steven
d2f53e17c5 feat: project init 2023-03-16 13:45:26 +08:00
steven
a182c5d3c6 feat: project init 2023-03-16 12:19:50 +08:00
steven
4e4c686f4d feat: project init 2023-03-16 11:31:27 +08:00
steven
301243b502 feat: project init 2023-03-16 11:29:34 +08:00
steven
b23898ec48 feat: project init 2023-03-16 10:45:19 +08:00
steven
909788c6f6 feat: project init 2023-03-16 10:38:32 +08:00
steven
507576795c feat: project init 2023-03-16 10:34:47 +08:00
steven
48526430a1 feat: project init 2023-03-16 10:29:08 +08:00
steven
aaab2d77c8 feat: project init 2023-03-16 10:24:42 +08:00
steven
b4b8856ed2 feat: project init 2023-03-16 10:20:57 +08:00
steven
eb1c9ff5de feat: project init 2023-03-16 10:19:38 +08:00
steven
6f346d7990 feat: project init 2023-03-16 10:18:45 +08:00
steven
27c053a645 feat: project init 2023-03-16 10:17:08 +08:00
steven
55506483f9 feat: project init 2023-03-16 10:15:32 +08:00
steven
5f28b75abd feat: project init 2023-03-16 10:03:31 +08:00
steven
4bf921c82c feat: project init 2023-03-16 09:43:26 +08:00
steven
68cc6d3fad feat: project init 2023-03-16 09:06:07 +08:00
steven
63c4825006 feat: project init 2023-03-16 08:36:50 +08:00
steven
aa5f5b9340 feat: project init 2023-03-16 08:06:41 +08:00
steven
6216fdfd35 feat: project init 2023-03-16 07:58:13 +08:00
steven
1d11fc64a8 feat: project init 2023-03-16 07:49:44 +08:00
steven
87a2004b2b feat: project init 2023-03-15 23:28:02 +08:00
steven
92675ed37c feat: project init 2023-03-15 23:27:25 +08:00
Sunny Luo
992b17d25a Merge pull request #403 from bozaigao/master
fix: fix NativeEventEmitter warning
2023-02-20 18:21:00 +08:00
steven
d538782b01 fix: fix NativeEventEmitter warning 2023-02-20 14:36:08 +08:00
sunnylqm
d6c268f533 chore: some tweak 2023-02-20 13:03:12 +08:00
Sunny Luo
55879198e8 Merge pull request #402 from bozaigao/master
feat: support for new architecture
2023-02-20 11:01:03 +08:00
steven
f8115c3a85 fix: optimize 2023-02-19 21:14:03 +08:00
steven
e859900df6 feat: support for new architecture 2023-02-19 18:25:16 +08:00
120 changed files with 15859 additions and 3824 deletions

49
.github/workflows/e2e_android.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: e2e-android
on: push
jobs:
e2e-android:
runs-on: macos-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: .nvmrc
- name: Install Yarn dependencies
run: yarn --frozen-lockfile --prefer-offline
- name: Setup Java
uses: actions/setup-java@v3
with:
cache: gradle
distribution: temurin
java-version: 17
- name: Cache Detox build
id: cache-detox-build
uses: actions/cache@v3
with:
path: android/app/build
key: ${{ runner.os }}-detox-build
restore-keys: |
${{ runner.os }}-detox-build
- name: Detox build
run: yarn build:android-debug
- name: Get device name
id: device
run: node -e "console.log('AVD_NAME=' + require('./Example/testHotUpdate/.detoxrc').devices.emulator.device.avdName)" >> $GITHUB_OUTPUT
- name: Detox test
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 31
arch: x86_64
avd-name: ${{ steps.device.outputs.AVD_NAME }}
script: yarn test:android-debug

182
.github/workflows/e2e_ios.yml vendored Normal file
View File

@@ -0,0 +1,182 @@
name: Testing E2E iOS
on:
pull_request:
branches:
- '**'
paths-ignore:
- 'docs/**'
- 'website/**'
- '.spellcheck.dict.txt'
- '**/*.md'
push:
branches:
- master
paths-ignore:
- 'docs/**'
- 'website/**'
- '.spellcheck.dict.txt'
# - '**/*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ios:
name: iOS
runs-on: macos-12
# TODO matrix across APIs, at least 11 and 15 (lowest to highest)
timeout-minutes: 60
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
# Set up tool versions
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Configure JDK 1.11
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 'latest-stable'
- uses: actions/checkout@v3
with:
fetch-depth: 50
# Set path variables needed for caches
- name: Set workflow variables
id: workflow-variables
run: |
echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT
echo "xcode-version=$(xcodebuild -version|tail -1|cut -f3 -d' ')" >> $GITHUB_OUTPUT
echo "yarn-cache-dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Yarn Cache
id: yarn-cache
with:
path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }}
key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock') }}
restore-keys: ${{ runner.os }}-yarn-v1
- uses: actions/cache@v3
name: Detox Framework Cache
id: detox-cache
with:
path: ~/Library/Detox/ios
key: ${{ runner.os }}-detox-framework-cache-${{ steps.workflow-variables.outputs.xcode-version }}
# Detox is compiled during yarn install, using Xcode, set up cache first
- uses: hendrikmuhs/ccache-action@v1.2
name: Xcode Compile Cache
with:
key: ${{ runner.os }}-v2 # makes a unique key w/related restore key internally
max-size: 1500M
- name: Yarn Install
uses: nick-invision/retry@v2
with:
timeout_minutes: 10
retry_wait_seconds: 60
max_attempts: 3
command: yarn --no-audit --prefer-offline
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3
- name: Update Ruby build tools
uses: nick-invision/retry@v2
with:
timeout_minutes: 2
retry_wait_seconds: 60
max_attempts: 3
command: gem update cocoapods xcodeproj
- uses: actions/cache@v3
name: Cache Pods
id: pods-cache
with:
path: tests/ios/Pods
key: ${{ runner.os }}-pods-v2-${{ hashFiles('tests/ios/Podfile.lock') }}
restore-keys: ${{ runner.os }}-pods-v2
- name: Pod Install
uses: nick-invision/retry@v2
with:
timeout_minutes: 10
retry_wait_seconds: 30
max_attempts: 3
command: yarn tests:ios:pod:install
- name: Cache Firestore Emulator
uses: actions/cache@v3
with:
path: ~/.cache/pushy/emulators
key: pushy-emulators-v1-${{ github.run_id }}
restore-keys: pushy-emulators-v1
- name: Start Firestore Emulator
run: yarn tests:emulator:start-ci
- name: Install brew utilities
uses: nick-invision/retry@v2
with:
timeout_minutes: 5
retry_wait_seconds: 60
max_attempts: 3
command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew && HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils xcbeautify && applesimutils --list
- name: Build iOS App
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
export CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros
export CCACHE_FILECLONE=true
export CCACHE_DEPEND=true
export CCACHE_INODECACHE=true
export CCACHE_LIMIT_MULTIPLE=0.95
ccache -s
export SKIP_BUNDLING=1
export RCT_NO_LAUNCH_PACKAGER=1
set -o pipefail
yarn build:ios-debug
ccache -s
shell: bash
- name: Metro Bundler Cache
uses: actions/cache@v3
with:
path: ${{ steps.workflow-variables.outputs.metro-cache }}
key: ${{ runner.os }}-metro-v1-${{ github.run_id }}
restore-keys: ${{ runner.os }}-metro-v1
- name: Pre-fetch Javascript bundle
run: |
nohup yarn tests:packager:jet-ci &
printf 'Waiting for packager to come online'
until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do
printf '.'
sleep 2
done
echo "Packager is online! Preparing bundle..."
curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=true"
echo "...javascript bundle ready"
- name: Create Simulator Log
# With a little delay so the detox test below has time to spawn it, missing the first part of boot is fine
# If you boot the simulator separately from detox, some other race fails and detox testee never sends ready to proxy
continue-on-error: true
run: nohup sh -c "sleep 30 && xcrun simctl spawn booted log stream --level debug --style compact > simulator.log 2>&1 &"
- name: Detox Test
timeout-minutes: 60
run: yarn test:ios-debug

View File

@@ -0,0 +1,10 @@
#!/bin/bash
echo "Running $1 on all running emulators..."
devices=`adb devices`
for device in $devices; do
if [[ "$device" =~ "emulator-" ]]; then
adb -s $device $1
fi
done
echo "All Done."

View File

@@ -0,0 +1,13 @@
{
"rules": {
// Database in general is closed. Read/Write to anything but "tests/" will fail.
".read": false,
".write": false,
// ..."tests" node will succeed
"tests": {
".read": true,
".write": true,
}
}
}

39
.github/workflows/scripts/firebase.json vendored Normal file
View File

@@ -0,0 +1,39 @@
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"yarn",
"yarn --prefix \"$RESOURCE_DIR\" build"
],
"source": "functions"
},
"database": {
"rules": "database.rules"
},
"storage": {
"rules": "storage.rules"
},
"emulators": {
"auth": {
"port": 9099
},
"database": {
"port": 9000
},
"firestore": {
"port": 8080
},
"functions": {
"port": 5001
},
"storage": {
"port": 9199
},
"ui": {
"enabled": true
}
}
}

View File

@@ -0,0 +1,72 @@
{
"indexes": [
{
"collectionGroup": "firestore",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "a",
"order": "ASCENDING"
},
{
"fieldPath": "b",
"order": "ASCENDING"
}
]
}
],
"fieldOverrides": [
{
"collectionGroup": "collectionGroup",
"fieldPath": "value",
"indexes": [
{
"order": "ASCENDING",
"queryScope": "COLLECTION"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION"
},
{
"arrayConfig": "CONTAINS",
"queryScope": "COLLECTION"
},
{
"order": "ASCENDING",
"queryScope": "COLLECTION_GROUP"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION_GROUP"
}
]
},
{
"collectionGroup": "collectionGroup",
"fieldPath": "number",
"indexes": [
{
"order": "ASCENDING",
"queryScope": "COLLECTION"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION"
},
{
"arrayConfig": "CONTAINS",
"queryScope": "COLLECTION"
},
{
"order": "ASCENDING",
"queryScope": "COLLECTION_GROUP"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION_GROUP"
}
]
}
]
}

View File

@@ -0,0 +1,17 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
match /firestore-bundle-tests/{document=**} {
allow read, write: if true;
}
match /firestore/{document=**} {
allow read, write: if true;
}
match /{path=**}/collectionGroup/{documentId} {
allow read, write: if true;
}
}
}

View File

@@ -0,0 +1,10 @@
# Compiled JavaScript files
lib/**/*.js
lib/**/*.js.map
# TypeScript v1 declaration files
typings/
# Node.js dependency directory
node_modules/
yarn.lock

View File

@@ -0,0 +1,24 @@
{
"name": "functions",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^11.3.0",
"firebase-functions": "^4.2.1"
},
"devDependencies": {
"firebase-functions-test": "^3.0.0",
"typescript": "^4.9.5"
},
"private": true
}

View File

@@ -0,0 +1,13 @@
/*
*
* Testing tools for invertase/react-native-firebase use only.
*
* Copyright (C) 2018-present Invertase Limited <oss@invertase.io>
*
* See License file for more information.
*/
/* eslint-disable global-require */
module.exports = {
SAMPLE_DATA: require('./functions/sample-data'),
};

View File

@@ -0,0 +1,12 @@
import * as functions from 'firebase-functions';
// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
export const helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info('Hello logs!', { structuredData: true });
response.send('{ "data": "Hello from Firebase!" }');
});
export { testFunctionCustomRegion } from './testFunctionCustomRegion';
export { testFunctionDefaultRegion } from './testFunctionDefaultRegion';

View File

@@ -0,0 +1,80 @@
/*
* Testing tools for invertase/react-native-firebase use only.
*
* Copyright (C) 2018-present Invertase Limited <oss@invertase.io>
*
* See License file for more information.
*/
const SAMPLE_DATA: { [key: string]: any } = {
number: 1234,
string: 'acde',
boolean: true,
null: null,
object: {
number: 1234,
string: 'acde',
boolean: true,
null: null,
},
array: [1234, 'acde', true, null],
deepObject: {
array: [1234, 'acde', false, null],
object: {
number: 1234,
string: 'acde',
boolean: true,
null: null,
array: [1234, 'acde', true, null],
},
number: 1234,
string: 'acde',
boolean: true,
null: null,
},
deepArray: [
1234,
'acde',
true,
null,
[1234, 'acde', true, null],
{
number: 1234,
string: 'acde',
boolean: true,
null: null,
array: [1234, 'acde', true, null],
},
],
deepMap: {
number: 123,
string: 'foo',
booleanTrue: true,
booleanFalse: false,
null: null,
list: ['1', 2, true, false],
map: {
number: 123,
string: 'foo',
booleanTrue: true,
booleanFalse: false,
null: null,
},
},
deepList: [
'1',
2,
true,
false,
['1', 2, true, false],
{
number: 123,
string: 'foo',
booleanTrue: true,
booleanFalse: false,
null: null,
},
],
};
export default SAMPLE_DATA;

View File

@@ -0,0 +1,14 @@
/*
*
* Testing tools for invertase/react-native-firebase use only.
*
* Copyright (C) 2018-present Invertase Limited <oss@invertase.io>
*
* See License file for more information.
*/
import * as functions from 'firebase-functions';
export const testFunctionCustomRegion = functions
.region('europe-west1')
.https.onCall(() => 'europe-west1');

View File

@@ -0,0 +1,70 @@
/*
*
* Testing tools for invertase/react-native-firebase use only.
*
* Copyright (C) 2018-present Invertase Limited <oss@invertase.io>
*
* See License file for more information.
*/
import * as assert from 'assert';
import { FirebaseError } from 'firebase-admin';
import * as functions from 'firebase-functions';
import SAMPLE_DATA from './sample-data';
export const testFunctionDefaultRegion = functions.https.onCall(data => {
console.log(Date.now(), data);
if (typeof data === 'undefined') {
return 'undefined';
}
if (typeof data === 'string') {
return 'string';
}
if (typeof data === 'number') {
return 'number';
}
if (typeof data === 'boolean') {
return 'boolean';
}
if (data === null) {
return 'null';
}
if (Array.isArray(data)) {
return 'array';
}
const { type, asError, inputData } = data;
if (!Object.hasOwnProperty.call(SAMPLE_DATA, type)) {
throw new functions.https.HttpsError('invalid-argument', 'Invalid test requested.');
}
const outputData = SAMPLE_DATA[type];
try {
assert.deepEqual(outputData, inputData);
} catch (e) {
console.error(e);
throw new functions.https.HttpsError(
'invalid-argument',
'Input and Output types did not match.',
(e as FirebaseError).message,
);
}
// all good
if (asError) {
throw new functions.https.HttpsError(
'cancelled',
'Response data was requested to be sent as part of an Error payload, so here we are!',
outputData,
);
}
return outputData;
});

View File

@@ -0,0 +1,16 @@
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"skipLibCheck": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}

View File

@@ -0,0 +1,6 @@
@REM this pushd is likely not needed, but just in case
pushd "%~dp0"
@REM this is just to see what our current directory is. Should be .github/workflow/scripts
echo %cd%
@REM strangely, unless you specify the config file as being right in the current directory, it won't find it, and everything fails
yarn firebase emulators:start --config %cd%\firebase.json --only auth,database,firestore,functions,storage --project react-native-firebase-testing

View File

@@ -0,0 +1,44 @@
#!/bin/bash
if ! [ -x "$(command -v firebase)" ]; then
echo "❌ Firebase-tools CLI is missing. Run 'npm i -g firebase-tools' or the equivalent"
exit 1
fi
EMU_START_COMMAND="firebase emulators:start --only auth,database,firestore,functions,storage --project react-native-firebase-testing"
#EMU_START_COMMAND="sleep 120"
MAX_RETRIES=3
MAX_CHECKATTEMPTS=60
CHECKATTEMPTS_WAIT=1
# Make sure functions are ready to go
pushd "$(dirname "$0")/functions" && yarn && yarn build && popd
RETRIES=1
while [ $RETRIES -le $MAX_RETRIES ]; do
if [ "$1" == "--no-daemon" ]; then
echo "Starting Firebase Emulator Suite in foreground."
$EMU_START_COMMAND
exit 0
else
echo "Starting Firebase Emulator Suite in background."
$EMU_START_COMMAND &
CHECKATTEMPTS=1
while [ $CHECKATTEMPTS -le $MAX_CHECKATTEMPTS ]; do
sleep $CHECKATTEMPTS_WAIT
if curl --output /dev/null --silent --fail http://localhost:8080; then
echo "Firebase Emulator Suite is online!"
exit 0;
fi
echo "Waiting for Firebase Emulator Suite to come online, check $CHECKATTEMPTS of $MAX_CHECKATTEMPTS..."
((CHECKATTEMPTS = CHECKATTEMPTS + 1))
done
fi
echo "Firebase Emulator Suite did not come online in $MAX_CHECKATTEMPTS checks. Try $RETRIES of $MAX_RETRIES."
((RETRIES = RETRIES + 1))
done
echo "Firebase Emulator Suite did not come online after $MAX_RETRIES attempts."
exit 1

21
.github/workflows/scripts/storage.rules vendored Normal file
View File

@@ -0,0 +1,21 @@
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{document=**} {
allow read, write: if false;
}
match /writeOnly.jpeg {
allow read: if false;
allow write: if true;
}
match /playground/{document=**} {
allow read, write: if true;
}
match /react-native-firebase-testing/{document=**} {
allow read, write: if true;
}
}
}

6
.gitignore vendored
View File

@@ -41,6 +41,8 @@ local.properties
node_modules/
npm-debug.log
Example/**/update.json
Example/**/.update
Example/**/.pushy
Example/testHotUpdate/artifacts
yarn-error.log
Example/testHotUpdate/.pushy

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
18

View File

@@ -0,0 +1,6 @@
[android]
target = Google Inc.:Google APIs:23
[maven_repositories]
central = https://repo1.maven.org/maven2

View File

@@ -0,0 +1,94 @@
/** @type {Detox.DetoxConfig} */
module.exports = {
logger: {
level: process.env.CI ? 'debug' : undefined,
},
testRunner: {
args: {
config: 'e2e/jest.config.js',
maxWorkers: process.env.CI ? 2 : undefined,
_: ['e2e'],
},
},
artifacts: {
plugins: {
log: process.env.CI ? 'failing' : undefined,
screenshot: process.env.CI ? 'failing' : undefined,
},
},
apps: {
'ios.debug': {
type: 'ios.app',
binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/AwesomeProject.app',
build: "xcodebuild -workspace ios/AwesomeProject.xcworkspace -UseNewBuildSystem=NO -scheme AwesomeProject -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
start: "scripts/start-rn.sh ios",
},
'ios.release': {
type: 'ios.app',
binaryPath:
'ios/build/Build/Products/Release-iphonesimulator/AwesomeProject.app',
build:
'export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/AwesomeProject.xcworkspace -UseNewBuildSystem=NO -scheme AwesomeProject -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet',
},
'android.debug': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
build:
'cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug',
start: "scripts/start-rn.sh android",
reversePorts: [8081],
},
'android.release': {
type: 'android.apk',
binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
build:
'cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release',
},
},
devices: {
simulator: {
type: 'ios.simulator',
device: {
type: 'iPhone 14',
},
},
attached: {
type: 'android.attached',
device: {
adbName: '.*',
},
},
emulator: {
type: 'android.emulator',
device: {
avdName: 'Pixel_3a_API_33_arm64-v8a',
},
},
},
configurations: {
'ios.sim.debug': {
device: 'simulator',
app: 'ios.debug',
},
'ios.sim.release': {
device: 'simulator',
app: 'ios.release',
},
'android.att.debug': {
device: 'attached',
app: 'android.debug',
},
'android.att.release': {
device: 'attached',
app: 'android.release',
},
'android.emu.debug': {
device: 'emulator',
app: 'android.debug',
},
'android.emu.release': {
device: 'emulator',
app: 'android.release',
},
},
};

View File

@@ -0,0 +1,66 @@
[ignore]
; We fork some components by platform
.*/*[.]android.js
; Ignore "BUCK" generated dirs
<PROJECT_ROOT>/\.buckd/
; Ignore polyfills
node_modules/react-native/Libraries/polyfills/.*
; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
[include]
[libs]
node_modules/react-native/interface.js
node_modules/react-native/flow/
[options]
emoji=true
exact_by_default=true
format.bracket_spacing=false
module.file_ext=.js
module.file_ext=.json
module.file_ext=.ios.js
munge_underscores=true
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FlowFixMeProps
suppress_type=$FlowFixMeState
[lints]
sketchy-null-number=warn
sketchy-null-mixed=warn
sketchy-number=warn
untyped-type-import=warn
nonstrict-import=warn
deprecated-type=warn
unsafe-getters-setters=warn
unnecessary-invariant=warn
[strict]
deprecated-type
nonstrict-import
sketchy-null
unclear-type
unsafe-getters-setters
untyped-import
untyped-type-import
[version]
^0.176.3

View File

@@ -30,9 +30,6 @@ build/
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore
# node.js
#
@@ -40,6 +37,12 @@ node_modules/
npm-debug.log
yarn-error.log
# BUCK
buck-out/
\.buckd/
*.keystore
!debug.keystore
# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
@@ -58,6 +61,3 @@ yarn-error.log
# Ruby / CocoaPods
/ios/Pods/
/vendor/bundle/
# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

View File

@@ -0,0 +1 @@
18

View File

@@ -1 +1 @@
2.7.6
2.7.5

View File

@@ -1,6 +1,6 @@
source 'https://rubygems.org'
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby File.read(File.join(__dir__, '.ruby-version')).strip
ruby '3.1.1'
gem 'cocoapods', '~> 1.11', '>= 1.11.3'
gem 'cocoapods', '~> 1.11', '>= 1.11.2'

View File

@@ -1,30 +1,29 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.5)
CFPropertyList (3.0.6)
rexml
activesupport (6.1.5.1)
activesupport (7.0.4.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
addressable (2.8.1)
public_suffix (>= 2.0.2, < 6.0)
algoliasearch (1.27.5)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
claide (1.1.0)
cocoapods (1.11.3)
cocoapods (1.12.0)
addressable (~> 2.8)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.11.3)
cocoapods-core (= 1.12.0)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.4.0, < 2.0)
cocoapods-downloader (>= 1.6.0, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-trunk (>= 1.6.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
@@ -32,10 +31,10 @@ GEM
gh_inspector (~> 1.0)
molinillo (~> 0.8.0)
nap (~> 1.0)
ruby-macho (>= 1.0, < 3.0)
ruby-macho (>= 2.3.0, < 3.0)
xcodeproj (>= 1.21.0, < 2.0)
cocoapods-core (1.11.3)
activesupport (>= 5.0, < 7)
cocoapods-core (1.12.0)
activesupport (>= 5.0, < 8)
addressable (~> 2.8)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
@@ -54,19 +53,19 @@ GEM
netrc (~> 0.11)
cocoapods-try (1.2.0)
colored2 (3.1.2)
concurrent-ruby (1.1.10)
concurrent-ruby (1.2.2)
escape (0.0.4)
ethon (0.15.0)
ethon (0.16.0)
ffi (>= 1.15.0)
ffi (1.15.5)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
httpclient (2.8.3)
i18n (1.10.0)
i18n (1.12.0)
concurrent-ruby (~> 1.0)
json (2.6.1)
minitest (5.15.0)
json (2.6.3)
minitest (5.18.0)
molinillo (0.8.0)
nanaimo (0.3.0)
nap (1.1.0)
@@ -76,16 +75,15 @@ GEM
ruby-macho (2.5.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.4)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
xcodeproj (1.21.0)
xcodeproj (1.22.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.3.0)
rexml (~> 3.2.4)
zeitwerk (2.5.4)
PLATFORMS
ruby
@@ -94,7 +92,7 @@ DEPENDENCIES
cocoapods (~> 1.11, >= 1.11.2)
RUBY VERSION
ruby 2.7.4p191
ruby 3.1.1p18
BUNDLED WITH
2.2.27
2.1.4

View File

@@ -0,0 +1,66 @@
# react-native-android-detox
[![e2e-android](https://github.com/remarkablemark/react-native-android-detox/actions/workflows/e2e-android.yml/badge.svg)](https://github.com/remarkablemark/react-native-android-detox/actions/workflows/e2e-android.yml)
React Native Android Detox. The project has already been patched with the [additional Android configuration](https://wix.github.io/Detox/docs/introduction/project-setup/).
## Prerequisites
Follow the [environment setup](https://wix.github.io/Detox/docs/introduction/getting-started).
## Install
Clone the repository:
```sh
git clone https://github.com/remarkablemark/react-native-android-detox.git
cd react-native-android-detox
```
Install the dependencies:
```sh
yarn
```
## Build
### Android (Debug)
Build the Android debug app:
```sh
yarn detox build --configuration android.emu.debug
```
### Android (Release)
Build the Android release app:
```sh
yarn detox build --configuration android.emu.release
```
## Test
### Android (Debug)
Start the app:
```sh
yarn start
```
Run the test:
```sh
yarn detox test --configuration android.emu.debug
```
### Android (Release)
Run the test:
```sh
yarn detox test --configuration android.emu.release
```

View File

@@ -35,12 +35,12 @@ android_library(
android_build_config(
name = "build_config",
package = "com.testhotupdate",
package = "com.awesomeproject",
)
android_resource(
name = "res",
package = "com.testhotupdate",
package = "com.awesomeproject",
res = "src/main/res",
)

View File

@@ -1,87 +1,130 @@
apply plugin: "com.android.application"
apply plugin: "com.facebook.react"
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
import com.android.build.OutputFile
/**
* This is the configuration block to customize your React Native Android app.
* By default you don't need to apply any configuration, just uncomment the lines you need.
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation. If none specified and
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://reactnative.dev/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
react {
/* Folders */
// The root of your project, i.e. where "package.json" lives. Default is '..'
// root = file("../")
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
// reactNativeDir = file("../node_modules/react-native")
// The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
// codegenDir = file("../node_modules/react-native-codegen")
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
// cliFile = file("../node_modules/react-native/cli.js")
/* Variants */
// The list of variants to that are debuggable. For those we're going to
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
// debuggableVariants = ["liteDebug", "prodDebug"]
project.ext.react = [
enableHermes: false, // clean and rebuild if changing
]
/* Bundling */
// A list containing the node command and its flags. Default is just 'node'.
// nodeExecutableAndArgs = ["node"]
//
// The command to run when bundling. By default is 'bundle'
// bundleCommand = "ram-bundle"
//
// The path to the CLI configuration file. Default is empty.
// bundleConfig = file(../rn-cli.config.js)
//
// The name of the generated asset file containing your JS bundle
// bundleAssetName = "MyApplication.android.bundle"
//
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
// entryFile = file("../js/MyApplication.android.js")
//
// A list of extra flags to pass to the 'bundle' commands.
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
// extraPackagerArgs = []
/* Hermes Commands */
// The hermes compiler command to run. By default it is 'hermesc'
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
//
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
// hermesFlags = ["-O", "-output-source-map"]
}
apply from: "../../node_modules/react-native/react.gradle"
/**
* Set this to true to create four separate APKs instead of one,
* one for each native architecture. This is useful if you don't
* use App Bundles (https://developer.android.com/guide/app-bundle/)
* and want to have separate APKs to upload to the Play Store.
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore (JSC)
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
/**
* Private function to get the list of Native Architectures you want to build.
* This reads the value from reactNativeArchitectures in your gradle.properties
* file and works together with the --active-arch-only flag of react-native run-android.
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and that value will be read here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
/**
* Architectures to build native code for.
*/
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
@@ -93,13 +136,82 @@ android {
compileSdkVersion rootProject.ext.compileSdkVersion
namespace "com.testhotupdate"
defaultConfig {
applicationId "com.testhotupdate"
applicationId "com.awesomeproject"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) {
// We configure the NDK build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-21",
"APP_STL=c++_shared",
"NDK_TOOLCHAIN_VERSION=clang",
"GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
"NODE_MODULES_DIR=$rootDir/../node_modules"
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17"
// Make sure this target name is the same you specify inside the
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
targets "awesomeproject_appmodules"
}
}
if (!enableSeparateBuildPerCPUArchitecture) {
ndk {
abiFilters (*reactNativeArchitectures())
}
}
}
}
if (isNewArchitectureEnabled()) {
// We configure the NDK build only if you decide to opt-in for the New Architecture.
externalNativeBuild {
ndkBuild {
path "$projectDir/src/main/jni/Android.mk"
}
}
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
afterEvaluate {
// If you wish to add a custom TurboModule or component locally,
// you should uncomment this line.
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
// Due to a bug inside AGP, we have to explicitly set a dependency
// between configureNdkBuild* tasks and the preBuild tasks.
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
configureNdkBuildRelease.dependsOn(preReleaseBuild)
configureNdkBuildDebug.dependsOn(preDebugBuild)
reactNativeArchitectures().each { architecture ->
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
}
}
splits {
@@ -128,6 +240,7 @@ android {
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
}
}
@@ -149,22 +262,67 @@ android {
}
dependencies {
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
if (enableHermes) {
//noinspection GradleDynamicVersion
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
exclude group:'com.facebook.fbjni'
}
} else {
implementation jscFlavor
}
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
if (isNewArchitectureEnabled()) {
// If new architecture is enabled, we let you build RN from source
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
// This will be applied to all the imported transtitive dependency.
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid"))
.because("On New Architecture we're building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture we're building Hermes from source")
}
}
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.implementation
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
def isNewArchitectureEnabled() {
// To opt-in for the New Architecture, you can either:
// - Set `newArchEnabled` to true inside the `gradle.properties` file
// - Invoke gradle with `-newArchEnabled=true`
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

View File

@@ -0,0 +1,19 @@
"""Helper definitions to glob .aar and .jar targets"""
def create_aar_targets(aarfiles):
for aarfile in aarfiles:
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
lib_deps.append(":" + name)
android_prebuilt_aar(
name = name,
aar = aarfile,
)
def create_jar_targets(jarfiles):
for jarfile in jarfiles:
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
lib_deps.append(":" + name)
prebuilt_jar(
name = name,
binary_jar = jarfile,
)

View File

@@ -0,0 +1,29 @@
package com.awesomeproject;
import com.wix.detox.Detox;
import com.wix.detox.config.DetoxConfig;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
@Test
public void runDetoxTests() {
DetoxConfig detoxConfig = new DetoxConfig();
detoxConfig.idlePolicyConfig.masterTimeoutSec = 90;
detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60;
detoxConfig.rnContextLoadTimeoutSec = (BuildConfig.DEBUG ? 180 : 60);
Detox.runTests(mActivityRule, detoxConfig);
}
}

View File

@@ -4,7 +4,7 @@
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.testhotupdate;
package com.awesomeproject;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
@@ -17,6 +17,7 @@ import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
@@ -24,16 +25,13 @@ import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
import okhttp3.OkHttpClient;
/**
* Class responsible of loading Flipper inside your React Native application. This is the debug
* flavor of it. Here you can add your own plugins and customize the Flipper setup.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
@@ -72,4 +70,4 @@ public class ReactNativeFlipper {
}
}
}
}
}

View File

@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.awesomeproject">
<uses-permission android:name="android.permission.INTERNET" />
@@ -8,7 +9,8 @@
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:networkSecurityConfig="@xml/network_security_config">
<activity
android:name=".MainActivity"
android:label="@string/app_name"

View File

@@ -0,0 +1,48 @@
package com.awesomeproject;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "AwesomeProject";
}
/**
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
* (Paper).
*/
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new MainActivityDelegate(this, getMainComponentName());
}
public static class MainActivityDelegate extends ReactActivityDelegate {
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
super(activity, mainComponentName);
}
@Override
protected ReactRootView createRootView() {
ReactRootView reactRootView = new ReactRootView(getContext());
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView;
}
@Override
protected boolean isConcurrentRootEnabled() {
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
}
}

View File

@@ -0,0 +1,104 @@
package com.awesomeproject;
import android.app.Application;
import android.content.Context;
import androidx.annotation.Nullable;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.awesomeproject.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import cn.reactnative.modules.update.UpdateContext;
import cn.reactnative.modules.update.UpdatePackage;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Nullable
@Override
protected String getJSBundleFile() {
return UpdateContext.getBundleUrl(MainApplication.this);
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
private final ReactNativeHost mNewArchitectureNativeHost =
new MainApplicationReactNativeHost(this);
@Override
public ReactNativeHost getReactNativeHost() {
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
return mNewArchitectureNativeHost;
} else {
return mReactNativeHost;
}
}
@Override
public void onCreate() {
super.onCreate();
// If you opted-in for the New Architecture, we enable the TurboModule system
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* @param context
* @param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.awesomeproject.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,116 @@
package com.awesomeproject.newarchitecture;
import android.app.Application;
import androidx.annotation.NonNull;
import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.JSIModuleProvider;
import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.JSIModuleType;
import com.facebook.react.bridge.JavaScriptContextHolder;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.UIManager;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.fabric.CoreComponentsRegistry;
import com.facebook.react.fabric.FabricJSIModuleProvider;
import com.facebook.react.fabric.ReactNativeConfig;
import com.facebook.react.uimanager.ViewManagerRegistry;
import com.awesomeproject.BuildConfig;
import com.awesomeproject.newarchitecture.components.MainComponentsRegistry;
import com.awesomeproject.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
import java.util.ArrayList;
import java.util.List;
/**
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
* TurboModule delegates and the Fabric Renderer.
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
public class MainApplicationReactNativeHost extends ReactNativeHost {
public MainApplicationReactNativeHost(Application application) {
super(application);
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
// packages.add(new TurboReactPackage() { ... });
// If you have custom Fabric Components, their ViewManagers should also be loaded here
// inside a ReactPackage.
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@NonNull
@Override
protected ReactPackageTurboModuleManagerDelegate.Builder
getReactPackageTurboModuleManagerDelegateBuilder() {
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
// for the new architecture and to use TurboModules correctly.
return new MainApplicationTurboModuleManagerDelegate.Builder();
}
@Override
protected JSIModulePackage getJSIModulePackage() {
return new JSIModulePackage() {
@Override
public List<JSIModuleSpec> getJSIModules(
final ReactApplicationContext reactApplicationContext,
final JavaScriptContextHolder jsContext) {
final List<JSIModuleSpec> specs = new ArrayList<>();
// Here we provide a new JSIModuleSpec that will be responsible of providing the
// custom Fabric Components.
specs.add(
new JSIModuleSpec() {
@Override
public JSIModuleType getJSIModuleType() {
return JSIModuleType.UIManager;
}
@Override
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
final ComponentFactory componentFactory = new ComponentFactory();
CoreComponentsRegistry.register(componentFactory);
// Here we register a Components Registry.
// The one that is generated with the template contains no components
// and just provides you the one from React Native core.
MainComponentsRegistry.register(componentFactory);
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
ViewManagerRegistry viewManagerRegistry =
new ViewManagerRegistry(
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
return new FabricJSIModuleProvider(
reactApplicationContext,
componentFactory,
ReactNativeConfig.DEFAULT_CONFIG,
viewManagerRegistry);
}
});
return specs;
}
};
}
}

View File

@@ -0,0 +1,36 @@
package com.awesomeproject.newarchitecture.components;
import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip;
import com.facebook.react.fabric.ComponentFactory;
import com.facebook.soloader.SoLoader;
/**
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
* folder for you).
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
@DoNotStrip
public class MainComponentsRegistry {
static {
SoLoader.loadLibrary("fabricjni");
}
@DoNotStrip private final HybridData mHybridData;
@DoNotStrip
private native HybridData initHybrid(ComponentFactory componentFactory);
@DoNotStrip
private MainComponentsRegistry(ComponentFactory componentFactory) {
mHybridData = initHybrid(componentFactory);
}
@DoNotStrip
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
return new MainComponentsRegistry(componentFactory);
}
}

View File

@@ -0,0 +1,48 @@
package com.awesomeproject.newarchitecture.modules;
import com.facebook.jni.HybridData;
import com.facebook.react.ReactPackage;
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.soloader.SoLoader;
import java.util.List;
/**
* Class responsible to load the TurboModules. This class has native methods and needs a
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
* folder for you).
*
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
* `newArchEnabled` property). Is ignored otherwise.
*/
public class MainApplicationTurboModuleManagerDelegate
extends ReactPackageTurboModuleManagerDelegate {
private static volatile boolean sIsSoLibraryLoaded;
protected MainApplicationTurboModuleManagerDelegate(
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
super(reactApplicationContext, packages);
}
protected native HybridData initHybrid();
native boolean canCreateTurboModule(String moduleName);
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
protected MainApplicationTurboModuleManagerDelegate build(
ReactApplicationContext context, List<ReactPackage> packages) {
return new MainApplicationTurboModuleManagerDelegate(context, packages);
}
}
@Override
protected synchronized void maybeLoadOtherSoLibraries() {
if (!sIsSoLibraryLoaded) {
// If you change the name of your application .so file in the Android.mk file,
// make sure you update the name here as well.
SoLoader.loadLibrary("awesomeproject_appmodules");
sIsSoLibraryLoaded = true;
}
}
}

View File

@@ -1,35 +0,0 @@
package com.testhotupdate;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactActivityDelegate;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "testHotupdate";
}
/**
* Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
* DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
* (aka React 18) with two boolean flags.
*/
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new DefaultReactActivityDelegate(
this,
getMainComponentName(),
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
// If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
);
}
}

View File

@@ -1,67 +0,0 @@
package com.testhotupdate;
import android.app.Application;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.soloader.SoLoader;
import java.util.List;
import cn.reactnative.modules.update.UpdateContext;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new DefaultReactNativeHost(this) {
@Override
protected String getJSBundleFile() {
return UpdateContext.getBundleUrl(MainApplication.this);
}
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
@Override
protected boolean isNewArchEnabled() {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
@Override
protected Boolean isHermesEnabled() {
return BuildConfig.IS_HERMES_ENABLED;
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
// If you opted-in for the New Architecture, we load the native entry point for this app.
DefaultNewArchitectureEntryPoint.load();
}
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
}

View File

@@ -0,0 +1,48 @@
THIS_DIR := $(call my-dir)
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
# If you wish to add a custom TurboModule or Fabric component in your app you
# will have to include the following autogenerated makefile.
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
include $(CLEAR_VARS)
LOCAL_PATH := $(THIS_DIR)
# You can customize the name of your application .so file here.
LOCAL_MODULE := awesomeproject_appmodules
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
# If you wish to add a custom TurboModule or Fabric component in your app you
# will have to uncomment those lines to include the generated source
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
#
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
# Here you should add any native library you wish to depend on.
LOCAL_SHARED_LIBRARIES := \
libfabricjni \
libfbjni \
libfolly_runtime \
libglog \
libjsi \
libreact_codegen_rncore \
libreact_debug \
libreact_nativemodule_core \
libreact_render_componentregistry \
libreact_render_core \
libreact_render_debug \
libreact_render_graphics \
librrc_view \
libruntimeexecutor \
libturbomodulejsijni \
libyoga
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,24 @@
#include "MainApplicationModuleProvider.h"
#include <rncore.h>
namespace facebook {
namespace react {
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params) {
// Here you can provide your own module provider for TurboModules coming from
// either your application or from external libraries. The approach to follow
// is similar to the following (for a library called `samplelibrary`:
//
// auto module = samplelibrary_ModuleProvider(moduleName, params);
// if (module != nullptr) {
// return module;
// }
// return rncore_ModuleProvider(moduleName, params);
return rncore_ModuleProvider(moduleName, params);
}
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,16 @@
#pragma once
#include <memory>
#include <string>
#include <ReactCommon/JavaTurboModule.h>
namespace facebook {
namespace react {
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
const std::string moduleName,
const JavaTurboModule::InitParams &params);
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,45 @@
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainApplicationModuleProvider.h"
namespace facebook {
namespace react {
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
MainApplicationTurboModuleManagerDelegate::initHybrid(
jni::alias_ref<jhybridobject>) {
return makeCxxInstance();
}
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
registerHybrid({
makeNativeMethod(
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
makeNativeMethod(
"canCreateTurboModule",
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
});
}
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string name,
const std::shared_ptr<CallInvoker> jsInvoker) {
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
}
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string name,
const JavaTurboModule::InitParams &params) {
return MainApplicationModuleProvider(name, params);
}
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
std::string name) {
return getTurboModule(name, nullptr) != nullptr ||
getTurboModule(name, {.moduleName = name}) != nullptr;
}
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,38 @@
#include <memory>
#include <string>
#include <ReactCommon/TurboModuleManagerDelegate.h>
#include <fbjni/fbjni.h>
namespace facebook {
namespace react {
class MainApplicationTurboModuleManagerDelegate
: public jni::HybridClass<
MainApplicationTurboModuleManagerDelegate,
TurboModuleManagerDelegate> {
public:
// Adapt it to the package you used for your Java class.
static constexpr auto kJavaDescriptor =
"Lcom/awesomeproject/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
static void registerNatives();
std::shared_ptr<TurboModule> getTurboModule(
const std::string name,
const std::shared_ptr<CallInvoker> jsInvoker) override;
std::shared_ptr<TurboModule> getTurboModule(
const std::string name,
const JavaTurboModule::InitParams &params) override;
/**
* Test-only method. Allows user to verify whether a TurboModule can be
* created by instances of this class.
*/
bool canCreateTurboModule(std::string name);
};
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,61 @@
#include "MainComponentsRegistry.h"
#include <CoreComponentsRegistry.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/components/rncore/ComponentDescriptors.h>
namespace facebook {
namespace react {
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
std::shared_ptr<ComponentDescriptorProviderRegistry const>
MainComponentsRegistry::sharedProviderRegistry() {
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
// Custom Fabric Components go here. You can register custom
// components coming from your App or from 3rd party libraries here.
//
// providerRegistry->add(concreteComponentDescriptorProvider<
// AocViewerComponentDescriptor>());
return providerRegistry;
}
jni::local_ref<MainComponentsRegistry::jhybriddata>
MainComponentsRegistry::initHybrid(
jni::alias_ref<jclass>,
ComponentFactory *delegate) {
auto instance = makeCxxInstance(delegate);
auto buildRegistryFunction =
[](EventDispatcher::Weak const &eventDispatcher,
ContextContainer::Shared const &contextContainer)
-> ComponentDescriptorRegistry::Shared {
auto registry = MainComponentsRegistry::sharedProviderRegistry()
->createComponentDescriptorRegistry(
{eventDispatcher, contextContainer});
auto mutableRegistry =
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
mutableRegistry->setFallbackComponentDescriptor(
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
ComponentDescriptorParameters{
eventDispatcher, contextContainer, nullptr}));
return registry;
};
delegate->buildRegistryFunction = buildRegistryFunction;
return instance;
}
void MainComponentsRegistry::registerNatives() {
registerHybrid({
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
});
}
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,32 @@
#pragma once
#include <ComponentFactory.h>
#include <fbjni/fbjni.h>
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
namespace facebook {
namespace react {
class MainComponentsRegistry
: public facebook::jni::HybridClass<MainComponentsRegistry> {
public:
// Adapt it to the package you used for your Java class.
constexpr static auto kJavaDescriptor =
"Lcom/awesomeproject/newarchitecture/components/MainComponentsRegistry;";
static void registerNatives();
MainComponentsRegistry(ComponentFactory *delegate);
private:
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
sharedProviderRegistry();
static jni::local_ref<jhybriddata> initHybrid(
jni::alias_ref<jclass>,
ComponentFactory *delegate);
};
} // namespace react
} // namespace facebook

View File

@@ -0,0 +1,11 @@
#include <fbjni/fbjni.h>
#include "MainApplicationTurboModuleManagerDelegate.h"
#include "MainComponentsRegistry.h"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::jni::initialize(vm, [] {
facebook::react::MainApplicationTurboModuleManagerDelegate::
registerNatives();
facebook::react::MainComponentsRegistry::registerNatives();
});
}

View File

@@ -1,3 +1,3 @@
<resources>
<string name="app_name">testHotupdate</string>
<string name="app_name">AwesomeProject</string>
</resources>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">cos.pgyer.com</domain>
</domain-config>
</network-security-config>

View File

@@ -1,20 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.testhotupdate;
import android.content.Context;
import com.facebook.react.ReactInstanceManager;
/**
* Class responsible of loading Flipper inside your React Native application. This is the release
* flavor of it so it's empty as we don't want to load Flipper.
*/
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
// Do nothing as we don't want to initialize Flipper on Release.
}
}

View File

@@ -1,21 +1,58 @@
import org.apache.tools.ant.taskdefs.condition.Os
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
buildToolsVersion = "33.0.0"
buildToolsVersion = "31.0.0"
minSdkVersion = 21
compileSdkVersion = 33
targetSdkVersion = 33
compileSdkVersion = 31
targetSdkVersion = 31
kotlinVersion = '1.6.10'
// We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
ndkVersion = "23.1.7779620"
if (System.properties['os.arch'] == "aarch64") {
// For M1 Users we need to use the NDK 24 which added support for aarch64
ndkVersion = "24.0.8215888"
} else {
// Otherwise we default to the side-by-side NDK version from AGP.
ndkVersion = "21.4.7075529"
}
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("com.android.tools.build:gradle:7.1.1")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:5.0.1")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
}
}
}
allprojects {
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.
content {
excludeGroup "com.facebook.react"
}
}
google()
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}
maven { url 'https://www.jitpack.io' }
}
}

View File

@@ -38,7 +38,3 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,4 +1,11 @@
rootProject.name = 'testHotupdate'
rootProject.name = 'AwesomeProject'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
includeBuild('../node_modules/react-native-gradle-plugin')
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid")
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
include(":ReactAndroid:hermes-engine")
project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
}

View File

@@ -1,4 +1,4 @@
{
"name": "testHotupdate",
"displayName": "testHotupdate"
"name": "AwesomeProject",
"displayName": "AwesomeProject"
}

View File

@@ -0,0 +1,123 @@
import {by, device, element, expect, waitFor} from 'detox';
describe('测试Native模块的方法', () => {
beforeAll(async () => {
await device.launchApp();
});
it('setLocalHashInfo', async () => {
await element(by.id('testcase')).longPress();
await element(by.id('setLocalHashInfo')).longPress();
await element(by.id('submit')).longPress();
await expect(element(by.id('done'))).toBeVisible();
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
it('getLocalHashInfo', async () => {
await element(by.id('getLocalHashInfo')).longPress();
await element(by.id('submit')).longPress();
await expect(element(by.text('done'))).toBeVisible();
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
it('setUuid', async () => {
await element(by.id('setUuid')).longPress();
await element(by.id('submit')).longPress();
await expect(element(by.text('done'))).toBeVisible();
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
it('setBlockUpdate', async () => {
await element(by.id('setBlockUpdate')).longPress();
await element(by.id('submit')).longPress();
await expect(element(by.text('done'))).toBeVisible();
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
if (device.getPlatform() === 'android') {
it('reloadUpdate', async () => {
await element(by.id('reloadUpdate')).longPress();
await element(by.id('submit')).longPress();
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
}
it('setNeedUpdate', async () => {
await element(by.id('setNeedUpdate')).longPress();
await element(by.id('submit')).longPress();
await expect(element(by.text('done'))).toBeVisible();
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
if (device.getPlatform() === 'android') {
it('markSuccess', async () => {
await element(by.id('markSuccess')).longPress();
await element(by.id('submit')).longPress();
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
await element(by.id('done')).longPress();
});
}
it('downloadPatchFromPpk', async () => {
await element(by.id('downloadPatchFromPpk')).longPress();
await element(by.id('submit')).longPress();
if (device.getPlatform() === 'ios') {
await expect(element(by.text('failed to open zip file'))).toBeVisible();
} else {
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
}
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
it('downloadPatchFromPackage', async () => {
await element(by.id('downloadPatchFromPackage')).longPress();
await element(by.id('submit')).longPress();
if (device.getPlatform() === 'ios') {
await expect(element(by.text('failed to open zip file'))).toBeVisible();
} else {
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
}
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
it('downloadFullUpdate', async () => {
await element(by.id('downloadFullUpdate')).longPress();
await element(by.id('submit')).longPress();
if (device.getPlatform() === 'ios') {
await expect(element(by.text('failed to open zip file'))).toBeVisible();
} else {
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
}
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
if (device.getPlatform() === 'android') {
it('downloadAndInstallApk', async () => {
await element(by.id('downloadAndInstallApk')).longPress();
await element(by.id('submit')).longPress();
await waitFor(element(by.text('确认')))
.toBeVisible()
.withTimeout(10000);
await element(by.id('done')).longPress();
await expect(element(by.id('done'))).toBeNotVisible();
});
}
});

View File

@@ -0,0 +1,15 @@
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
rootDir: '..',
testMatch: ['<rootDir>/e2e/**/*.test.ts'],
testTimeout: 240000,
maxWorkers: 2,
transform: {
'\\.tsx?$': 'ts-jest',
},
globalSetup: 'detox/runners/jest/globalSetup',
globalTeardown: 'detox/runners/jest/globalTeardown',
reporters: ['detox/runners/jest/reporter'],
testEnvironment: 'detox/runners/jest/testEnvironment',
verbose: true,
};

View File

@@ -2,9 +2,10 @@
# used when running script phases inside Xcode.
# To customize your local environment, you can create an `.xcode.env.local`
# file that is not versioned.
# NODE_BINARY variable contains the PATH to the node executable.
#
# Customize the NODE_BINARY variable here.
# For example, to use nvm with brew, add the following line
# . "$(brew --prefix nvm)/nvm.sh" --no-use
export NODE_BINARY=$(command -v node)
export NODE_BINARY=$(command -v node)

View File

@@ -7,13 +7,13 @@
objects = {
/* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* testHotupdateTests.m */; };
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */; };
00E356F31AD99517003FC87E /* AwesomeProjectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* AwesomeProjectTests.m */; };
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
7699B88040F8A987B510C191 /* libPods-AwesomeProject-AwesomeProjectTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
983131D2EBAB94EBB6700C34 /* libPods-testHotupdate-testHotupdateTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 59B080016B9F7992256D7BCD /* libPods-testHotupdate-testHotupdateTests.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -22,27 +22,27 @@
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = testHotupdate;
remoteInfo = AwesomeProject;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = testHotupdateTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356EE1AD99517003FC87E /* AwesomeProjectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AwesomeProjectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* testHotupdateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testHotupdateTests.m; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* testHotupdate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testHotupdate.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = testHotupdate/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = testHotupdate/AppDelegate.mm; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = testHotupdate/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = testHotupdate/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testHotupdate/main.m; sourceTree = "<group>"; };
35A33350B5D9A46B028EB31B /* Pods-testHotupdate-testHotupdateTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotupdate-testHotupdateTests.release.xcconfig"; path = "Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests.release.xcconfig"; sourceTree = "<group>"; };
3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotupdate.debug.xcconfig"; path = "Target Support Files/Pods-testHotupdate/Pods-testHotupdate.debug.xcconfig"; sourceTree = "<group>"; };
404B8A109FF0E52B839C8687 /* Pods-testHotupdate-testHotupdateTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotupdate-testHotupdateTests.debug.xcconfig"; path = "Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests.debug.xcconfig"; sourceTree = "<group>"; };
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotupdate.release.xcconfig"; path = "Target Support Files/Pods-testHotupdate/Pods-testHotupdate.release.xcconfig"; sourceTree = "<group>"; };
59B080016B9F7992256D7BCD /* libPods-testHotupdate-testHotupdateTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotupdate-testHotupdateTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotupdate.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = testHotupdate/LaunchScreen.storyboard; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* AwesomeProjectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AwesomeProjectTests.m; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* AwesomeProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AwesomeProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = AwesomeProject/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = AwesomeProject/AppDelegate.mm; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AwesomeProject/Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AwesomeProject/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AwesomeProject/main.m; sourceTree = "<group>"; };
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject-AwesomeProjectTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject.debug.xcconfig"; path = "Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject.debug.xcconfig"; sourceTree = "<group>"; };
5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject.release.xcconfig"; path = "Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject.release.xcconfig"; sourceTree = "<group>"; };
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig"; path = "Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig"; sourceTree = "<group>"; };
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject.a"; sourceTree = BUILT_PRODUCTS_DIR; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AwesomeProject/LaunchScreen.storyboard; sourceTree = "<group>"; };
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig"; path = "Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */
@@ -51,7 +51,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
983131D2EBAB94EBB6700C34 /* libPods-testHotupdate-testHotupdateTests.a in Frameworks */,
7699B88040F8A987B510C191 /* libPods-AwesomeProject-AwesomeProjectTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -59,20 +59,20 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */,
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
00E356EF1AD99517003FC87E /* testHotupdateTests */ = {
00E356EF1AD99517003FC87E /* AwesomeProjectTests */ = {
isa = PBXGroup;
children = (
00E356F21AD99517003FC87E /* testHotupdateTests.m */,
00E356F21AD99517003FC87E /* AwesomeProjectTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
path = testHotupdateTests;
path = AwesomeProjectTests;
sourceTree = "<group>";
};
00E356F01AD99517003FC87E /* Supporting Files */ = {
@@ -83,7 +83,7 @@
name = "Supporting Files";
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* testHotupdate */ = {
13B07FAE1A68108700A75B9A /* AwesomeProject */ = {
isa = PBXGroup;
children = (
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
@@ -93,15 +93,15 @@
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
13B07FB71A68108700A75B9A /* main.m */,
);
name = testHotupdate;
name = AwesomeProject;
sourceTree = "<group>";
};
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */,
59B080016B9F7992256D7BCD /* libPods-testHotupdate-testHotupdateTests.a */,
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */,
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -116,9 +116,9 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
13B07FAE1A68108700A75B9A /* testHotupdate */,
13B07FAE1A68108700A75B9A /* AwesomeProject */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* testHotupdateTests */,
00E356EF1AD99517003FC87E /* AwesomeProjectTests */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
BBD78D7AC51CEA395F1C20DB /* Pods */,
@@ -131,8 +131,8 @@
83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* testHotupdate.app */,
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */,
13B07F961A680F5B00A75B9A /* AwesomeProject.app */,
00E356EE1AD99517003FC87E /* AwesomeProjectTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -140,10 +140,10 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup;
children = (
3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */,
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */,
404B8A109FF0E52B839C8687 /* Pods-testHotupdate-testHotupdateTests.debug.xcconfig */,
35A33350B5D9A46B028EB31B /* Pods-testHotupdate-testHotupdateTests.release.xcconfig */,
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */,
5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */,
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */,
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
@@ -151,30 +151,30 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
00E356ED1AD99517003FC87E /* testHotupdateTests */ = {
00E356ED1AD99517003FC87E /* AwesomeProjectTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "AwesomeProjectTests" */;
buildPhases = (
DC20F2927A7E6CA06E8D485C /* [CP] Check Pods Manifest.lock */,
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
4C7F70F5C06F7BFA31EE8610 /* [CP] Embed Pods Frameworks */,
BC2CDA870086B299A0FA004A /* [CP] Copy Pods Resources */,
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */,
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
00E356F51AD99517003FC87E /* PBXTargetDependency */,
);
name = testHotupdateTests;
productName = testHotupdateTests;
productReference = 00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */;
name = AwesomeProjectTests;
productName = AwesomeProjectTests;
productReference = 00E356EE1AD99517003FC87E /* AwesomeProjectTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
13B07F861A680F5B00A75B9A /* testHotupdate */ = {
13B07F861A680F5B00A75B9A /* AwesomeProject */ = {
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */;
buildPhases = (
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */,
@@ -189,9 +189,9 @@
);
dependencies = (
);
name = testHotupdate;
productName = testHotupdate;
productReference = 13B07F961A680F5B00A75B9A /* testHotupdate.app */;
name = AwesomeProject;
productName = AwesomeProject;
productReference = 13B07F961A680F5B00A75B9A /* AwesomeProject.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@@ -211,7 +211,7 @@
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */;
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */;
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
@@ -224,8 +224,8 @@
projectDirPath = "";
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* testHotupdate */,
00E356ED1AD99517003FC87E /* testHotupdateTests */,
13B07F861A680F5B00A75B9A /* AwesomeProject */,
00E356ED1AD99517003FC87E /* AwesomeProjectTests */,
);
};
/* End PBXProject section */
@@ -256,13 +256,15 @@
files = (
);
inputPaths = (
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/.xcode.env",
);
name = "Bundle React Native code and images";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
@@ -270,49 +272,37 @@
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
4C7F70F5C06F7BFA31EE8610 /* [CP] Embed Pods Frameworks */ = {
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-AwesomeProject-AwesomeProjectTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
BC2CDA870086B299A0FA004A /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate-testHotupdateTests/Pods-testHotupdate-testHotupdateTests-resources.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
@@ -330,33 +320,28 @@
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-testHotupdate-checkManifestLockResult.txt",
"$(DERIVED_FILE_DIR)/Pods-AwesomeProject-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
DC20F2927A7E6CA06E8D485C /* [CP] Check Pods Manifest.lock */ = {
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-testHotupdate-testHotupdateTests-checkManifestLockResult.txt",
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
@@ -365,15 +350,32 @@
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-input-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-output-files.xcfilelist",
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources.sh\"\n";
showEnvVarsInLog = 0;
};
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
FD10A7F022414F080027D42C /* Start Packager */ = {
@@ -402,7 +404,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */,
00E356F31AD99517003FC87E /* AwesomeProjectTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -420,7 +422,7 @@
/* Begin PBXTargetDependency section */
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 13B07F861A680F5B00A75B9A /* testHotupdate */;
target = 13B07F861A680F5B00A75B9A /* AwesomeProject */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
@@ -428,15 +430,15 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 404B8A109FF0E52B839C8687 /* Pods-testHotupdate-testHotupdateTests.debug.xcconfig */;
baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = testHotupdateTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
INFOPLIST_FILE = AwesomeProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -449,18 +451,18 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AwesomeProject.app/AwesomeProject";
};
name = Debug;
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 35A33350B5D9A46B028EB31B /* Pods-testHotupdate-testHotupdateTests.release.xcconfig */;
baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = testHotupdateTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
INFOPLIST_FILE = AwesomeProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -473,19 +475,19 @@
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AwesomeProject.app/AwesomeProject";
};
name = Release;
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */;
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = testHotupdate/Info.plist;
INFOPLIST_FILE = AwesomeProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -496,7 +498,7 @@
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = testHotupdate;
PRODUCT_NAME = AwesomeProject;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -505,12 +507,12 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */;
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = testHotupdate/Info.plist;
INFOPLIST_FILE = AwesomeProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -521,7 +523,7 @@
"-lc++",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = testHotupdate;
PRODUCT_NAME = AwesomeProject;
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
@@ -560,7 +562,7 @@
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -576,7 +578,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
@@ -632,7 +634,7 @@
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -641,7 +643,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift,
"$(inherited)",
@@ -667,7 +669,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */ = {
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "AwesomeProjectTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00E356F61AD99517003FC87E /* Debug */,
@@ -676,7 +678,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */ = {
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */,
@@ -685,7 +687,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */ = {
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */,

View File

@@ -15,9 +15,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "testHotupdate.app"
BlueprintName = "testHotupdate"
ReferencedContainer = "container:testHotupdate.xcodeproj">
BuildableName = "AwesomeProject.app"
BlueprintName = "AwesomeProject"
ReferencedContainer = "container:AwesomeProject.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
@@ -33,9 +33,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "testHotupdateTests.xctest"
BlueprintName = "testHotupdateTests"
ReferencedContainer = "container:testHotupdate.xcodeproj">
BuildableName = "AwesomeProjectTests.xctest"
BlueprintName = "AwesomeProjectTests"
ReferencedContainer = "container:AwesomeProject.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
@@ -55,9 +55,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "testHotupdate.app"
BlueprintName = "testHotupdate"
ReferencedContainer = "container:testHotupdate.xcodeproj">
BuildableName = "AwesomeProject.app"
BlueprintName = "AwesomeProject"
ReferencedContainer = "container:AwesomeProject.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
@@ -72,9 +72,9 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
BuildableName = "testHotupdate.app"
BlueprintName = "testHotupdate"
ReferencedContainer = "container:testHotupdate.xcodeproj">
BuildableName = "AwesomeProject.app"
BlueprintName = "AwesomeProject"
ReferencedContainer = "container:AwesomeProject.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>

View File

@@ -2,7 +2,7 @@
<Workspace
version = "1.0">
<FileRef
location = "group:testHotupdate.xcodeproj">
location = "group:AwesomeProject.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,8 @@
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
@property (nonatomic, strong) UIWindow *window;
@end

View File

@@ -0,0 +1,133 @@
#import "AppDelegate.h"
#import "RCTPushy.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTAppSetupUtils.h>
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager;
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
facebook::react::ContextContainer::Shared _contextContainer;
}
@end
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTAppSetupPrepareApp(application);
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
#if RCT_NEW_ARCH_ENABLED
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif
NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"AwesomeProject", initProps);
if (@available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
// Switch this bool to turn on and off the concurrent root
return true;
}
- (NSDictionary *)prepareInitialProps
{
NSMutableDictionary *initProps = [NSMutableDictionary new];
#ifdef RCT_NEW_ARCH_ENABLED
initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
#endif
return initProps;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [RCTPushy bundleURL];
#endif
}
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}
#pragma mark RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
return RCTCoreModulesClassProvider(name);
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
initParams:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return RCTAppSetupDefaultModuleFromClass(moduleClass);
}
#endif
@end

View File

@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>testHotupdate</string>
<string>AwesomeProject</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -26,6 +26,8 @@
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>

View File

@@ -16,7 +16,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="testHotupdate" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AwesomeProject" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<nil key="highlightedColor"/>

View File

@@ -7,11 +7,11 @@
#define TIMEOUT_SECONDS 600
#define TEXT_TO_LOOK_FOR @"Welcome to React"
@interface testHotupdateTests : XCTestCase
@interface AwesomeProjectTests : XCTestCase
@end
@implementation testHotupdateTests
@implementation AwesomeProjectTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
{

View File

@@ -1,27 +1,12 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, min_ios_version_supported
prepare_react_native_project!
platform :ios, '12.4'
install! 'cocoapods', :deterministic_uuids => false
# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
#
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
# ```js
# module.exports = {
# dependencies: {
# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
# ```
flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
production = ENV["PRODUCTION"] == "1"
linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
use_frameworks! :linkage => linkage.to_sym
end
target 'testHotupdate' do
target 'AwesomeProject' do
config = use_native_modules!
# Flags change depending on the env values.
@@ -29,32 +14,22 @@ target 'testHotupdate' do
use_react_native!(
:path => config[:reactNativePath],
# Hermes is now enabled by default. Disable by setting this flag to false.
# Upcoming versions of React Native may rely on get_default_flags(), but
# we make it explicit here to aid in the React Native upgrade process.
# to enable hermes on iOS, change `false` to `true` and then install pods
:production => production,
:hermes_enabled => flags[:hermes_enabled],
:fabric_enabled => flags[:fabric_enabled],
# Enables Flipper.
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
:flipper_configuration => flipper_config,
:flipper_configuration => FlipperConfiguration.enabled,
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
target 'testHotupdateTests' do
target 'AwesomeProjectTests' do
inherit! :complete
# Pods for testing
end
post_install do |installer|
react_native_post_install(
installer,
# Set `mac_catalyst_enabled` to `true` in order to apply patches
# necessary for Mac Catalyst builds
:mac_catalyst_enabled => false
)
react_native_post_install(installer)
__apply_Xcode_12_5_M1_post_install_workaround(installer)
end
end
end

View File

@@ -2,14 +2,14 @@ PODS:
- boost (1.76.0)
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
- FBLazyVector (0.71.1)
- FBReactNativeSpec (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTRequired (= 0.71.1)
- RCTTypeSafety (= 0.71.1)
- React-Core (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- FBLazyVector (0.69.8)
- FBReactNativeSpec (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.69.8)
- RCTTypeSafety (= 0.69.8)
- React-Core (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- Flipper (0.125.0):
- Flipper-Folly (~> 2.6)
- Flipper-RSocket (~> 1.4)
@@ -73,322 +73,297 @@ PODS:
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
- hermes-engine (0.71.1):
- hermes-engine/Pre-built (= 0.71.1)
- hermes-engine/Pre-built (0.71.1)
- libevent (2.1.12)
- OpenSSL-Universal (1.1.1100)
- RCT-Folly (2021.07.22.00):
- RCT-Folly (2021.06.28.00-v2):
- boost
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- RCT-Folly/Default (= 2021.07.22.00)
- RCT-Folly/Default (2021.07.22.00):
- RCT-Folly/Default (= 2021.06.28.00-v2)
- RCT-Folly/Default (2021.06.28.00-v2):
- boost
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- RCT-Folly/Futures (2021.07.22.00):
- boost
- DoubleConversion
- fmt (~> 6.2.1)
- RCTRequired (0.69.8)
- RCTTypeSafety (0.69.8):
- FBLazyVector (= 0.69.8)
- RCTRequired (= 0.69.8)
- React-Core (= 0.69.8)
- React (0.69.8):
- React-Core (= 0.69.8)
- React-Core/DevSupport (= 0.69.8)
- React-Core/RCTWebSocket (= 0.69.8)
- React-RCTActionSheet (= 0.69.8)
- React-RCTAnimation (= 0.69.8)
- React-RCTBlob (= 0.69.8)
- React-RCTImage (= 0.69.8)
- React-RCTLinking (= 0.69.8)
- React-RCTNetwork (= 0.69.8)
- React-RCTSettings (= 0.69.8)
- React-RCTText (= 0.69.8)
- React-RCTVibration (= 0.69.8)
- React-bridging (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi (= 0.69.8)
- React-callinvoker (0.69.8)
- React-Codegen (0.69.8):
- FBReactNativeSpec (= 0.69.8)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.69.8)
- RCTTypeSafety (= 0.69.8)
- React-Core (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-Core (0.69.8):
- glog
- libevent
- RCTRequired (0.71.1)
- RCTTypeSafety (0.71.1):
- FBLazyVector (= 0.71.1)
- RCTRequired (= 0.71.1)
- React-Core (= 0.71.1)
- React (0.71.1):
- React-Core (= 0.71.1)
- React-Core/DevSupport (= 0.71.1)
- React-Core/RCTWebSocket (= 0.71.1)
- React-RCTActionSheet (= 0.71.1)
- React-RCTAnimation (= 0.71.1)
- React-RCTBlob (= 0.71.1)
- React-RCTImage (= 0.71.1)
- React-RCTLinking (= 0.71.1)
- React-RCTNetwork (= 0.71.1)
- React-RCTSettings (= 0.71.1)
- React-RCTText (= 0.71.1)
- React-RCTVibration (= 0.71.1)
- React-callinvoker (0.71.1)
- React-Codegen (0.71.1):
- FBReactNativeSpec
- hermes-engine
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React-Core
- React-jsi
- React-jsiexecutor
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- React-Core (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default (= 0.71.1)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.69.8)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/CoreModulesHeaders (0.71.1):
- React-Core/CoreModulesHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/Default (0.71.1):
- React-Core/Default (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/DevSupport (0.71.1):
- React-Core/DevSupport (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default (= 0.71.1)
- React-Core/RCTWebSocket (= 0.71.1)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-jsinspector (= 0.71.1)
- React-perflogger (= 0.71.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.69.8)
- React-Core/RCTWebSocket (= 0.69.8)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-jsinspector (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTActionSheetHeaders (0.71.1):
- React-Core/RCTActionSheetHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTAnimationHeaders (0.71.1):
- React-Core/RCTAnimationHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTBlobHeaders (0.71.1):
- React-Core/RCTBlobHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTImageHeaders (0.71.1):
- React-Core/RCTImageHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTLinkingHeaders (0.71.1):
- React-Core/RCTLinkingHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTNetworkHeaders (0.71.1):
- React-Core/RCTNetworkHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTSettingsHeaders (0.71.1):
- React-Core/RCTSettingsHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTTextHeaders (0.71.1):
- React-Core/RCTTextHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTVibrationHeaders (0.71.1):
- React-Core/RCTVibrationHeaders (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-Core/RCTWebSocket (0.71.1):
- React-Core/RCTWebSocket (0.69.8):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default (= 0.71.1)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-perflogger (= 0.71.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.69.8)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.69.8)
- Yoga
- React-CoreModules (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTTypeSafety (= 0.71.1)
- React-Codegen (= 0.71.1)
- React-Core/CoreModulesHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- React-RCTImage (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-cxxreact (0.71.1):
- React-CoreModules (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.69.8)
- React-Core/CoreModulesHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- React-RCTImage (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-cxxreact (0.69.8):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- React-callinvoker (= 0.71.1)
- React-jsi (= 0.71.1)
- React-jsinspector (= 0.71.1)
- React-logger (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-runtimeexecutor (= 0.71.1)
- React-hermes (0.71.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly/Futures (= 2021.07.22.00)
- React-cxxreact (= 0.71.1)
- React-jsiexecutor (= 0.71.1)
- React-jsinspector (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-jsi (0.71.1):
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.69.8)
- React-jsi (= 0.69.8)
- React-jsinspector (= 0.69.8)
- React-logger (= 0.69.8)
- React-perflogger (= 0.69.8)
- React-runtimeexecutor (= 0.69.8)
- React-jsi (0.69.8):
- boost (= 1.76.0)
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2021.07.22.00)
- React-jsiexecutor (0.71.1):
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.69.8)
- React-jsi/Default (0.69.8):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-perflogger (= 0.71.1)
- React-jsinspector (0.71.1)
- React-logger (0.71.1):
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.69.8):
- DoubleConversion
- glog
- react-native-update (8.1.0):
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-perflogger (= 0.69.8)
- React-jsinspector (0.69.8)
- React-logger (0.69.8):
- glog
- react-native-update (9.0.0):
- React
- react-native-update/HDiffPatch (= 8.1.0)
- react-native-update/RCTPushy (= 8.1.0)
- SSZipArchive
- react-native-update/HDiffPatch (8.1.0):
- React
- SSZipArchive
- react-native-update/RCTPushy (8.1.0):
- React
- SSZipArchive
- React-perflogger (0.71.1)
- React-RCTActionSheet (0.71.1):
- React-Core/RCTActionSheetHeaders (= 0.71.1)
- React-RCTAnimation (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTTypeSafety (= 0.71.1)
- React-Codegen (= 0.71.1)
- React-Core/RCTAnimationHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTAppDelegate (0.71.1):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React-Core
- ReactCommon/turbomodule/core
- React-RCTBlob (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- React-Codegen (= 0.71.1)
- React-Core/RCTBlobHeaders (= 0.71.1)
- React-Core/RCTWebSocket (= 0.71.1)
- React-jsi (= 0.71.1)
- React-RCTNetwork (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTImage (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTTypeSafety (= 0.71.1)
- React-Codegen (= 0.71.1)
- React-Core/RCTImageHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- React-RCTNetwork (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTLinking (0.71.1):
- React-Codegen (= 0.71.1)
- React-Core/RCTLinkingHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTNetwork (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTTypeSafety (= 0.71.1)
- React-Codegen (= 0.71.1)
- React-Core/RCTNetworkHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTSettings (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- RCTTypeSafety (= 0.71.1)
- React-Codegen (= 0.71.1)
- React-Core/RCTSettingsHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-RCTText (0.71.1):
- React-Core/RCTTextHeaders (= 0.71.1)
- React-RCTVibration (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- React-Codegen (= 0.71.1)
- React-Core/RCTVibrationHeaders (= 0.71.1)
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/core (= 0.71.1)
- React-runtimeexecutor (0.71.1):
- React-jsi (= 0.71.1)
- ReactCommon/turbomodule/bridging (0.71.1):
- react-native-update/HDiffPatch (= 9.0.0)
- react-native-update/RCTPushy (= 9.0.0)
- SSZipArchive
- react-native-update/HDiffPatch (9.0.0):
- React
- React-Core
- SSZipArchive
- react-native-update/RCTPushy (9.0.0):
- React
- React-Core
- SSZipArchive
- React-perflogger (0.69.8)
- React-RCTActionSheet (0.69.8):
- React-Core/RCTActionSheetHeaders (= 0.69.8)
- React-RCTAnimation (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.69.8)
- React-Core/RCTAnimationHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTBlob (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.69.8)
- React-Core/RCTBlobHeaders (= 0.69.8)
- React-Core/RCTWebSocket (= 0.69.8)
- React-jsi (= 0.69.8)
- React-RCTNetwork (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTImage (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.69.8)
- React-Core/RCTImageHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- React-RCTNetwork (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTLinking (0.69.8):
- React-Codegen (= 0.69.8)
- React-Core/RCTLinkingHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTNetwork (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.69.8)
- React-Core/RCTNetworkHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTSettings (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.69.8)
- React-Core/RCTSettingsHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTText (0.69.8):
- React-Core/RCTTextHeaders (= 0.69.8)
- React-RCTVibration (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.69.8)
- React-Core/RCTVibrationHeaders (= 0.69.8)
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.69.8)
- React-runtimeexecutor (0.69.8):
- React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (0.69.8):
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- React-callinvoker (= 0.71.1)
- React-Core (= 0.71.1)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-logger (= 0.71.1)
- React-perflogger (= 0.71.1)
- ReactCommon/turbomodule/core (0.71.1):
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- React-callinvoker (= 0.71.1)
- React-Core (= 0.71.1)
- React-cxxreact (= 0.71.1)
- React-jsi (= 0.71.1)
- React-logger (= 0.71.1)
- React-perflogger (= 0.71.1)
- RCT-Folly (= 2021.06.28.00-v2)
- React-bridging (= 0.69.8)
- React-callinvoker (= 0.69.8)
- React-Core (= 0.69.8)
- React-cxxreact (= 0.69.8)
- React-jsi (= 0.69.8)
- React-logger (= 0.69.8)
- React-perflogger (= 0.69.8)
- SocketRocket (0.6.0)
- SSZipArchive (2.4.3)
- Yoga (1.14.0)
@@ -422,13 +397,12 @@ DEPENDENCIES:
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.1100)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- React-bridging (from `../node_modules/react-native/ReactCommon`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`)
@@ -436,7 +410,6 @@ DEPENDENCIES:
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
- React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
@@ -445,7 +418,6 @@ DEPENDENCIES:
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
- React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
- React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
- React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
@@ -487,8 +459,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
hermes-engine:
:podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
@@ -497,6 +467,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/TypeSafety"
React:
:path: "../node_modules/react-native/"
React-bridging:
:path: "../node_modules/react-native/ReactCommon"
React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Codegen:
@@ -507,8 +479,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/CoreModules"
React-cxxreact:
:path: "../node_modules/react-native/ReactCommon/cxxreact"
React-hermes:
:path: "../node_modules/react-native/ReactCommon/hermes"
React-jsi:
:path: "../node_modules/react-native/ReactCommon/jsi"
React-jsiexecutor:
@@ -525,8 +495,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
:path: "../node_modules/react-native/Libraries/NativeAnimation"
React-RCTAppDelegate:
:path: "../node_modules/react-native/Libraries/AppDelegate"
React-RCTBlob:
:path: "../node_modules/react-native/Libraries/Blob"
React-RCTImage:
@@ -551,9 +519,9 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: ad72713385db5289b19f1ead07e8e4aa26dcb01d
FBReactNativeSpec: df2602c11e33d310433496e28a48b4b2be652a61
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: c7b6997d41fffaaaf4d18c82bc93885df731e2d0
FBReactNativeSpec: b1217c558a3ae84c2057d9c2ddce88af21379a68
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
@@ -564,43 +532,41 @@ SPEC CHECKSUMS:
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 476ee3e89abb49e07f822b48323c51c57124b572
hermes-engine: 922ccd744f50d9bfde09e9677bf0f3b562ea5fb9
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
RCTRequired: fd4d923b964658aa0c4091a32c8b2004c6d9e3a6
RCTTypeSafety: c276d85975bde3d8448907235c70bf0da257adfd
React: e481a67971af1ce9639c9f746b753dd0e84ca108
React-callinvoker: 1051c04a94fa9d243786b86380606bad701a3b31
React-Codegen: 14b1e716d361d5ad95e0ce1a338f3fa0733a98b5
React-Core: 698fc3baecb80d511d987475a16d036cec6d287f
React-CoreModules: 59245305f41ff0adfeac334acc0594dea4585a7c
React-cxxreact: 49accd2954b0f532805dbcd1918fa6962f32f247
React-hermes: d068733294581a085e95b6024e8d951b005e26d3
React-jsi: 122b9bce14f4c6c7cb58f28f87912cfe091885fa
React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa
React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07
React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75
react-native-update: 394b7f52ed3c0688d12084f3fb47d49504131be6
React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85
React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de
React-RCTAnimation: 168d53718c74153947c0109f55900faa64d79439
React-RCTAppDelegate: a8efbab128b34aa07a9491c85a41401210b1bec5
React-RCTBlob: 9bcbfc893bfda9f6b2eb016329d38c0f6366d31a
React-RCTImage: 3fcd4570b4b0f1ac2f4b4b6308dba33ce66c5b50
React-RCTLinking: 1edb8e1bb3fc39bf9e13c63d6aaaa3f0c3d18683
React-RCTNetwork: 500a79e0e0f67678077df727fabba87a55c043e1
React-RCTSettings: cc4414eb84ad756d619076c3999fecbf12896d6f
React-RCTText: 2a34261f3da6e34f47a62154def657546ebfa5e1
React-RCTVibration: 49d531ec8498e0afa2c9b22c2205784372e3d4f3
React-runtimeexecutor: 311feb67600774723fe10eb8801d3138cae9ad67
ReactCommon: 03be76588338a27a88d103b35c3c44a3fd43d136
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
RCTRequired: 344fd6fb3c669da87e91294be7ee0199bf35c701
RCTTypeSafety: ca608cc1d3a81229632bc0c1136b698b9337c1d8
React: 1d76bae8d73113b202224075f0b0bd546996b328
React-bridging: 2eb62dc8ba31194d285705cb62e24a15753aeaec
React-callinvoker: f3cfb045a0fb185445542555d88b6acf385cbedc
React-Codegen: 808e2d4d4201583ac89fb40d6862aaa26cb88999
React-Core: 82c5392ab182252ce4ffbc16794e0e38b32ea9a1
React-CoreModules: 4e891a6c0a59b01ca8406e041c7e49ab12e51d48
React-cxxreact: 0dc4ba3d97839bd36d422592ddb0bdfa9940a990
React-jsi: dcd936ff5e580dba0d8644ac9ee4ca47bb166df1
React-jsiexecutor: 2cf8ea3753afb81dfcc386613dbbb0b5d155fb34
React-jsinspector: 0eda09e9cf22bbb5dbb1d23143b03a31acf37d67
React-logger: 5997ab008583826c10ffe4e1ff990363e975639d
react-native-update: 2b5ef06bfeaa668614c8deb7ec4d20dcf56f9278
React-perflogger: ad1416a715d86b32f456e5d0aed99c3b52f1de37
React-RCTActionSheet: cbf7c6a953982562418ee72a1084ff7b9447b558
React-RCTAnimation: 33df3e25824dd7313edec28dded2745542f9352b
React-RCTBlob: 2434411df0d2d0e6567445a995f6678e2cc1d8e3
React-RCTImage: 0b912ab4255ea5ec903d06c77f5a23cea9e9c988
React-RCTLinking: eb239c24f4f5fe79c57a2fedf45f34f40481dda3
React-RCTNetwork: db173a6c35c1212909944920a5aa03eb8b7b9cf4
React-RCTSettings: 687fa7538972467d80cd7729b6f86598e1369813
React-RCTText: 605ef414f8e72bd111945d3612cd0518de612b24
React-RCTVibration: 5462287ee85304ba1a00474665ab292e63a41663
React-runtimeexecutor: 9df680f18497367bcf5c15b6b6406c0f2dfa2b6a
ReactCommon: c10f046f3ef8561e7c8e7e9b9dae2ecc9ffc48ef
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
Yoga: 921eb014669cf9c718ada68b08d362517d564e0c
Yoga: d3820731e0ca3a4933f061ad29defaf7726e3251
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 640d0fbc8653c12b1d7121eae0169fad3d42517e
PODFILE CHECKSUM: 618d17df10f335f1d113daac849a7997894646b2
COCOAPODS: 1.11.3

View File

@@ -1,6 +0,0 @@
#import <RCTAppDelegate.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : RCTAppDelegate
@end

View File

@@ -1,38 +0,0 @@
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import "RCTPushy.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.moduleName = @"testHotupdate";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
// 非DEBUG情况下替换为热更新bundle
return [RCTPushy bundleURL];
#endif
}
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
///
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
/// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
- (BOOL)concurrentRootEnabled
{
return true;
}
@end

View File

@@ -1,5 +1,5 @@
{
"name": "testhotupdate",
"name": "testHotUpdate",
"version": "0.0.1",
"private": true,
"scripts": {
@@ -7,29 +7,30 @@
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"test:e2e": "detox test --configuration android.emu.debug",
"lint": "eslint .",
"apk": "(cd android && ./gradlew aR)"
"postinstall": "patch-package"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.71.1",
"patch-package": "^6.5.1",
"postinstall-postinstall": "^2.1.0",
"react": "18.0.0",
"react-native": "0.69.8",
"react-native-update": "link:../.."
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native-community/eslint-config": "^3.0.0",
"@tsconfig/react-native": "^2.0.2",
"@types/jest": "^29.2.1",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.73.7",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0"
"@babel/core": "^7.21.0",
"@babel/runtime": "^7.21.0",
"@react-native-community/eslint-config": "^3.2.0",
"babel-jest": "^29.5.0",
"detox": "^20.5.0",
"eslint": "^8.36.0",
"jest": "^29.5.0",
"metro-react-native-babel-preset": "^0.76.0",
"pod-install": "^0.1.37",
"prettier": "^2.8.4",
"react-test-renderer": "18.2.0",
"ts-jest": "^29.0.5"
},
"jest": {
"preset": "react-native"

View File

@@ -0,0 +1,13 @@
diff --git a/node_modules/react-native/scripts/react_native_pods.rb b/node_modules/react-native/scripts/react_native_pods.rb
index e7c59ad..1461d45 100644
--- a/node_modules/react-native/scripts/react_native_pods.rb
+++ b/node_modules/react-native/scripts/react_native_pods.rb
@@ -420,7 +420,7 @@ def get_react_codegen_spec(options={})
'source' => { :git => '' },
'header_mappings_dir' => './',
'platforms' => {
- 'ios' => '11.0',
+ 'ios' => '12.0',
},
'source_files' => "**/*.{h,mm,cpp}",
'pod_target_xcconfig' => { "HEADER_SEARCH_PATHS" =>

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env bash
trap 'kill $RN_PID' EXIT
PLATFORM=$1
kill -9 $(lsof -i :8081 | awk '{print $2}' | tail -n +2) & npm start &
RN_PID=$!
sleep 2 && curl>/dev/null http://localhost:8081/index.bundle
wait $RN_PID

View File

@@ -1,21 +1,146 @@
import React from 'react';
/* eslint-disable react-native/no-inline-styles */
/* eslint-disable react/react-in-jsx-scope */
import {useCallback, useMemo, useState} from 'react';
import {
ActivityIndicator,
Alert,
Modal,
TextInput,
Button,
NativeModules,
StyleSheet,
SafeAreaView,
Text,
View,
TouchableOpacity,
} from 'react-native';
const Pushy = NativeModules.Pushy;
import {PushyModule} from 'react-native-update';
const Hash = '9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474';
const UUID = '00000000-0000-0000-0000-000000000000';
const DownloadUrl =
'http://cos.pgyer.com/697913e94d7441f20c686e2b0996a1aa.apk?sign=7a8f11b1df82cba45c8ac30b1acec88c&t=1680404102&response-content-disposition=attachment%3Bfilename%3DtestHotupdate_1.0.apk';
const CustomDialog = ({title, visible, onConfirm}) => {
if (!visible) {
return null;
}
return (
<View style={styles.overlay}>
<View style={styles.dialog}>
<Text style={styles.title}>{title}</Text>
<TouchableOpacity testID='done' style={styles.button} onLongPress={onConfirm}>
<Text style={styles.buttonText}>确认</Text>
</TouchableOpacity>
</View>
</View>
);
};
export default function TestConsole({visible}) {
const [text, setText] = React.useState('');
const [running, setRunning] = React.useState(false);
const [text, setText] = useState('');
const [running, setRunning] = useState(false);
const [options, setOptions] = useState();
const [alertVisible, setAlertVisible] = useState(false);
const [alertMsg, setAlertMsg] = useState('');
const NativeTestMethod = useMemo(() => {
return [
{
name: 'setLocalHashInfo',
invoke: () => {
setText(
`setLocalHashInfo\n${Hash}\n{\"version\":\"1.0.0\",\"size\":\"19M\"}`,
);
},
},
{
name: 'getLocalHashInfo',
invoke: () => {
setText(`getLocalHashInfo\n${Hash}`);
},
},
{
name: 'setUuid',
invoke: () => {
setText(`setUuid\n${UUID}`);
},
},
{
name: 'setBlockUpdate',
invoke: () => {
setText('setBlockUpdate');
setOptions({reason: 'application has been block', until: 1673082950});
},
},
{
name: 'reloadUpdate',
invoke: () => {
setText('reloadUpdate');
setOptions({hash: Hash});
},
},
{
name: 'setNeedUpdate',
invoke: () => {
setText('setNeedUpdate');
setOptions({hash: Hash});
},
},
{
name: 'markSuccess',
invoke: () => {
setText('markSuccess');
setOptions(undefined);
},
},
{
name: 'downloadPatchFromPpk',
invoke: () => {
setText('downloadPatchFromPpk');
setOptions({updateUrl: DownloadUrl, hash: Hash, originHash: Hash});
},
},
{
name: 'downloadPatchFromPackage',
invoke: () => {
setText('downloadPatchFromPackage');
setOptions({updateUrl: DownloadUrl, hash: Hash});
},
},
{
name: 'downloadFullUpdate',
invoke: () => {
setText('downloadFullUpdate');
setOptions({updateUrl: DownloadUrl, hash: Hash});
},
},
{
name: 'downloadAndInstallApk',
invoke: () => {
setText('downloadAndInstallApk');
setOptions({url: DownloadUrl, target: Hash, hash: Hash});
},
},
];
}, []);
const renderTestView = useCallback(() => {
const views = [];
for (let i = 0; i < NativeTestMethod.length; i++) {
views.push(
<TouchableOpacity
key={i}
testID={NativeTestMethod[i].name}
onLongPress={() => {
NativeTestMethod[i].invoke();
}}
>
<Text>{NativeTestMethod[i].name}</Text>
</TouchableOpacity>,
);
}
return <View>{views}</View>;
}, [NativeTestMethod]);
return (
<Modal visible={visible}>
<SafeAreaView style={{flex: 1, padding: 10}}>
@@ -38,39 +163,90 @@ export default function TestConsole({visible}) {
onChangeText={setText}
/>
{running && <ActivityIndicator />}
<Button
title="执行"
onPress={async () => {
<TouchableOpacity
style={{backgroundColor:'rgb(0,140,237)', justifyContent: 'center',
alignItems: 'center',paddingTop:10,paddingBottom:10,marginBottom:5}}
testID="submit"
onLongPress={async () => {
setRunning(true);
try {
const inputs = text.split('\n');
const methodName = inputs[0];
let params;
let params = [];
if (inputs.length === 1) {
await Pushy[methodName]();
if (options) {
await PushyModule[methodName](options);
} else {
await PushyModule[methodName]();
}
} else {
if (inputs.length === 2) {
params = inputs[1];
params = [inputs[1]];
} else {
params = {};
for (let i = 1; i < inputs.length; i += 2) {
params[inputs[i]] = inputs[i + 1];
}
params = [inputs[1], inputs[2]];
console.log({inputs, params});
}
await Pushy[methodName](params);
await PushyModule[methodName](...params);
}
Alert.alert('done');
setAlertVisible(true);
setAlertMsg('done');
} catch (e) {
Alert.alert(e.message);
setAlertVisible(true);
setAlertMsg(e.message);
}
setRunning(false);
}}
/>
<View style={{marginTop: 15}}>
<Button title="重置" onPress={() => setText('')} />
</View>
>
<Text style={{color:'white'}}>执行</Text>
</TouchableOpacity>
<Button title="重置" onPress={() => setText('')} />
{renderTestView()}
<CustomDialog
title={alertMsg}
visible={alertVisible}
onConfirm={()=>{setAlertVisible(false)}}
/>
</SafeAreaView>
</Modal>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
overlay: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
},
dialog: {
backgroundColor: 'white',
borderRadius: 10,
padding: 20,
width: '80%',
alignItems: 'center',
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 20,
},
button: {
backgroundColor: '#2196F3',
borderRadius: 5,
paddingVertical: 10,
paddingHorizontal: 20,
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
});

View File

@@ -170,6 +170,7 @@ export default class App extends Component {
</TouchableOpacity>
<TouchableOpacity
testID="testcase"
style={{marginTop: 15}}
onLongPress={() => {
this.setState({showTestConsole: true});

View File

@@ -0,0 +1,10 @@
{
"ios": {
"appId": 10976,
"appKey": "p5q_rPYNOE0WdCf-i9ZCGPw-DUGUCMvY"
},
"android": {
"appId": 10977,
"appKey": "bUYKfZgtC9VirZsQbAt8qken2Gq2uxe3"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。(暂不支持新架构,会待其相对稳定后跟进)
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。支持新架构
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
6. 支持崩溃回滚,安全可靠。
@@ -33,3 +33,4 @@ $ yarn start
本组件由[React Native 中文网](https://reactnative.cn/)独家发布,如有定制需求可以[联系我们](https://reactnative.cn/about.html#content)。
关于此插件发现任何问题,可以前往[Issues](https://github.com/reactnativecn/react-native-pushy/issues)发帖提问。

View File

@@ -5,9 +5,40 @@ def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}
def supportsNamespace() {
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
def major = parsed[0].toInteger()
def minor = parsed[1].toInteger()
// Namespace support was added in 7.3.0
if (major == 7 && minor >= 3) {
return true
}
return major >= 8
}
apply plugin: 'com.android.library'
if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}
android {
if (supportsNamespace()) {
namespace "cn.reactnative.modules.update"
sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
}
}
}
compileSdkVersion safeExtGet('compileSdkVersion', 28)
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
@@ -17,11 +48,17 @@ android {
versionCode 1
versionName "1.0"
consumerProguardFiles "proguard.pro"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['./lib']
if (isNewArchitectureEnabled()) {
java.srcDirs += ['src/newarch']
} else {
java.srcDirs += ['src/oldarch']
}
}
}
@@ -44,4 +81,12 @@ repositories {
dependencies {
implementation 'com.facebook.react:react-native:+'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
}
if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../lib/")
libraryName = "update"
codegenJavaPackageName = "cn.reactnative.modules.update"
}
}

View File

@@ -24,7 +24,7 @@ int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
mem_as_hStreamInput(&patStream,pat,pat+patsize);
if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0))
return kHPatch_error_info;//data error;
return kHPatch_ok; //ok
return kHPatch_ok; //ok
}
static hpatch_TDecompress* getDecompressPlugin(const char* compressType){
@@ -68,7 +68,7 @@ static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOld
_check(decompressPlugin,kHPatch_error_compressType);
}
}
{// mem
{// mem
size_t mem_size;
size_t oldSize=(size_t)old->streamSize;
isLoadOldAllToMem=isLoadOldAllToMem&&(old->streamSize<=kMaxLoadMemOldSize);
@@ -76,7 +76,7 @@ static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOld
mem_size=temp_cache_size+(isLoadOldAllToMem?oldSize:0);
temp_cache=malloc(mem_size);
_check(temp_cache,kHPatch_error_malloc);
if (isLoadOldAllToMem){//load old to mem
if (isLoadOldAllToMem){//load old to mem
uint8_t* oldMem=temp_cache+temp_cache_size;
_check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread);
mem_as_hStreamInput(&_old,oldMem,oldMem+oldSize);
@@ -95,7 +95,7 @@ _clear:
}
int hpatch_by_mem(const uint8_t* old,size_t oldsize,uint8_t* newBuf,size_t newsize,
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
hpatch_TStreamInput oldStream;
hpatch_TStreamInput patStream;
hpatch_TStreamOutput newStream;

View File

@@ -1,5 +1,5 @@
// hpatch.h
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
// hpatch.h
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
// Copyright 2021 housisong, All rights reserved
#ifndef HDIFFPATCH_PATCH_H
@@ -41,4 +41,4 @@ int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfi
#ifdef __cplusplus
}
#endif
#endif //HDIFFPATCH_PATCH_H
#endif //HDIFFPATCH_PATCH_H

View File

@@ -1,2 +1,3 @@
-keepnames class cn.reactnative.modules.update.DownloadTask { *; }
-keepnames class cn.reactnative.modules.update.UpdateModuleImpl { *; }
-keepnames class com.facebook.react.ReactInstanceManager { *; }

View File

@@ -1,9 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.reactnative.modules.update">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
<provider

View File

@@ -0,0 +1,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
<provider
android:name=".PushyFileProvider"
android:authorities="${applicationId}.pushy.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/pushy_file_paths" />
</provider>
</application>
</manifest>

View File

@@ -237,19 +237,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
while (entries.hasMoreElements()) {
ZipEntry ze = entries.nextElement();
String fn = ze.getName();
File fmd = new File(param.unzipDirectory, fn);
if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzipping " + fn);
}
if (ze.isDirectory()) {
fmd.mkdirs();
continue;
}
zipFile.unzipToFile(ze, fmd);
zipFile.unzipToPath(ze, param.unzipDirectory);
}
zipFile.close();
@@ -324,8 +312,15 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
} else {
target = copyList.get((from));
}
target.add(new File(param.unzipDirectory, to));
//copyFromResource(from, new File(param.unzipDirectory, to));
File toFile = new File(param.unzipDirectory, to);
// Fixing a Zip Path Traversal Vulnerability
// https://support.google.com/faqs/answer/9294009
String canonicalPath = toFile.getCanonicalPath();
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
throw new SecurityException("Illegal name: " + to);
}
target.add(toFile);
}
continue;
}
@@ -339,18 +334,9 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
fout.close();
continue;
}
File fmd = new File(param.unzipDirectory, fn);
if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzipping " + fn);
}
if (ze.isDirectory()) {
fmd.mkdirs();
continue;
}
zipFile.unzipToFile(ze, fmd);
zipFile.unzipToPath(ze, param.unzipDirectory);
}
zipFile.close();
@@ -419,18 +405,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
fout.close();
continue;
}
File fmd = new File(param.unzipDirectory, fn);
if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzipping " + fn);
}
if (ze.isDirectory()) {
fmd.mkdirs();
continue;
}
zipFile.unzipToFile(ze, fmd);
zipFile.unzipToPath(ze, param.unzipDirectory);
}
zipFile.close();

View File

@@ -1,7 +1,5 @@
package cn.reactnative.modules.update;
import android.content.Context;
import java.io.File;
/**

View File

@@ -1,5 +1,7 @@
package cn.reactnative.modules.update;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -10,12 +12,15 @@ import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class SafeZipFile extends ZipFile {
public SafeZipFile(File file) throws IOException {
super(file);
}
private static final int BUFFER_SIZE = 8192;
@Override
public Enumeration<? extends ZipEntry> entries() {
return new SafeZipEntryIterator(super.entries());
@@ -43,40 +48,46 @@ public class SafeZipFile extends ZipFile {
* avoid ZipperDown
*/
if (null != name && (name.contains("../") || name.contains("..\\"))) {
throw new SecurityException("illegal entry: " + entry.getName());
throw new SecurityException("illegal entry: " + name);
}
}
return entry;
}
}
public void unzipToFile(ZipEntry entry, File output) throws IOException {
InputStream inputStream = null;
try {
inputStream = getInputStream(entry);
writeOutInputStream(output, inputStream);
} finally {
if (inputStream != null) {
inputStream.close();
public void unzipToPath(ZipEntry ze, File targetPath) throws IOException {
String name = ze.getName();
File target = new File(targetPath, name);
// Fixing a Zip Path Traversal Vulnerability
// https://support.google.com/faqs/answer/9294009
String canonicalPath = target.getCanonicalPath();
if (!canonicalPath.startsWith(targetPath.getCanonicalPath() + File.separator)) {
throw new SecurityException("Illegal name: " + name);
}
if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzipping " + name);
}
if (ze.isDirectory()) {
target.mkdirs();
return;
}
unzipToFile(ze, target);
}
public void unzipToFile(ZipEntry ze, File target) throws IOException {
try (InputStream inputStream = getInputStream(ze)) {
try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(target));
BufferedInputStream input = new BufferedInputStream(inputStream)) {
byte[] buffer = new byte[BUFFER_SIZE];
int n;
while ((n = input.read(buffer, 0, BUFFER_SIZE)) >= 0) {
output.write(buffer, 0, n);
}
}
}
}
private void writeOutInputStream(File file, InputStream inputStream) throws IOException {
BufferedOutputStream output = null;
try {
output = new BufferedOutputStream(
new FileOutputStream(file));
BufferedInputStream input = new BufferedInputStream(inputStream);
byte b[] = new byte[8192];
int n;
while ((n = input.read(b, 0, 8192)) >= 0) {
output.write(b, 0, n);
}
} finally {
if (output != null) {
output.close();
}
}
}
}

View File

@@ -0,0 +1,265 @@
package cn.reactnative.modules.update;
import android.app.Activity;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.UiThreadUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class UpdateModuleImpl {
public static final String NAME = "Pushy";
public static void downloadFullUpdate(UpdateContext updateContext, ReadableMap options, Promise promise) {
String url = options.getString("updateUrl");
String hash = options.getString("hash");
updateContext.downloadFullUpdate(url, hash, new UpdateContext.DownloadFileListener() {
@Override
public void onDownloadCompleted(DownloadTaskParams params) {
promise.resolve(null);
}
@Override
public void onDownloadFailed(Throwable error) {
promise.reject(error);
}
});
}
public static void downloadAndInstallApk(UpdateContext updateContext, ReadableMap options, Promise promise) {
String url = options.getString("url");
String hash = options.getString("hash");
String target = options.getString("target");
updateContext.downloadFile(url, hash, target, new UpdateContext.DownloadFileListener() {
@Override
public void onDownloadCompleted(DownloadTaskParams params) {
UpdateModule.installApk(params.targetFile);
promise.resolve(null);
}
@Override
public void onDownloadFailed(Throwable error) {
promise.reject(error);
}
});
}
public static void installApk(String url) {
File toInstall = new File(url);
UpdateModule.installApk(toInstall);
}
public static void downloadPatchFromPackage(UpdateContext updateContext, ReadableMap options, Promise promise) {
String url = options.getString("updateUrl");
String hash = options.getString("hash");
updateContext.downloadPatchFromApk(url, hash, new UpdateContext.DownloadFileListener() {
@Override
public void onDownloadCompleted(DownloadTaskParams params) {
promise.resolve(null);
}
@Override
public void onDownloadFailed(Throwable error) {
promise.reject(error);
}
});
}
public static void downloadPatchFromPpk(UpdateContext updateContext, ReadableMap options, Promise promise) {
try {
String url = options.getString("updateUrl");
String hash = options.getString("hash");
String originHash = options.getString("originHash");
updateContext.downloadPatchFromPpk(url, hash, originHash, new UpdateContext.DownloadFileListener() {
@Override
public void onDownloadCompleted(DownloadTaskParams params) {
promise.resolve(null);
}
@Override
public void onDownloadFailed(Throwable error) {
promise.reject(error);
}
});
}catch (Exception e){
promise.reject("执行报错:"+e.getMessage());
}
}
public static void reloadUpdate(UpdateContext updateContext, ReactApplicationContext mContext, ReadableMap options,Promise promise) {
final String hash = options.getString("hash");
if(hash==null || hash.isEmpty()){
promise.reject("hash不能为空");
return;
}
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
updateContext.switchVersion(hash);
Activity activity = mContext.getCurrentActivity();
Application application = activity.getApplication();
ReactInstanceManager instanceManager = updateContext.getCustomReactInstanceManager();
if (instanceManager == null) {
instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
}
try {
JSBundleLoader loader = JSBundleLoader.createFileLoader(UpdateContext.getBundleUrl(application));
Field loadField = instanceManager.getClass().getDeclaredField("mBundleLoader");
loadField.setAccessible(true);
loadField.set(instanceManager, loader);
} catch (Throwable err) {
promise.reject("pushy:"+err.getMessage());
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
jsBundleField.setAccessible(true);
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
}
try {
instanceManager.recreateReactContextInBackground();
promise.resolve(true);
} catch (Throwable err) {
promise.reject("pushy:"+err.getMessage());
activity.recreate();
}
} catch (Throwable err) {
promise.reject("pushy:switchVersion failed"+err.getMessage());
Log.e("pushy", "switchVersion failed", err);
}
}
});
}
public static void setNeedUpdate(UpdateContext updateContext, ReadableMap options,Promise promise) {
try {
final String hash = options.getString("hash");
if(hash==null || hash.isEmpty()){
promise.reject("hash不能为空");
return;
}
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
try {
updateContext.switchVersion(hash);
promise.resolve(true);
} catch (Throwable err) {
promise.reject("switchVersionLater failed:"+err.getMessage());
Log.e("pushy", "switchVersionLater failed", err);
}
}
});
}catch (Exception e){
promise.reject("执行报错:"+e.getMessage());
}
}
public static void markSuccess(UpdateContext updateContext,Promise promise) {
try {
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
updateContext.markSuccess();
promise.resolve(true);
}
});
}catch (Exception e){
promise.reject("执行报错:"+e.getMessage());
}
}
public static void setBlockUpdate(UpdateContext updateContext, ReadableMap options,Promise promise) {
try {
final int until = options.getInt("until");
final String reason = options.getString("reason");
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
updateContext.setBlockUpdate(until, reason);
}
});
promise.resolve(true);
}catch (Exception e){
promise.reject("执行报错:"+e.getMessage());
}
}
public static void setUuid(UpdateContext updateContext, String uuid, Promise promise) {
try {
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
updateContext.setKv("uuid", uuid);
promise.resolve(true);
}
});
}catch (Exception e){
promise.reject("执行报错:"+e.getMessage());
}
}
public static boolean check(String json) {
ObjectMapper mapper = new ObjectMapper();
try {
mapper.readValue(json, Map.class);
System.out.println("String can be converted to Map");
return true;
} catch (IOException e) {
System.out.println("String cannot be converted to Map");
return false;
}
}
public static void setLocalHashInfo(UpdateContext updateContext, final String hash, final String info, Promise promise) {
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
if(!check(info)){
updateContext.setKv("hash_" + hash, info);
promise.reject("校验报错:json字符串格式错误");
}else {
updateContext.setKv("hash_" + hash, info);
promise.resolve(true);
}
}
});
}
public static void getLocalHashInfo(UpdateContext updateContext, final String hash, Promise promise) {
String value = updateContext.getKv("hash_" + hash);
if(check(value)){
promise.resolve(value);
}else {
promise.reject("校验报错:json字符串格式错误");
}
}
}

View File

@@ -1,34 +1,45 @@
package cn.reactnative.modules.update;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import androidx.annotation.Nullable;
import com.facebook.react.TurboReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import java.util.HashMap;
import java.util.Map;
/**
* Created by tdzl2003 on 3/31/16.
*/
public class UpdatePackage implements ReactPackage {
public class UpdatePackage extends TurboReactPackage {
@Nullable
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.asList(new NativeModule[]{
// Modules from third-party
new UpdateModule(reactContext),
});
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
if (name.equals(UpdateModuleImpl.NAME)) {
return new UpdateModule(reactContext);
} else {
return null;
}
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return () -> {
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
moduleInfos.put(
UpdateModuleImpl.NAME,
new ReactModuleInfo(
UpdateModuleImpl.NAME,
UpdateModuleImpl.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
isTurboModule // isTurboModule
));
return moduleInfos;
};
}
}

View File

@@ -0,0 +1,147 @@
package cn.reactnative.modules.update;
import static androidx.core.content.FileProvider.getUriForFile;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
public class UpdateModule extends NativeUpdateSpec {
UpdateContext updateContext;
public static ReactApplicationContext mContext;
public UpdateModule(ReactApplicationContext reactContext, UpdateContext updateContext) {
super(reactContext);
this.updateContext = updateContext;
mContext = reactContext;
}
public UpdateModule(ReactApplicationContext reactContext) {
this(reactContext, new UpdateContext(reactContext.getApplicationContext()));
}
@Override
protected Map<String, Object> getTypedExportedConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put("downloadRootDir", updateContext.getRootDir());
constants.put("packageVersion", updateContext.getPackageVersion());
constants.put("currentVersion", updateContext.getCurrentVersion());
constants.put("buildTime", updateContext.getBuildTime());
constants.put("isUsingBundleUrl", updateContext.getIsUsingBundleUrl());
boolean isFirstTime = updateContext.isFirstTime();
constants.put("isFirstTime", isFirstTime);
if (isFirstTime) {
updateContext.clearFirstTime();
}
String rolledBackVersion = updateContext.rolledBackVersion();
constants.put("rolledBackVersion", rolledBackVersion);
if (rolledBackVersion != null) {
updateContext.clearRollbackMark();
}
constants.put("blockUpdate", updateContext.getBlockUpdate());
constants.put("uuid", updateContext.getKv("uuid"));
return constants;
}
@Override
public String getName() {
return UpdateModuleImpl.NAME;
}
@Override
public void downloadFullUpdate(ReadableMap options, final Promise promise) {
UpdateModuleImpl.downloadFullUpdate(this.updateContext,options,promise);
}
@Override
public void downloadAndInstallApk(ReadableMap options, final Promise promise) {
UpdateModuleImpl.downloadAndInstallApk(this.updateContext,options,promise);
}
public static void installApk(File toInstall) {
Uri apkUri;
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
apkUri = getUriForFile(mContext, mContext.getPackageName() + ".pushy.fileprovider", toInstall);
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData(apkUri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
} else {
apkUri = Uri.fromFile(toInstall);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
mContext.startActivity(intent);
}
@Override
public void downloadPatchFromPackage(ReadableMap options, final Promise promise) {
UpdateModuleImpl.downloadPatchFromPackage(updateContext,options,promise);
}
@Override
public void downloadPatchFromPpk(ReadableMap options, final Promise promise) {
UpdateModuleImpl.downloadPatchFromPpk(updateContext,options,promise);
}
@Override
public void reloadUpdate(ReadableMap options,Promise promise) {
UpdateModuleImpl.reloadUpdate(updateContext, mContext, options,promise);
}
@Override
public void setNeedUpdate(ReadableMap options,Promise promise) {
UpdateModuleImpl.setNeedUpdate(updateContext, options,promise);
}
@Override
public void markSuccess(Promise promise) {
UpdateModuleImpl.markSuccess(updateContext,promise);
}
@Override
public void setBlockUpdate(ReadableMap options,Promise promise) {
UpdateModuleImpl.setBlockUpdate(updateContext,options,promise);
}
@Override
public void setUuid(final String uuid, Promise promise) {
UpdateModuleImpl.setUuid(updateContext,uuid,promise);
}
@Override
public void setLocalHashInfo(final String hash, final String info, final Promise promise) {
UpdateModuleImpl.setLocalHashInfo(updateContext,hash,info,promise);
}
@Override
public void getLocalHashInfo(final String hash, final Promise promise) {
UpdateModuleImpl.getLocalHashInfo(updateContext,hash,promise);
}
@Override
public void addListener(String eventName) {
// Set up any upstream listeners or background tasks as necessary
}
@Override
public void removeListeners(double count) {
// Remove upstream listeners, stop unnecessary background tasks
}
/* 发送事件*/
public static void sendEvent(String eventName, WritableMap params) {
((ReactContext) mContext).getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,
params);
}
}

View File

@@ -66,7 +66,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
@Override
public String getName() {
return "RCTPushy";
return UpdateModuleImpl.NAME;
}
@ReactMethod
@@ -169,7 +169,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
}
@ReactMethod
public void reloadUpdate(ReadableMap options) {
public void reloadUpdate(ReadableMap options, final Promise promise) {
final String hash = options.getString("hash");
UiThreadUtil.runOnUiThread(new Runnable() {
@@ -191,6 +191,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
loadField.setAccessible(true);
loadField.set(instanceManager, loader);
} catch (Throwable err) {
promise.reject(err);
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
jsBundleField.setAccessible(true);
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
@@ -198,11 +199,14 @@ public class UpdateModule extends ReactContextBaseJavaModule {
try {
instanceManager.recreateReactContextInBackground();
promise.resolve(null);
} catch (Throwable err) {
activity.recreate();
promise.reject(err);
}
} catch (Throwable err) {
promise.reject(err);
Log.e("pushy", "switchVersion failed", err);
}
}

12
e2e/jest.config.js Normal file
View File

@@ -0,0 +1,12 @@
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
rootDir: '..',
testMatch: ['<rootDir>/e2e/**/*.test.js'],
testTimeout: 120000,
maxWorkers: 1,
globalSetup: 'detox/runners/jest/globalSetup',
globalTeardown: 'detox/runners/jest/globalTeardown',
reporters: ['detox/runners/jest/reporter'],
testEnvironment: 'detox/runners/jest/testEnvironment',
verbose: true,
};

Some files were not shown because too many files have changed in this diff Show More