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

Compare commits

...

119 Commits

Author SHA1 Message Date
sunnylqm
4bf004a274 v10.1.0 2024-02-24 11:37:41 +08:00
sunnylqm
f01716bcb2 feat: add logger 2024-02-24 11:36:58 +08:00
sunnylqm
4f9e1495c8 v10.0.2 2024-02-19 11:42:17 +08:00
sunnylqm
9c06bac91b fix: dead loop 2024-02-19 11:41:17 +08:00
sunnylqm
4923aff184 v10.0.1 2024-02-19 09:37:31 +08:00
sunnylqm
f6a38c1f48 fix: default strategy 2024-02-19 09:36:53 +08:00
Sunny Luo
92cfbb3fdf Merge pull request #426 from reactnativecn/v10
V10
2024-02-08 22:07:46 +08:00
sunnylqm
64ef8e129d fix: update example 2024-02-08 22:06:59 +08:00
sunnylqm
ce51b2ca81 v10.0.0-beta.3 2024-02-08 21:50:54 +08:00
sunnylqm
6c1662fce1 feat: add progress 2024-02-08 21:50:17 +08:00
sunnylqm
d9e4575964 fix example 2024-02-05 22:50:46 +08:00
sunnylqm
190103687c fix: options 2024-02-05 22:22:11 +08:00
sunnylqm
f6f055be64 update update.json 2024-02-05 22:09:53 +08:00
sunnylqm
05e5c5a1a7 v10.0.0-beta.2 2024-01-25 22:09:35 +08:00
sunnylqm
296498e20a update 2024-01-22 18:39:52 +08:00
sunnylqm
2a3b8e5707 feat: update example 2024-01-22 15:55:52 +08:00
sunnylqm
e86df57476 v10.0.0-beta.1 2024-01-22 15:34:54 +08:00
sunnylqm
40b2e9dea0 v10.0.0-beta.0 2024-01-22 15:06:02 +08:00
sunnylqm
1afc896306 feat: new version 2024-01-21 22:23:51 +08:00
sunnylqm
36533d43c4 fix: new version 2024-01-21 14:41:06 +08:00
sunnylqm
e5405b4977 translate 2024-01-18 00:32:21 +08:00
sunnylqm
9d93faab31 v10 2024-01-18 00:22:17 +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
sunnylqm
65a332b88a update example to 0.71.1 2023-01-27 19:00:17 +08:00
116 changed files with 17617 additions and 4500 deletions

View File

@@ -1,29 +1,4 @@
{ {
"extends": "eslint-config-airbnb/base", "root": true,
"parser": "babel-eslint", "extends": "@react-native"
"env": {
"browser": true,
"node": true,
"mocha": true
},
"rules": {
// Disable for console/alert
"no-console": 0,
"no-alert": 0,
"indent": [2, 2, {"SwitchCase": 1}]
},
"plugins": [
"import"
],
"settings": {
"import/parser": "babel-eslint",
"import/resolve": {
"moduleDirectory": ["node_modules", "src"]
}
},
"globals": {
"__DEV__": true,
"__OPTION__": true
}
} }

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/ node_modules/
npm-debug.log npm-debug.log
Example/**/update.json Example/**/.update
Example/**/.pushy
Example/testHotUpdate/artifacts
yarn-error.log yarn-error.log
Example/testHotUpdate/.pushy

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
18

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

@@ -52,7 +52,6 @@ nonstrict-import=warn
deprecated-type=warn deprecated-type=warn
unsafe-getters-setters=warn unsafe-getters-setters=warn
unnecessary-invariant=warn unnecessary-invariant=warn
signature-verification-failure=warn
[strict] [strict]
deprecated-type deprecated-type
@@ -64,4 +63,4 @@ untyped-import
untyped-type-import untyped-type-import
[version] [version]
^0.170.0 ^0.176.3

View File

@@ -20,6 +20,7 @@ DerivedData
*.hmap *.hmap
*.ipa *.ipa
*.xcuserstate *.xcuserstate
ios/.xcode.env.local
# Android/IntelliJ # Android/IntelliJ
# #
@@ -49,9 +50,10 @@ buck-out/
# For more information about the recommended setup visit: # For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/ # https://docs.fastlane.tools/best-practices/source-control/
*/fastlane/report.xml **/fastlane/report.xml
*/fastlane/Preview.html **/fastlane/Preview.html
*/fastlane/screenshots **/fastlane/screenshots
**/fastlane/test_output
# Bundle artifact # Bundle artifact
*.jsbundle *.jsbundle

View File

@@ -0,0 +1 @@
18

View File

@@ -1 +1 @@
2.7.4 2.7.5

View File

@@ -1,112 +0,0 @@
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React from 'react';
import type {Node} from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
} from 'react-native';
import {
Colors,
DebugInstructions,
Header,
LearnMoreLinks,
ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';
const Section = ({children, title}): Node => {
const isDarkMode = useColorScheme() === 'dark';
return (
<View style={styles.sectionContainer}>
<Text
style={[
styles.sectionTitle,
{
color: isDarkMode ? Colors.white : Colors.black,
},
]}>
{title}
</Text>
<Text
style={[
styles.sectionDescription,
{
color: isDarkMode ? Colors.light : Colors.dark,
},
]}>
{children}
</Text>
</View>
);
};
const App: () => Node = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<Section title="Step One">
Edit <Text style={styles.highlight}>App.js</Text> to change this
screen and then come back to see your edits.
</Section>
<Section title="See Your Changes">
<ReloadInstructions />
</Section>
<Section title="Debug">
<DebugInstructions />
</Section>
<Section title="Learn More">
Read the docs to discover what to do next:
</Section>
<LearnMoreLinks />
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
},
highlight: {
fontWeight: '700',
},
});
export default App;

View File

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

View File

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

View File

@@ -1,7 +1,9 @@
apply plugin: "com.android.application" plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
import com.android.build.OutputFile import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os
/** /**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
@@ -135,11 +137,13 @@ android {
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig { defaultConfig {
applicationId "com.testhotupdate" applicationId "com.awesomeproject"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) { if (isNewArchitectureEnabled()) {
@@ -152,16 +156,13 @@ android {
"GENERATED_SRC_DIR=$buildDir/generated/source", "GENERATED_SRC_DIR=$buildDir/generated/source",
"PROJECT_BUILD_DIR=$buildDir", "PROJECT_BUILD_DIR=$buildDir",
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build" "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" cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
cppFlags "-std=c++17" cppFlags "-std=c++17"
// Make sure this target name is the same you specify inside the // Make sure this target name is the same you specify inside the
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable. // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
targets "testhotupdate_appmodules" targets "awesomeproject_appmodules"
// Fix for windows limit on number of character in file paths and in command lines
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
arguments "NDK_APP_SHORT_COMMANDS=true"
}
} }
} }
if (!enableSeparateBuildPerCPUArchitecture) { if (!enableSeparateBuildPerCPUArchitecture) {
@@ -239,6 +240,7 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
} }
} }
@@ -260,6 +262,8 @@ android {
} }
dependencies { dependencies {
androidTestImplementation('com.wix:detox:+')
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion //noinspection GradleDynamicVersion
@@ -281,9 +285,10 @@ dependencies {
} }
if (enableHermes) { if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/"; //noinspection GradleDynamicVersion
debugImplementation files(hermesPath + "hermes-debug.aar") implementation("com.facebook.react:hermes-engine:+") { // From node_modules
releaseImplementation files(hermesPath + "hermes-release.aar") exclude group:'com.facebook.fbjni'
}
} else { } else {
implementation jscFlavor implementation jscFlavor
} }
@@ -296,7 +301,11 @@ if (isNewArchitectureEnabled()) {
configurations.all { configurations.all {
resolutionStrategy.dependencySubstitution { resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native")) substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source") .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")
} }
} }
} }

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 * <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree. * directory of this source tree.
*/ */
package com.testhotupdate; package com.awesomeproject;
import android.content.Context; import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient; import com.facebook.flipper.android.AndroidFlipperClient;

View File

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

View File

@@ -1,4 +1,4 @@
package com.testhotupdate; package com.awesomeproject;
import com.facebook.react.ReactActivity; import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate; import com.facebook.react.ReactActivityDelegate;
@@ -12,12 +12,13 @@ public class MainActivity extends ReactActivity {
*/ */
@Override @Override
protected String getMainComponentName() { protected String getMainComponentName() {
return "testHotupdate"; return "AwesomeProject";
} }
/** /**
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
* you can specify the rendered you wish to use (Fabric or the older renderer). * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
* (Paper).
*/ */
@Override @Override
protected ReactActivityDelegate createReactActivityDelegate() { protected ReactActivityDelegate createReactActivityDelegate() {
@@ -36,5 +37,12 @@ public class MainActivity extends ReactActivity {
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
return reactRootView; 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

@@ -1,46 +1,54 @@
package com.testhotupdate; package com.awesomeproject;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import androidx.annotation.Nullable;
import com.facebook.react.PackageList; import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication; import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage; import com.facebook.react.ReactPackage;
import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
import com.testhotupdate.newarchitecture.MainApplicationReactNativeHost; import com.awesomeproject.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List; import java.util.List;
import cn.reactnative.modules.update.UpdateContext;
import cn.reactnative.modules.update.UpdatePackage;
public class MainApplication extends Application implements ReactApplication { public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) { new ReactNativeHost(this) {
@Override @Override
protected String getJSBundleFile() { public boolean getUseDeveloperSupport() {
return UpdateContext.getBundleUrl(MainApplication.this); return BuildConfig.DEBUG;
} }
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override @Nullable
protected List<ReactPackage> getPackages() { @Override
@SuppressWarnings("UnnecessaryLocalVariable") protected String getJSBundleFile() {
List<ReactPackage> packages = new PackageList(this).getPackages(); return UpdateContext.getBundleUrl(MainApplication.this);
// Packages that cannot be autolinked yet can be added manually here, for example: }
// packages.add(new MyReactNativePackage());
return packages;
}
@Override @Override
protected String getJSMainModuleName() { protected List<ReactPackage> getPackages() {
return "index"; @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 = private final ReactNativeHost mNewArchitectureNativeHost =
new MainApplicationReactNativeHost(this); new MainApplicationReactNativeHost(this);
@@ -78,7 +86,7 @@ public class MainApplication extends Application implements ReactApplication {
We use reflection here to pick up the class that initializes Flipper, We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode since Flipper library is not available in release mode
*/ */
Class<?> aClass = Class.forName("com.testhotupdate.ReactNativeFlipper"); Class<?> aClass = Class.forName("com.awesomeproject.ReactNativeFlipper");
aClass aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager); .invoke(null, context, reactInstanceManager);

View File

@@ -1,4 +1,4 @@
package com.testhotupdate.newarchitecture; package com.awesomeproject.newarchitecture;
import android.app.Application; import android.app.Application;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@@ -16,12 +16,12 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.UIManager;
import com.facebook.react.fabric.ComponentFactory; import com.facebook.react.fabric.ComponentFactory;
import com.facebook.react.fabric.CoreComponentsRegistry; import com.facebook.react.fabric.CoreComponentsRegistry;
import com.facebook.react.fabric.EmptyReactNativeConfig;
import com.facebook.react.fabric.FabricJSIModuleProvider; import com.facebook.react.fabric.FabricJSIModuleProvider;
import com.facebook.react.fabric.ReactNativeConfig;
import com.facebook.react.uimanager.ViewManagerRegistry; import com.facebook.react.uimanager.ViewManagerRegistry;
import com.testhotupdate.BuildConfig; import com.awesomeproject.BuildConfig;
import com.testhotupdate.newarchitecture.components.MainComponentsRegistry; import com.awesomeproject.newarchitecture.components.MainComponentsRegistry;
import com.testhotupdate.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate; import com.awesomeproject.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -105,7 +105,7 @@ public class MainApplicationReactNativeHost extends ReactNativeHost {
return new FabricJSIModuleProvider( return new FabricJSIModuleProvider(
reactApplicationContext, reactApplicationContext,
componentFactory, componentFactory,
new EmptyReactNativeConfig(), ReactNativeConfig.DEFAULT_CONFIG,
viewManagerRegistry); viewManagerRegistry);
} }
}); });

View File

@@ -1,4 +1,4 @@
package com.testhotupdate.newarchitecture.components; package com.awesomeproject.newarchitecture.components;
import com.facebook.jni.HybridData; import com.facebook.jni.HybridData;
import com.facebook.proguard.annotations.DoNotStrip; import com.facebook.proguard.annotations.DoNotStrip;

View File

@@ -1,4 +1,4 @@
package com.testhotupdate.newarchitecture.modules; package com.awesomeproject.newarchitecture.modules;
import com.facebook.jni.HybridData; import com.facebook.jni.HybridData;
import com.facebook.react.ReactPackage; import com.facebook.react.ReactPackage;
@@ -41,7 +41,7 @@ public class MainApplicationTurboModuleManagerDelegate
if (!sIsSoLibraryLoaded) { if (!sIsSoLibraryLoaded) {
// If you change the name of your application .so file in the Android.mk file, // If you change the name of your application .so file in the Android.mk file,
// make sure you update the name here as well. // make sure you update the name here as well.
SoLoader.loadLibrary("testhotupdate_appmodules"); SoLoader.loadLibrary("awesomeproject_appmodules");
sIsSoLibraryLoaded = true; sIsSoLibraryLoaded = true;
} }
} }

View File

@@ -10,14 +10,14 @@ include $(CLEAR_VARS)
LOCAL_PATH := $(THIS_DIR) LOCAL_PATH := $(THIS_DIR)
# You can customize the name of your application .so file here. # You can customize the name of your application .so file here.
LOCAL_MODULE := testhotupdate_appmodules LOCAL_MODULE := awesomeproject_appmodules
LOCAL_C_INCLUDES := $(LOCAL_PATH) LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
# If you wish to add a custom TurboModule or Fabric component in your app you # 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 # will have to uncomment those lines to include the generated source
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
# #
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
@@ -28,8 +28,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \
libfabricjni \ libfabricjni \
libfbjni \ libfbjni \
libfolly_futures \ libfolly_runtime \
libfolly_json \
libglog \ libglog \
libjsi \ libjsi \
libreact_codegen_rncore \ libreact_codegen_rncore \

View File

@@ -14,7 +14,7 @@ class MainApplicationTurboModuleManagerDelegate
public: public:
// Adapt it to the package you used for your Java class. // Adapt it to the package you used for your Java class.
static constexpr auto kJavaDescriptor = static constexpr auto kJavaDescriptor =
"Lcom/testhotupdate/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; "Lcom/awesomeproject/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>); static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);

View File

@@ -13,7 +13,7 @@ class MainComponentsRegistry
public: public:
// Adapt it to the package you used for your Java class. // Adapt it to the package you used for your Java class.
constexpr static auto kJavaDescriptor = constexpr static auto kJavaDescriptor =
"Lcom/testhotupdate/newarchitecture/components/MainComponentsRegistry;"; "Lcom/awesomeproject/newarchitecture/components/MainComponentsRegistry;";
static void registerNatives(); static void registerNatives();

View File

@@ -1,3 +1,3 @@
<resources> <resources>
<string name="app_name">testHotupdate</string> <string name="app_name">AwesomeProject</string>
</resources> </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

@@ -8,6 +8,7 @@ buildscript {
minSdkVersion = 21 minSdkVersion = 21
compileSdkVersion = 31 compileSdkVersion = 31
targetSdkVersion = 31 targetSdkVersion = 31
kotlinVersion = '1.6.10'
if (System.properties['os.arch'] == "aarch64") { if (System.properties['os.arch'] == "aarch64") {
// For M1 Users we need to use the NDK 24 which added support for aarch64 // For M1 Users we need to use the NDK 24 which added support for aarch64
@@ -22,11 +23,12 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath("com.android.tools.build:gradle:7.0.4") classpath("com.android.tools.build:gradle:7.1.1")
classpath("com.facebook.react:react-native-gradle-plugin") classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:4.1.2") classpath("de.undercouch:gradle-download-task:5.0.1")
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
} }
} }
@@ -48,6 +50,9 @@ allprojects {
} }
} }
google() google()
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}
maven { url 'https://www.jitpack.io' } maven { url 'https://www.jitpack.io' }
} }
} }

View File

@@ -1,4 +1,4 @@
rootProject.name = 'testHotupdate' rootProject.name = 'AwesomeProject'
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app' include ':app'
includeBuild('../node_modules/react-native-gradle-plugin') includeBuild('../node_modules/react-native-gradle-plugin')
@@ -6,4 +6,6 @@ includeBuild('../node_modules/react-native-gradle-plugin')
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
include(":ReactAndroid") include(":ReactAndroid")
project(":ReactAndroid").projectDir = file('../node_modules/react-native/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", "name": "AwesomeProject",
"displayName": "testHotupdate" "displayName": "AwesomeProject"
} }

View File

@@ -1,3 +1,8 @@
module.exports = { module.exports = {
presets: ['module:metro-react-native-babel-preset'], presets: ['module:metro-react-native-babel-preset'],
env: {
production: {
plugins: ['react-native-paper/babel'],
},
},
}; };

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

@@ -0,0 +1,11 @@
# This `.xcode.env` file is versioned and is used to source the environment
# 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)

View File

@@ -7,11 +7,12 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* testHotupdateTests.m */; }; 00E356F31AD99517003FC87E /* AwesomeProjectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* AwesomeProjectTests.m */; };
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */; }; 0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 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 */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -21,24 +22,27 @@
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1; proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A; remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = testHotupdate; remoteInfo = AwesomeProject;
}; };
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference 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>"; }; 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>"; }; 00E356F21AD99517003FC87E /* AwesomeProjectTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AwesomeProjectTests.m; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* testHotupdate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testHotupdate.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = testHotupdate/AppDelegate.h; sourceTree = "<group>"; }; 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 = testHotupdate/AppDelegate.mm; 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 = testHotupdate/Images.xcassets; 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 = testHotupdate/Info.plist; 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 = testHotupdate/main.m; sourceTree = "<group>"; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AwesomeProject/main.m; 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>"; }; 19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject-AwesomeProjectTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
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>"; }; 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>"; };
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotupdate.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 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>"; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = testHotupdate/LaunchScreen.storyboard; 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; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -47,6 +51,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
7699B88040F8A987B510C191 /* libPods-AwesomeProject-AwesomeProjectTests.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -54,20 +59,20 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */, 0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
00E356EF1AD99517003FC87E /* testHotupdateTests */ = { 00E356EF1AD99517003FC87E /* AwesomeProjectTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
00E356F21AD99517003FC87E /* testHotupdateTests.m */, 00E356F21AD99517003FC87E /* AwesomeProjectTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */, 00E356F01AD99517003FC87E /* Supporting Files */,
); );
path = testHotupdateTests; path = AwesomeProjectTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
00E356F01AD99517003FC87E /* Supporting Files */ = { 00E356F01AD99517003FC87E /* Supporting Files */ = {
@@ -78,7 +83,7 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
13B07FAE1A68108700A75B9A /* testHotupdate */ = { 13B07FAE1A68108700A75B9A /* AwesomeProject */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
@@ -88,14 +93,15 @@
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
13B07FB71A68108700A75B9A /* main.m */, 13B07FB71A68108700A75B9A /* main.m */,
); );
name = testHotupdate; name = AwesomeProject;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */, 5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */,
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -110,9 +116,9 @@
83CBB9F61A601CBA00E9B192 = { 83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
13B07FAE1A68108700A75B9A /* testHotupdate */, 13B07FAE1A68108700A75B9A /* AwesomeProject */,
832341AE1AAA6A7D00B99B32 /* Libraries */, 832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* testHotupdateTests */, 00E356EF1AD99517003FC87E /* AwesomeProjectTests */,
83CBBA001A601CBA00E9B192 /* Products */, 83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */, 2D16E6871FA4F8E400B85C8A /* Frameworks */,
BBD78D7AC51CEA395F1C20DB /* Pods */, BBD78D7AC51CEA395F1C20DB /* Pods */,
@@ -125,8 +131,8 @@
83CBBA001A601CBA00E9B192 /* Products */ = { 83CBBA001A601CBA00E9B192 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
13B07F961A680F5B00A75B9A /* testHotupdate.app */, 13B07F961A680F5B00A75B9A /* AwesomeProject.app */,
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */, 00E356EE1AD99517003FC87E /* AwesomeProjectTests.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -134,8 +140,10 @@
BBD78D7AC51CEA395F1C20DB /* Pods */ = { BBD78D7AC51CEA395F1C20DB /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */, 3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */,
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */, 5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */,
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */,
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */,
); );
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -143,27 +151,30 @@
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
00E356ED1AD99517003FC87E /* testHotupdateTests */ = { 00E356ED1AD99517003FC87E /* AwesomeProjectTests */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "AwesomeProjectTests" */;
buildPhases = ( buildPhases = (
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */, 00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */, 00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */, 00E356EC1AD99517003FC87E /* Resources */,
C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */,
F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
dependencies = ( dependencies = (
00E356F51AD99517003FC87E /* PBXTargetDependency */, 00E356F51AD99517003FC87E /* PBXTargetDependency */,
); );
name = testHotupdateTests; name = AwesomeProjectTests;
productName = testHotupdateTests; productName = AwesomeProjectTests;
productReference = 00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */; productReference = 00E356EE1AD99517003FC87E /* AwesomeProjectTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test"; productType = "com.apple.product-type.bundle.unit-test";
}; };
13B07F861A680F5B00A75B9A /* testHotupdate */ = { 13B07F861A680F5B00A75B9A /* AwesomeProject */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */;
buildPhases = ( buildPhases = (
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */, FD10A7F022414F080027D42C /* Start Packager */,
@@ -178,9 +189,9 @@
); );
dependencies = ( dependencies = (
); );
name = testHotupdate; name = AwesomeProject;
productName = testHotupdate; productName = AwesomeProject;
productReference = 13B07F961A680F5B00A75B9A /* testHotupdate.app */; productReference = 13B07F961A680F5B00A75B9A /* AwesomeProject.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@@ -200,7 +211,7 @@
}; };
}; };
}; };
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */;
compatibilityVersion = "Xcode 12.0"; compatibilityVersion = "Xcode 12.0";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
@@ -213,8 +224,8 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
13B07F861A680F5B00A75B9A /* testHotupdate */, 13B07F861A680F5B00A75B9A /* AwesomeProject */,
00E356ED1AD99517003FC87E /* testHotupdateTests */, 00E356ED1AD99517003FC87E /* AwesomeProjectTests */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@@ -245,13 +256,15 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"$(SRCROOT)/.xcode.env.local",
"$(SRCROOT)/.xcode.env",
); );
name = "Bundle React Native code and images"; name = "Bundle React Native code and images";
outputPaths = ( outputPaths = (
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; 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 */ = { 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
@@ -259,15 +272,37 @@
files = ( files = (
); );
inputFileListPaths = ( 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"; name = "[CP] Embed Pods Frameworks";
outputFileListPaths = ( 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; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; 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;
};
A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-AwesomeProject-AwesomeProjectTests-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; showEnvVarsInLog = 0;
}; };
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
@@ -285,28 +320,62 @@
outputFileListPaths = ( outputFileListPaths = (
); );
outputPaths = ( outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-testHotupdate-checkManifestLockResult.txt", "$(DERIVED_FILE_DIR)/Pods-AwesomeProject-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; 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 = "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; showEnvVarsInLog = 0;
}; };
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",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputFileListPaths = ( 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"; name = "[CP] Copy Pods Resources";
outputFileListPaths = ( 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; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; 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; showEnvVarsInLog = 0;
}; };
FD10A7F022414F080027D42C /* Start Packager */ = { FD10A7F022414F080027D42C /* Start Packager */ = {
@@ -335,7 +404,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */, 00E356F31AD99517003FC87E /* AwesomeProjectTests.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -353,7 +422,7 @@
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
target = 13B07F861A680F5B00A75B9A /* testHotupdate */; target = 13B07F861A680F5B00A75B9A /* AwesomeProject */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
}; };
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
@@ -361,14 +430,15 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = { 00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1", "DEBUG=1",
"$(inherited)", "$(inherited)",
); );
INFOPLIST_FILE = testHotupdateTests/Info.plist; INFOPLIST_FILE = AwesomeProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -381,17 +451,18 @@
); );
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AwesomeProject.app/AwesomeProject";
}; };
name = Debug; name = Debug;
}; };
00E356F71AD99517003FC87E /* Release */ = { 00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = testHotupdateTests/Info.plist; INFOPLIST_FILE = AwesomeProjectTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -404,19 +475,19 @@
); );
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AwesomeProject.app/AwesomeProject";
}; };
name = Release; name = Release;
}; };
13B07F941A680F5B00A75B9A /* Debug */ = { 13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */; baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = testHotupdate/Info.plist; INFOPLIST_FILE = AwesomeProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -427,7 +498,7 @@
"-lc++", "-lc++",
); );
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = testHotupdate; PRODUCT_NAME = AwesomeProject;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
@@ -436,12 +507,12 @@
}; };
13B07F951A680F5B00A75B9A /* Release */ = { 13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */; baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1; CURRENT_PROJECT_VERSION = 1;
INFOPLIST_FILE = testHotupdate/Info.plist; INFOPLIST_FILE = AwesomeProject/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -452,7 +523,7 @@
"-lc++", "-lc++",
); );
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = testHotupdate; PRODUCT_NAME = AwesomeProject;
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
@@ -507,7 +578,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift, /usr/lib/swift,
"$(inherited)", "$(inherited)",
@@ -525,6 +596,7 @@
"-DFOLLY_MOBILE=1", "-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1", "-DFOLLY_USE_LIBCPP=1",
); );
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
}; };
name = Debug; name = Debug;
@@ -571,7 +643,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 12.4;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
/usr/lib/swift, /usr/lib/swift,
"$(inherited)", "$(inherited)",
@@ -588,6 +660,7 @@
"-DFOLLY_MOBILE=1", "-DFOLLY_MOBILE=1",
"-DFOLLY_USE_LIBCPP=1", "-DFOLLY_USE_LIBCPP=1",
); );
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos; SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
@@ -596,7 +669,7 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */ = { 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "AwesomeProjectTests" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
00E356F61AD99517003FC87E /* Debug */, 00E356F61AD99517003FC87E /* Debug */,
@@ -605,7 +678,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */ = { 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
13B07F941A680F5B00A75B9A /* Debug */, 13B07F941A680F5B00A75B9A /* Debug */,
@@ -614,7 +687,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */ = { 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
83CBBA201A601CBA00E9B192 /* Debug */, 83CBBA201A601CBA00E9B192 /* Debug */,

View File

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

View File

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

@@ -1,9 +1,8 @@
#import "AppDelegate.h" #import "AppDelegate.h"
#import "RCTPushy.h"
#import <React/RCTBridge.h> #import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h> #import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h> #import <React/RCTRootView.h>
#import "RCTPushy.h"
#import <React/RCTAppSetupUtils.h> #import <React/RCTAppSetupUtils.h>
@@ -17,6 +16,8 @@
#import <react/config/ReactNativeConfig.h> #import <react/config/ReactNativeConfig.h>
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> { @interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
RCTTurboModuleManager *_turboModuleManager; RCTTurboModuleManager *_turboModuleManager;
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter; RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
@@ -42,7 +43,8 @@
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif #endif
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"testHotupdate", nil); NSDictionary *initProps = [self prepareInitialProps];
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"AwesomeProject", initProps);
if (@available(iOS 13.0, *)) { if (@available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor]; rootView.backgroundColor = [UIColor systemBackgroundColor];
@@ -58,12 +60,33 @@
return YES; 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 - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{ {
#if DEBUG #if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else #else
// 非DEBUG情况下替换为热更新bundle
return [RCTPushy bundleURL]; return [RCTPushy bundleURL];
#endif #endif
} }

View File

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

View File

@@ -16,7 +16,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <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"/> <rect key="frame" x="0.0" y="202" width="375" height="43"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>

View File

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

View File

@@ -1,10 +1,12 @@
require_relative '../node_modules/react-native/scripts/react_native_pods' require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '11.0' platform :ios, '12.4'
install! 'cocoapods', :deterministic_uuids => false install! 'cocoapods', :deterministic_uuids => false
target 'testHotupdate' do production = ENV["PRODUCTION"] == "1"
target 'AwesomeProject' do
config = use_native_modules! config = use_native_modules!
# Flags change depending on the env values. # Flags change depending on the env values.
@@ -13,18 +15,18 @@ target 'testHotupdate' do
use_react_native!( use_react_native!(
:path => config[:reactNativePath], :path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods # to enable hermes on iOS, change `false` to `true` and then install pods
:production => production,
:hermes_enabled => flags[:hermes_enabled], :hermes_enabled => flags[:hermes_enabled],
:fabric_enabled => flags[:fabric_enabled], :fabric_enabled => flags[:fabric_enabled],
:flipper_configuration => FlipperConfiguration.enabled,
# An absolute path to your application root. # An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.." :app_path => "#{Pod::Config.instance.installation_root}/.."
) )
target 'AwesomeProjectTests' do
# Enables Flipper. inherit! :complete
# # Pods for testing
# Note that if you have use_frameworks! enabled, Flipper will not work and end
# you should disable the next line.
use_flipper!()
post_install do |installer| post_install do |installer|
react_native_post_install(installer) react_native_post_install(installer)

View File

@@ -2,19 +2,19 @@ PODS:
- boost (1.76.0) - boost (1.76.0)
- CocoaAsyncSocket (7.6.5) - CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6) - DoubleConversion (1.1.6)
- FBLazyVector (0.68.2) - FBLazyVector (0.69.8)
- FBReactNativeSpec (0.68.2): - FBReactNativeSpec (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.2) - RCTRequired (= 0.69.8)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Core (= 0.68.2) - React-Core (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- Flipper (0.125.0): - Flipper (0.125.0):
- Flipper-Folly (~> 2.6) - Flipper-Folly (~> 2.6)
- Flipper-RSocket (~> 1.4) - Flipper-RSocket (~> 1.4)
- Flipper-Boost-iOSX (1.76.0.1.11) - Flipper-Boost-iOSX (1.76.0.1.11)
- Flipper-DoubleConversion (3.2.0) - Flipper-DoubleConversion (3.2.0.1)
- Flipper-Fmt (7.1.7) - Flipper-Fmt (7.1.7)
- Flipper-Folly (2.6.10): - Flipper-Folly (2.6.10):
- Flipper-Boost-iOSX - Flipper-Boost-iOSX
@@ -23,7 +23,7 @@ PODS:
- Flipper-Glog - Flipper-Glog
- libevent (~> 2.1.12) - libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.1100) - OpenSSL-Universal (= 1.1.1100)
- Flipper-Glog (0.5.0.4) - Flipper-Glog (0.5.0.5)
- Flipper-PeerTalk (0.0.4) - Flipper-PeerTalk (0.0.4)
- Flipper-RSocket (1.4.3): - Flipper-RSocket (1.4.3):
- Flipper-Folly (~> 2.6) - Flipper-Folly (~> 2.6)
@@ -86,278 +86,288 @@ PODS:
- DoubleConversion - DoubleConversion
- fmt (~> 6.2.1) - fmt (~> 6.2.1)
- glog - glog
- RCTRequired (0.68.2) - RCTRequired (0.69.8)
- RCTTypeSafety (0.68.2): - RCTTypeSafety (0.69.8):
- FBLazyVector (= 0.68.2) - 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) - RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.2) - React-jsi (= 0.69.8)
- React-Core (= 0.68.2) - React-callinvoker (0.69.8)
- React (0.68.2): - React-Codegen (0.69.8):
- React-Core (= 0.68.2) - FBReactNativeSpec (= 0.69.8)
- React-Core/DevSupport (= 0.68.2)
- React-Core/RCTWebSocket (= 0.68.2)
- React-RCTActionSheet (= 0.68.2)
- React-RCTAnimation (= 0.68.2)
- React-RCTBlob (= 0.68.2)
- React-RCTImage (= 0.68.2)
- React-RCTLinking (= 0.68.2)
- React-RCTNetwork (= 0.68.2)
- React-RCTSettings (= 0.68.2)
- React-RCTText (= 0.68.2)
- React-RCTVibration (= 0.68.2)
- React-callinvoker (0.68.2)
- React-Codegen (0.68.2):
- FBReactNativeSpec (= 0.68.2)
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.2) - RCTRequired (= 0.69.8)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Core (= 0.68.2) - React-Core (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-Core (0.68.2): - React-Core (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.2) - React-Core/Default (= 0.69.8)
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/CoreModulesHeaders (0.68.2): - React-Core/CoreModulesHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/Default (0.68.2): - React-Core/Default (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/DevSupport (0.68.2): - React-Core/DevSupport (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.2) - React-Core/Default (= 0.69.8)
- React-Core/RCTWebSocket (= 0.68.2) - React-Core/RCTWebSocket (= 0.69.8)
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-jsinspector (= 0.68.2) - React-jsinspector (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTActionSheetHeaders (0.68.2): - React-Core/RCTActionSheetHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTAnimationHeaders (0.68.2): - React-Core/RCTAnimationHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTBlobHeaders (0.68.2): - React-Core/RCTBlobHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTImageHeaders (0.68.2): - React-Core/RCTImageHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTLinkingHeaders (0.68.2): - React-Core/RCTLinkingHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTNetworkHeaders (0.68.2): - React-Core/RCTNetworkHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTSettingsHeaders (0.68.2): - React-Core/RCTSettingsHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTTextHeaders (0.68.2): - React-Core/RCTTextHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTVibrationHeaders (0.68.2): - React-Core/RCTVibrationHeaders (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default - React-Core/Default
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-Core/RCTWebSocket (0.68.2): - React-Core/RCTWebSocket (0.69.8):
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.2) - React-Core/Default (= 0.69.8)
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsiexecutor (= 0.68.2) - React-jsiexecutor (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- Yoga - Yoga
- React-CoreModules (0.68.2): - React-CoreModules (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/CoreModulesHeaders (= 0.68.2) - React-Core/CoreModulesHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-RCTImage (= 0.68.2) - React-RCTImage (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-cxxreact (0.68.2): - React-cxxreact (0.69.8):
- boost (= 1.76.0) - boost (= 1.76.0)
- DoubleConversion - DoubleConversion
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.68.2) - React-callinvoker (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-jsinspector (= 0.68.2) - React-jsinspector (= 0.69.8)
- React-logger (= 0.68.2) - React-logger (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- React-runtimeexecutor (= 0.68.2) - React-runtimeexecutor (= 0.69.8)
- React-jsi (0.68.2): - React-jsi (0.69.8):
- boost (= 1.76.0) - boost (= 1.76.0)
- DoubleConversion - DoubleConversion
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.68.2) - React-jsi/Default (= 0.69.8)
- React-jsi/Default (0.68.2): - React-jsi/Default (0.69.8):
- boost (= 1.76.0) - boost (= 1.76.0)
- DoubleConversion - DoubleConversion
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.68.2): - React-jsiexecutor (0.69.8):
- DoubleConversion - DoubleConversion
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-perflogger (= 0.68.2) - React-perflogger (= 0.69.8)
- React-jsinspector (0.68.2) - React-jsinspector (0.69.8)
- React-logger (0.68.2): - React-logger (0.69.8):
- glog - glog
- react-native-update (7.4.2): - react-native-safe-area-context (4.8.2):
- React-Core
- react-native-update (10.0.0-beta.1):
- React - React
- react-native-update/HDiffPatch (= 7.4.2) - React-Core
- react-native-update/RCTPushy (= 7.4.2) - react-native-update/HDiffPatch (= 10.0.0-beta.1)
- react-native-update/RCTPushy (= 10.0.0-beta.1)
- SSZipArchive - SSZipArchive
- react-native-update/HDiffPatch (7.4.2): - react-native-update/HDiffPatch (10.0.0-beta.1):
- React - React
- React-Core
- SSZipArchive - SSZipArchive
- react-native-update/RCTPushy (7.4.2): - react-native-update/RCTPushy (10.0.0-beta.1):
- React - React
- React-Core
- SSZipArchive - SSZipArchive
- React-perflogger (0.68.2) - React-perflogger (0.69.8)
- React-RCTActionSheet (0.68.2): - React-RCTActionSheet (0.69.8):
- React-Core/RCTActionSheetHeaders (= 0.68.2) - React-Core/RCTActionSheetHeaders (= 0.69.8)
- React-RCTAnimation (0.68.2): - React-RCTAnimation (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTAnimationHeaders (= 0.68.2) - React-Core/RCTAnimationHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTBlob (0.68.2): - React-RCTBlob (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTBlobHeaders (= 0.68.2) - React-Core/RCTBlobHeaders (= 0.69.8)
- React-Core/RCTWebSocket (= 0.68.2) - React-Core/RCTWebSocket (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-RCTNetwork (= 0.68.2) - React-RCTNetwork (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTImage (0.68.2): - React-RCTImage (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTImageHeaders (= 0.68.2) - React-Core/RCTImageHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- React-RCTNetwork (= 0.68.2) - React-RCTNetwork (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTLinking (0.68.2): - React-RCTLinking (0.69.8):
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTLinkingHeaders (= 0.68.2) - React-Core/RCTLinkingHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTNetwork (0.68.2): - React-RCTNetwork (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTNetworkHeaders (= 0.68.2) - React-Core/RCTNetworkHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTSettings (0.68.2): - React-RCTSettings (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.2) - RCTTypeSafety (= 0.69.8)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTSettingsHeaders (= 0.68.2) - React-Core/RCTSettingsHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-RCTText (0.68.2): - React-RCTText (0.69.8):
- React-Core/RCTTextHeaders (= 0.68.2) - React-Core/RCTTextHeaders (= 0.69.8)
- React-RCTVibration (0.68.2): - React-RCTVibration (0.69.8):
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.68.2) - React-Codegen (= 0.69.8)
- React-Core/RCTVibrationHeaders (= 0.68.2) - React-Core/RCTVibrationHeaders (= 0.69.8)
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (= 0.68.2) - ReactCommon/turbomodule/core (= 0.69.8)
- React-runtimeexecutor (0.68.2): - React-runtimeexecutor (0.69.8):
- React-jsi (= 0.68.2) - React-jsi (= 0.69.8)
- ReactCommon/turbomodule/core (0.68.2): - ReactCommon/turbomodule/core (0.69.8):
- DoubleConversion - DoubleConversion
- glog - glog
- RCT-Folly (= 2021.06.28.00-v2) - RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.68.2) - React-bridging (= 0.69.8)
- React-Core (= 0.68.2) - React-callinvoker (= 0.69.8)
- React-cxxreact (= 0.68.2) - React-Core (= 0.69.8)
- React-jsi (= 0.68.2) - React-cxxreact (= 0.69.8)
- React-logger (= 0.68.2) - React-jsi (= 0.69.8)
- React-perflogger (= 0.68.2) - React-logger (= 0.69.8)
- React-perflogger (= 0.69.8)
- RNVectorIcons (10.0.3):
- React-Core
- SocketRocket (0.6.0) - SocketRocket (0.6.0)
- SSZipArchive (2.4.3) - SSZipArchive (2.4.3)
- Yoga (1.14.0) - Yoga (1.14.0)
@@ -371,10 +381,10 @@ DEPENDENCIES:
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- Flipper (= 0.125.0) - Flipper (= 0.125.0)
- Flipper-Boost-iOSX (= 1.76.0.1.11) - Flipper-Boost-iOSX (= 1.76.0.1.11)
- Flipper-DoubleConversion (= 3.2.0) - Flipper-DoubleConversion (= 3.2.0.1)
- Flipper-Fmt (= 7.1.7) - Flipper-Fmt (= 7.1.7)
- Flipper-Folly (= 2.6.10) - Flipper-Folly (= 2.6.10)
- Flipper-Glog (= 0.5.0.4) - Flipper-Glog (= 0.5.0.5)
- Flipper-PeerTalk (= 0.0.4) - Flipper-PeerTalk (= 0.0.4)
- Flipper-RSocket (= 1.4.3) - Flipper-RSocket (= 1.4.3)
- FlipperKit (= 0.125.0) - FlipperKit (= 0.125.0)
@@ -396,6 +406,7 @@ DEPENDENCIES:
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`) - React (from `../node_modules/react-native/`)
- React-bridging (from `../node_modules/react-native/ReactCommon`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`) - React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`) - React-Core (from `../node_modules/react-native/`)
@@ -407,7 +418,8 @@ DEPENDENCIES:
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
- React-logger (from `../node_modules/react-native/ReactCommon/logger`) - React-logger (from `../node_modules/react-native/ReactCommon/logger`)
- react-native-update (from `../../..`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-update (from `../node_modules/react-native-update`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
@@ -420,6 +432,7 @@ DEPENDENCIES:
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS: SPEC REPOS:
@@ -460,6 +473,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/TypeSafety" :path: "../node_modules/react-native/Libraries/TypeSafety"
React: React:
:path: "../node_modules/react-native/" :path: "../node_modules/react-native/"
React-bridging:
:path: "../node_modules/react-native/ReactCommon"
React-callinvoker: React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker" :path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Codegen: React-Codegen:
@@ -478,8 +493,10 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/jsinspector" :path: "../node_modules/react-native/ReactCommon/jsinspector"
React-logger: React-logger:
:path: "../node_modules/react-native/ReactCommon/logger" :path: "../node_modules/react-native/ReactCommon/logger"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-update: react-native-update:
:path: "../../.." :path: "../node_modules/react-native-update"
React-perflogger: React-perflogger:
:path: "../node_modules/react-native/ReactCommon/reactperflogger" :path: "../node_modules/react-native/ReactCommon/reactperflogger"
React-RCTActionSheet: React-RCTActionSheet:
@@ -504,59 +521,64 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor" :path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
ReactCommon: ReactCommon:
:path: "../node_modules/react-native/ReactCommon" :path: "../node_modules/react-native/ReactCommon"
RNVectorIcons:
:path: "../node_modules/react-native-vector-icons"
Yoga: Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga" :path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS: SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234 boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: a7a655862f6b09625d11c772296b01cd5164b648 FBLazyVector: c7b6997d41fffaaaf4d18c82bc93885df731e2d0
FBReactNativeSpec: 81ce99032d5b586fddd6a38d450f8595f7e04be4 FBReactNativeSpec: b1217c558a3ae84c2057d9c2ddce88af21379a68
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 3d3d04a078d4f3a1b6c6916587f159dc11f232c4 Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
Flipper-Glog: 87bc98ff48de90cb5b0b5114ed3da79d85ee2dd4 Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541 Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86 FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 476ee3e89abb49e07f822b48323c51c57124b572 glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8 RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
RCTRequired: 3e917ea5377751094f38145fdece525aa90545a0 RCTRequired: 344fd6fb3c669da87e91294be7ee0199bf35c701
RCTTypeSafety: c43c072a4bd60feb49a9570b0517892b4305c45e RCTTypeSafety: ca608cc1d3a81229632bc0c1136b698b9337c1d8
React: 176dd882de001854ced260fad41bb68a31aa4bd0 React: 1d76bae8d73113b202224075f0b0bd546996b328
React-callinvoker: c2864d1818d6e64928d2faf774a3800dfc38fe1f React-bridging: 2eb62dc8ba31194d285705cb62e24a15753aeaec
React-Codegen: 98b6f97f0a7abf7d67e4ce435c77c05b7a95cf05 React-callinvoker: f3cfb045a0fb185445542555d88b6acf385cbedc
React-Core: fdaa2916b1c893f39f02cff0476d1fb0cab1e352 React-Codegen: 808e2d4d4201583ac89fb40d6862aaa26cb88999
React-CoreModules: fd8705b80699ec36c2cdd635c2ce9d874b9cfdfc React-Core: 82c5392ab182252ce4ffbc16794e0e38b32ea9a1
React-cxxreact: 1832d971f7b0cb2c7b943dc0ec962762c90c906e React-CoreModules: 4e891a6c0a59b01ca8406e041c7e49ab12e51d48
React-jsi: 72af715135abe8c3f0dcf3b2548b71d048b69a7e React-cxxreact: 0dc4ba3d97839bd36d422592ddb0bdfa9940a990
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6 React-jsi: dcd936ff5e580dba0d8644ac9ee4ca47bb166df1
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8 React-jsiexecutor: 2cf8ea3753afb81dfcc386613dbbb0b5d155fb34
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1 React-jsinspector: 0eda09e9cf22bbb5dbb1d23143b03a31acf37d67
react-native-update: 35b44bdcfd37e0f0bbef8ceb1bdda85067e591ff React-logger: 5997ab008583826c10ffe4e1ff990363e975639d
React-perflogger: a18b4f0bd933b8b24ecf9f3c54f9bf65180f3fe6 react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89
React-RCTActionSheet: 547fe42fdb4b6089598d79f8e1d855d7c23e2162 react-native-update: 767449a2cf592387b9aecb97980ec0536d72c890
React-RCTAnimation: bc9440a1c37b06ae9ebbb532d244f607805c6034 React-perflogger: ad1416a715d86b32f456e5d0aed99c3b52f1de37
React-RCTBlob: a1295c8e183756d7ef30ba6e8f8144dfe8a19215 React-RCTActionSheet: cbf7c6a953982562418ee72a1084ff7b9447b558
React-RCTImage: a30d1ee09b1334067fbb6f30789aae2d7ac150c9 React-RCTAnimation: 33df3e25824dd7313edec28dded2745542f9352b
React-RCTLinking: ffc6d5b88d1cb9aca13c54c2ec6507fbf07f2ac4 React-RCTBlob: 2434411df0d2d0e6567445a995f6678e2cc1d8e3
React-RCTNetwork: f807a2facab6cf5cf36d592e634611de9cf12d81 React-RCTImage: 0b912ab4255ea5ec903d06c77f5a23cea9e9c988
React-RCTSettings: 861806819226ed8332e6a8f90df2951a34bb3e7f React-RCTLinking: eb239c24f4f5fe79c57a2fedf45f34f40481dda3
React-RCTText: f3fb464cc41a50fc7a1aba4deeb76a9ad8282cb9 React-RCTNetwork: db173a6c35c1212909944920a5aa03eb8b7b9cf4
React-RCTVibration: 79040b92bfa9c3c2d2cb4f57e981164ec7ab9374 React-RCTSettings: 687fa7538972467d80cd7729b6f86598e1369813
React-runtimeexecutor: b960b687d2dfef0d3761fbb187e01812ebab8b23 React-RCTText: 605ef414f8e72bd111945d3612cd0518de612b24
ReactCommon: 095366164a276d91ea704ce53cb03825c487a3f2 React-RCTVibration: 5462287ee85304ba1a00474665ab292e63a41663
React-runtimeexecutor: 9df680f18497367bcf5c15b6b6406c0f2dfa2b6a
ReactCommon: c10f046f3ef8561e7c8e7e9b9dae2ecc9ffc48ef
RNVectorIcons: bc7ee28cadf39c77a49232a14738dfce690f66cd
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952 Yoga: d3820731e0ca3a4933f061ad29defaf7726e3251
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 3360a41d7ffd204bbb0ce92d9f9025f372649143 PODFILE CHECKSUM: 618d17df10f335f1d113daac849a7997894646b2
COCOAPODS: 1.11.3 COCOAPODS: 1.14.3

View File

@@ -1,11 +1,12 @@
const path = require('path'); const path = require('path');
const extraNodeModules = { // const extraNodeModules = {
'react-native': path.resolve(__dirname, 'node_modules/react-native'), // react: path.resolve(__dirname, 'node_modules/react'),
'react-native-update': path.resolve(__dirname, '../..'), // 'react-native': path.resolve(__dirname, 'node_modules/react-native'),
'@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'), // 'react-native-update': path.resolve(__dirname, '../..'),
}; // '@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
const watchFolders = [path.resolve(__dirname, '../..')]; // };
// const watchFolders = [path.resolve(__dirname, '../..')];
module.exports = { module.exports = {
transformer: { transformer: {
@@ -16,8 +17,8 @@ module.exports = {
}, },
}), }),
}, },
resolver: { // resolver: {
extraNodeModules, // extraNodeModules,
}, // },
watchFolders, // watchFolders,
}; };

View File

@@ -1,5 +1,5 @@
{ {
"name": "testhotupdate", "name": "testHotUpdate",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
@@ -7,23 +7,33 @@
"ios": "react-native run-ios", "ios": "react-native run-ios",
"start": "react-native start", "start": "react-native start",
"test": "jest", "test": "jest",
"test:e2e": "detox test --configuration android.emu.debug",
"lint": "eslint .", "lint": "eslint .",
"apk": "(cd android && ./gradlew aR)" "postinstall": "patch-package"
}, },
"dependencies": { "dependencies": {
"react": "17.0.2", "patch-package": "^6.5.1",
"react-native": "0.68.5", "postinstall-postinstall": "^2.1.0",
"react-native-update": "link:../.." "react": "18.0.0",
"react-native": "0.69.8",
"react-native-paper": "^5.12.1",
"react-native-safe-area-context": "^4.8.2",
"react-native-update": "^10.0.2",
"react-native-vector-icons": "^10.0.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.9", "@babel/core": "^7.21.0",
"@babel/runtime": "^7.12.5", "@babel/runtime": "^7.21.0",
"@react-native-community/eslint-config": "^2.0.0", "@react-native-community/eslint-config": "^3.2.0",
"babel-jest": "^26.6.3", "babel-jest": "^29.5.0",
"eslint": "^7.32.0", "detox": "^20.5.0",
"jest": "^26.6.3", "eslint": "^8.36.0",
"metro-react-native-babel-preset": "^0.67.0", "jest": "^29.5.0",
"react-test-renderer": "17.0.2" "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": { "jest": {
"preset": "react-native" "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 { import {
ActivityIndicator, ActivityIndicator,
Alert,
Modal, Modal,
TextInput, TextInput,
Button, Button,
NativeModules,
StyleSheet, StyleSheet,
SafeAreaView, SafeAreaView,
Text, Text,
View, View,
TouchableOpacity,
} from 'react-native'; } 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}) { export default function TestConsole({visible}) {
const [text, setText] = React.useState(''); const [text, setText] = useState('');
const [running, setRunning] = React.useState(false); 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 ( return (
<Modal visible={visible}> <Modal visible={visible}>
<SafeAreaView style={{flex: 1, padding: 10}}> <SafeAreaView style={{flex: 1, padding: 10}}>
@@ -38,39 +163,90 @@ export default function TestConsole({visible}) {
onChangeText={setText} onChangeText={setText}
/> />
{running && <ActivityIndicator />} {running && <ActivityIndicator />}
<Button <TouchableOpacity
title="执行" style={{backgroundColor:'rgb(0,140,237)', justifyContent: 'center',
onPress={async () => { alignItems: 'center',paddingTop:10,paddingBottom:10,marginBottom:5}}
testID="submit"
onLongPress={async () => {
setRunning(true); setRunning(true);
try { try {
const inputs = text.split('\n'); const inputs = text.split('\n');
const methodName = inputs[0]; const methodName = inputs[0];
let params; let params = [];
if (inputs.length === 1) { if (inputs.length === 1) {
await Pushy[methodName](); if (options) {
await PushyModule[methodName](options);
} else {
await PushyModule[methodName]();
}
} else { } else {
if (inputs.length === 2) { if (inputs.length === 2) {
params = inputs[1]; params = [inputs[1]];
} else { } else {
params = {}; params = [inputs[1], inputs[2]];
for (let i = 1; i < inputs.length; i += 2) {
params[inputs[i]] = inputs[i + 1];
}
console.log({inputs, params}); console.log({inputs, params});
} }
await Pushy[methodName](params); await PushyModule[methodName](...params);
} }
Alert.alert('done'); setAlertVisible(true);
setAlertMsg('done');
} catch (e) { } catch (e) {
Alert.alert(e.message); setAlertVisible(true);
setAlertMsg(e.message);
} }
setRunning(false); setRunning(false);
}} }}
/> >
<View style={{marginTop: 15}}> <Text style={{color:'white'}}>执行</Text>
<Button title="重置" onPress={() => setText('')} /> </TouchableOpacity>
</View> <Button title="重置" onPress={() => setText('')} />
{renderTestView()}
<CustomDialog
title={alertMsg}
visible={alertVisible}
onConfirm={()=>{setAlertVisible(false)}}
/>
</SafeAreaView> </SafeAreaView>
</Modal> </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

@@ -1,205 +0,0 @@
import React, {Component} from 'react';
import {
StyleSheet,
Platform,
Text,
View,
Alert,
TouchableOpacity,
Linking,
Image,
} from 'react-native';
import {
isFirstTime,
isRolledBack,
packageVersion,
currentVersion,
checkUpdate,
downloadUpdate,
switchVersion,
switchVersionLater,
markSuccess,
downloadAndInstallApk,
cInfo,
} from 'react-native-update';
import TestConsole from './TestConsole';
import _updateConfig from '../update.json';
const {appKey} = _updateConfig[Platform.OS];
export default class App extends Component {
state = {
received: 0,
total: 0,
showTestConsole: false,
};
componentDidMount() {
if (isRolledBack) {
Alert.alert('提示', '刚刚更新失败了,版本被回滚.');
} else if (isFirstTime) {
Alert.alert(
'提示',
'这是当前版本第一次启动,是否要模拟启动失败?将回滚到上一版本',
[
{
text: '是',
onPress: () => {
throw new Error('模拟启动失败,请重启应用');
},
},
{
text: '否',
onPress: () => {
markSuccess();
},
},
],
);
}
}
doUpdate = async info => {
try {
const hash = await downloadUpdate(info, {
onDownloadProgress: ({received, total}) => {
this.setState({
received,
total,
});
},
});
if (!hash) {
return;
}
Alert.alert('提示', '下载完毕,是否重启应用?', [
{
text: '是',
onPress: () => {
switchVersion(hash);
},
},
{text: '否'},
{
text: '下次启动时',
onPress: () => {
switchVersionLater(hash);
},
},
]);
} catch (err) {
Alert.alert('更新失败', err.message);
}
};
checkUpdate = async () => {
let info;
try {
info = await checkUpdate(appKey);
} catch (err) {
Alert.alert('更新检查失败', err.message);
return;
}
if (info.expired) {
Alert.alert('提示', '您的应用版本已更新,点击确定下载安装新版本', [
{
text: '确定',
onPress: () => {
if (info.downloadUrl) {
// apk可直接下载安装
if (
Platform.OS === 'android' &&
info.downloadUrl.endsWith('.apk')
) {
downloadAndInstallApk({
url: info.downloadUrl,
onDownloadProgress: ({received, total}) => {
this.setState({
received,
total,
});
},
});
} else {
Linking.openURL(info.downloadUrl);
}
}
},
},
]);
} else if (info.upToDate) {
Alert.alert('提示', '您的应用版本已是最新.');
} else {
Alert.alert(
'提示',
'检查到新的版本' + info.name + ',是否下载?\n' + info.description,
[
{
text: '是',
onPress: () => {
this.doUpdate(info);
},
},
{text: '否'},
],
);
}
};
render() {
const {received, total, showTestConsole} = this.state;
return (
<View style={styles.container}>
<Text style={styles.welcome}>欢迎使用热更新服务</Text>
<Image
resizeMode={'contain'}
source={require('./assets/shezhi.png')}
style={styles.image}
/>
<Text style={styles.instructions}>
这是版本一 {'\n'}
当前原生包版本号: {packageVersion}
{'\n'}
当前热更新版本Hash: {currentVersion || '(空)'}
{'\n'}
</Text>
<Text>
下载进度{received} / {total}
</Text>
<TouchableOpacity onPress={this.checkUpdate}>
<Text style={styles.instructions}>点击这里检查更新</Text>
</TouchableOpacity>
<TouchableOpacity
style={{marginTop: 15}}
onLongPress={() => {
this.setState({showTestConsole: true});
}}>
<Text style={styles.instructions}>
react-native-update版本{cInfo.pushy}
</Text>
</TouchableOpacity>
<TestConsole visible={showTestConsole} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
image: {},
});

View File

@@ -0,0 +1,166 @@
import React, {useState} from 'react';
import {
StyleSheet,
Platform,
Text,
View,
TouchableOpacity,
Image,
Switch,
} from 'react-native';
import {Icon, PaperProvider, Snackbar, Banner} from 'react-native-paper';
import TestConsole from './TestConsole';
import _updateConfig from '../update.json';
import {PushyProvider, Pushy, usePushy} from 'react-native-update';
const {appKey} = _updateConfig[Platform.OS];
function App() {
const {
client,
checkUpdate,
downloadUpdate,
switchVersionLater,
switchVersion,
updateInfo,
packageVersion,
currentHash,
progress: {received, total} = {},
} = usePushy();
const [useDefaultAlert, setUseDefaultAlert] = useState(true);
const [showTestConsole, setShowTestConsole] = useState(false);
const [showUpdateBanner, setShowUpdateBanner] = useState(false);
const [showUpdateSnackbar, setShowUpdateSnackbar] = useState(false);
const snackbarVisible =
!useDefaultAlert && showUpdateSnackbar && updateInfo?.update;
return (
<View style={styles.container}>
<Text style={styles.welcome}>使Pushy热更新服务</Text>
<View style={{flexDirection: 'row'}}>
<Text>
{useDefaultAlert ? '当前使用' : '当前不使用'}alert更新提示
</Text>
<Switch
value={useDefaultAlert}
onValueChange={v => {
setUseDefaultAlert(v);
client?.setOptions({
useAlert: v,
});
setShowUpdateSnackbar(!v);
}}
/>
</View>
<Image
resizeMode={'contain'}
source={require('./assets/shezhi.png')}
style={styles.image}
/>
<Text style={styles.instructions}>
{'\n'}
: {packageVersion}
{'\n'}
Hash: {currentHash || '(空)'}
{'\n'}
</Text>
<Text>
{received} / {total}
</Text>
<TouchableOpacity
onPress={() => {
checkUpdate();
setShowUpdateSnackbar(true);
}}>
<Text style={styles.instructions}></Text>
</TouchableOpacity>
<TouchableOpacity
testID="testcase"
style={{marginTop: 15}}
onLongPress={() => {
setShowTestConsole(true);
}}>
<Text style={styles.instructions}>
react-native-update版本{client?.version}
</Text>
</TouchableOpacity>
<TestConsole visible={showTestConsole} />
{snackbarVisible && (
<Snackbar
visible={snackbarVisible}
onDismiss={() => {
setShowUpdateSnackbar(false);
}}
action={{
label: '更新',
onPress: async () => {
setShowUpdateSnackbar(false);
await downloadUpdate();
setShowUpdateBanner(true);
},
}}>
<Text style={{color: 'white'}}>
({updateInfo.name})
</Text>
</Snackbar>
)}
<Banner
style={{width: '100%', position: 'absolute', top: 0}}
visible={showUpdateBanner}
actions={[
{
label: '立即重启',
onPress: switchVersion,
},
{
label: '下次再说',
onPress: () => {
switchVersionLater();
setShowUpdateBanner(false);
},
},
]}
icon={({size}) => (
<Icon name="checkcircleo" size={size} color="#00f" />
)}>
</Banner>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
image: {},
});
const pushyClient = new Pushy({
appKey,
});
export default function Root() {
return (
<PushyProvider client={pushyClient}>
<PaperProvider>
<App />
</PaperProvider>
</PushyProvider>
);
}

View File

@@ -0,0 +1,10 @@
{
"ios": {
"appId": 24794,
"appKey": "SqShg4Klnj2hG6LAFMW2PdcgSSuniz0T"
},
"android": {
"appId": 27509,
"appKey": "aQz3Uc2pA7gt_prDaQ4rbWRY"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。 1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。 2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。(暂不支持新架构,会待其相对稳定后跟进) 3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。支持新架构
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。 4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。 5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
6. 支持崩溃回滚,安全可靠。 6. 支持崩溃回滚,安全可靠。
@@ -33,3 +33,4 @@ $ yarn start
本组件由[React Native 中文网](https://reactnative.cn/)独家发布,如有定制需求可以[联系我们](https://reactnative.cn/about.html#content)。 本组件由[React Native 中文网](https://reactnative.cn/)独家发布,如有定制需求可以[联系我们](https://reactnative.cn/about.html#content)。
关于此插件发现任何问题,可以前往[Issues](https://github.com/reactnativecn/react-native-pushy/issues)发帖提问。 关于此插件发现任何问题,可以前往[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 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' apply plugin: 'com.android.library'
if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}
android { android {
if (supportsNamespace()) {
namespace "cn.reactnative.modules.update"
sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
}
}
}
compileSdkVersion safeExtGet('compileSdkVersion', 28) compileSdkVersion safeExtGet('compileSdkVersion', 28)
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3') buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
@@ -17,11 +48,17 @@ android {
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
consumerProguardFiles "proguard.pro" consumerProguardFiles "proguard.pro"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
} }
sourceSets { sourceSets {
main { main {
// let gradle pack the shared library into apk // let gradle pack the shared library into apk
jniLibs.srcDirs = ['./lib'] jniLibs.srcDirs = ['./lib']
if (isNewArchitectureEnabled()) {
java.srcDirs += ['src/newarch']
} else {
java.srcDirs += ['src/oldarch']
}
} }
} }
@@ -44,4 +81,12 @@ repositories {
dependencies { dependencies {
implementation 'com.facebook.react:react-native:+' 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); mem_as_hStreamInput(&patStream,pat,pat+patsize);
if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0)) if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0))
return kHPatch_error_info;//data error; return kHPatch_error_info;//data error;
return kHPatch_ok; //ok return kHPatch_ok; //ok
} }
static hpatch_TDecompress* getDecompressPlugin(const char* compressType){ 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); _check(decompressPlugin,kHPatch_error_compressType);
} }
} }
{// mem {// mem
size_t mem_size; size_t mem_size;
size_t oldSize=(size_t)old->streamSize; size_t oldSize=(size_t)old->streamSize;
isLoadOldAllToMem=isLoadOldAllToMem&&(old->streamSize<=kMaxLoadMemOldSize); 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); mem_size=temp_cache_size+(isLoadOldAllToMem?oldSize:0);
temp_cache=malloc(mem_size); temp_cache=malloc(mem_size);
_check(temp_cache,kHPatch_error_malloc); _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; uint8_t* oldMem=temp_cache+temp_cache_size;
_check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread); _check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread);
mem_as_hStreamInput(&_old,oldMem,oldMem+oldSize); 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, 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 oldStream;
hpatch_TStreamInput patStream; hpatch_TStreamInput patStream;
hpatch_TStreamOutput newStream; hpatch_TStreamOutput newStream;

View File

@@ -1,5 +1,5 @@
// hpatch.h // hpatch.h
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile" // import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
// Copyright 2021 housisong, All rights reserved // Copyright 2021 housisong, All rights reserved
#ifndef HDIFFPATCH_PATCH_H #ifndef HDIFFPATCH_PATCH_H
@@ -41,4 +41,4 @@ int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfi
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #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.DownloadTask { *; }
-keepnames class cn.reactnative.modules.update.UpdateModuleImpl { *; }
-keepnames class com.facebook.react.ReactInstanceManager { *; } -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" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.reactnative.modules.update"> package="cn.reactnative.modules.update">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application> <application>
<meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" /> <meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
<provider <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()) { while (entries.hasMoreElements()) {
ZipEntry ze = entries.nextElement(); ZipEntry ze = entries.nextElement();
String fn = ze.getName(); zipFile.unzipToPath(ze, param.unzipDirectory);
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.close(); zipFile.close();
@@ -324,8 +312,15 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
} else { } else {
target = copyList.get((from)); target = copyList.get((from));
} }
target.add(new File(param.unzipDirectory, to)); File toFile = new File(param.unzipDirectory, to);
//copyFromResource(from, 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; continue;
} }
@@ -339,18 +334,9 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
fout.close(); fout.close();
continue; continue;
} }
File fmd = new File(param.unzipDirectory, fn);
if (UpdateContext.DEBUG) {
Log.d("RNUpdate", "Unzipping " + fn);
}
if (ze.isDirectory()) { zipFile.unzipToPath(ze, param.unzipDirectory);
fmd.mkdirs();
continue;
}
zipFile.unzipToFile(ze, fmd);
} }
zipFile.close(); zipFile.close();
@@ -419,18 +405,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
fout.close(); fout.close();
continue; continue;
} }
File fmd = new File(param.unzipDirectory, fn);
if (UpdateContext.DEBUG) { zipFile.unzipToPath(ze, param.unzipDirectory);
Log.d("RNUpdate", "Unzipping " + fn);
}
if (ze.isDirectory()) {
fmd.mkdirs();
continue;
}
zipFile.unzipToFile(ze, fmd);
} }
zipFile.close(); zipFile.close();

View File

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

View File

@@ -1,5 +1,7 @@
package cn.reactnative.modules.update; package cn.reactnative.modules.update;
import android.util.Log;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; import java.io.BufferedOutputStream;
import java.io.File; import java.io.File;
@@ -10,12 +12,15 @@ import java.util.Enumeration;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
public class SafeZipFile extends ZipFile { public class SafeZipFile extends ZipFile {
public SafeZipFile(File file) throws IOException { public SafeZipFile(File file) throws IOException {
super(file); super(file);
} }
private static final int BUFFER_SIZE = 8192;
@Override @Override
public Enumeration<? extends ZipEntry> entries() { public Enumeration<? extends ZipEntry> entries() {
return new SafeZipEntryIterator(super.entries()); return new SafeZipEntryIterator(super.entries());
@@ -43,40 +48,46 @@ public class SafeZipFile extends ZipFile {
* avoid ZipperDown * avoid ZipperDown
*/ */
if (null != name && (name.contains("../") || name.contains("..\\"))) { if (null != name && (name.contains("../") || name.contains("..\\"))) {
throw new SecurityException("illegal entry: " + entry.getName()); throw new SecurityException("illegal entry: " + name);
} }
} }
return entry; return entry;
} }
} }
public void unzipToFile(ZipEntry entry, File output) throws IOException { public void unzipToPath(ZipEntry ze, File targetPath) throws IOException {
InputStream inputStream = null; String name = ze.getName();
try { File target = new File(targetPath, name);
inputStream = getInputStream(entry);
writeOutInputStream(output, inputStream); // Fixing a Zip Path Traversal Vulnerability
} finally { // https://support.google.com/faqs/answer/9294009
if (inputStream != null) { String canonicalPath = target.getCanonicalPath();
inputStream.close(); 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; package cn.reactnative.modules.update;
import com.facebook.react.ReactPackage; import androidx.annotation.Nullable;
import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.TurboReactPackage;
import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager; import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import java.util.Arrays; import java.util.HashMap;
import java.util.Collections; import java.util.Map;
import java.util.List;
/** /**
* Created by tdzl2003 on 3/31/16. * Created by tdzl2003 on 3/31/16.
*/ */
public class UpdatePackage implements ReactPackage { public class UpdatePackage extends TurboReactPackage {
@Nullable
@Override @Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { public NativeModule getModule(String name, ReactApplicationContext reactContext) {
return Arrays.asList(new NativeModule[]{ if (name.equals(UpdateModuleImpl.NAME)) {
// Modules from third-party return new UpdateModule(reactContext);
new UpdateModule(reactContext), } else {
}); return null;
} }
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
} }
@Override @Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { public ReactModuleInfoProvider getReactModuleInfoProvider() {
return Collections.emptyList(); 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 @Override
public String getName() { public String getName() {
return "RCTPushy"; return UpdateModuleImpl.NAME;
} }
@ReactMethod @ReactMethod
@@ -169,7 +169,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
} }
@ReactMethod @ReactMethod
public void reloadUpdate(ReadableMap options) { public void reloadUpdate(ReadableMap options, final Promise promise) {
final String hash = options.getString("hash"); final String hash = options.getString("hash");
UiThreadUtil.runOnUiThread(new Runnable() { UiThreadUtil.runOnUiThread(new Runnable() {
@@ -191,6 +191,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
loadField.setAccessible(true); loadField.setAccessible(true);
loadField.set(instanceManager, loader); loadField.set(instanceManager, loader);
} catch (Throwable err) { } catch (Throwable err) {
promise.reject(err);
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile"); Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
jsBundleField.setAccessible(true); jsBundleField.setAccessible(true);
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application)); jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
@@ -198,11 +199,14 @@ public class UpdateModule extends ReactContextBaseJavaModule {
try { try {
instanceManager.recreateReactContextInBackground(); instanceManager.recreateReactContextInBackground();
promise.resolve(null);
} catch (Throwable err) { } catch (Throwable err) {
activity.recreate(); activity.recreate();
promise.reject(err);
} }
} catch (Throwable err) { } catch (Throwable err) {
promise.reject(err);
Log.e("pushy", "switchVersion failed", 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,
};

23
e2e/starter.test.js Normal file
View File

@@ -0,0 +1,23 @@
describe('Example', () => {
beforeAll(async () => {
await device.launchApp();
});
beforeEach(async () => {
await device.reloadReactNative();
});
it('should have welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
it('should show hello screen after tap', async () => {
await element(by.id('hello_button')).tap();
await expect(element(by.text('Hello!!!'))).toBeVisible();
});
it('should show world screen after tap', async () => {
await element(by.id('world_button')).tap();
await expect(element(by.text('World!!!'))).toBeVisible();
});
});

View File

@@ -1,7 +1,10 @@
#import "RCTPushy.h" #import "RCTPushy.h"
#import "RCTPushyDownloader.h" #import "RCTPushyDownloader.h"
#import "RCTPushyManager.h" #import "RCTPushyManager.h"
// Thanks to this guard, we won't import this header when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
#import "RCTPushySpec.h"
#endif
#import <React/RCTConvert.h> #import <React/RCTConvert.h>
#import <React/RCTLog.h> #import <React/RCTLog.h>
@@ -189,29 +192,53 @@ RCT_EXPORT_MODULE(RCTPushy);
return self; return self;
} }
RCT_EXPORT_METHOD(setBlockUpdate:(NSDictionary *)options) RCT_EXPORT_METHOD(setBlockUpdate:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
// NSMutableDictionary *blockUpdateInfo = [NSMutableDictionary new]; // NSMutableDictionary *blockUpdateInfo = [NSMutableDictionary new];
// blockUpdateInfo[@"reason"] = options[@"reason"]; // blockUpdateInfo[@"reason"] = options[@"reason"];
// blockUpdateInfo[@"until"] = options[@"until"]; // blockUpdateInfo[@"until"] = options[@"until"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @try {
[defaults setObject:options forKey:keyBlockUpdate]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize]; [defaults setObject:options forKey:keyBlockUpdate];
[defaults synchronize];
resolve(@true);
}
@catch (NSException *exception) {
reject(@"执行报错", nil, nil);
}
} }
RCT_EXPORT_METHOD(setUuid:(NSString *)uuid) RCT_EXPORT_METHOD(setUuid:(NSString *)uuid resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; @try {
[defaults setObject:uuid forKey:keyUuid]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize]; [defaults setObject:uuid forKey:keyUuid];
[defaults synchronize];
resolve(@true);
}
@catch (NSException *exception) {
reject(@"json格式校验报错", nil, nil);
}
} }
RCT_EXPORT_METHOD(setLocalHashInfo:(NSString *)hash RCT_EXPORT_METHOD(setLocalHashInfo:(NSString *)hash
value:(NSString *)value) value:(NSString *)value resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
[defaults setObject:value forKey:[keyHashInfo stringByAppendingString:hash]]; NSError *error = nil;
[defaults synchronize]; id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (object && [object isKindOfClass:[NSDictionary class]]) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:value forKey:[keyHashInfo stringByAppendingString:hash]];
[defaults synchronize];
resolve(@true);
} else {
reject(@"json格式校验报错", nil, nil);
}
} }
@@ -266,7 +293,9 @@ RCT_EXPORT_METHOD(downloadPatchFromPpk:(NSDictionary *)options
}]; }];
} }
RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options) RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSString *hash = options[@"hash"]; NSString *hash = options[@"hash"];
@@ -287,45 +316,66 @@ RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
[defaults setObject:newInfo forKey:keyPushyInfo]; [defaults setObject:newInfo forKey:keyPushyInfo];
[defaults synchronize]; [defaults synchronize];
resolve(@true);
}else{
reject(@"执行报错", nil, nil);
} }
} }
RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options) RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSString *hash = options[@"hash"]; @try {
NSString *hash = options[@"hash"];
if (hash.length) { if (hash.length) {
[self setNeedUpdate:options]; [self setNeedUpdate:options resolver:resolve rejecter:reject];
// reload 0.62+ // reload 0.62+
// RCTReloadCommandSetBundleURL([[self class] bundleURL]); // RCTReloadCommandSetBundleURL([[self class] bundleURL]);
// RCTTriggerReloadCommandListeners(@"pushy reload"); // RCTTriggerReloadCommandListeners(@"pushy reload");
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self.bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"]; [self.bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"];
[self.bridge reload]; [self.bridge reload];
}); });
resolve(@true);
}else{
reject(@"执行报错", nil, nil);
}
}
@catch (NSException *exception) {
reject(@"执行报错", nil, nil);
} }
} }
RCT_EXPORT_METHOD(markSuccess) RCT_EXPORT_METHOD(markSuccess:
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
// up package info
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *pushyInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]];
[pushyInfo setObject:@(NO) forKey:paramIsFirstTime];
[pushyInfo setObject:@(YES) forKey:paramIsFirstLoadOk];
NSString *lastVersion = pushyInfo[paramLastVersion]; @try {
NSString *curVersion = pushyInfo[paramCurrentVersion]; // up package info
if (lastVersion != nil && ![lastVersion isEqualToString:curVersion]) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[pushyInfo removeObjectForKey:[keyHashInfo stringByAppendingString:lastVersion]]; NSMutableDictionary *pushyInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]];
[pushyInfo setObject:@(NO) forKey:paramIsFirstTime];
[pushyInfo setObject:@(YES) forKey:paramIsFirstLoadOk];
NSString *lastVersion = pushyInfo[paramLastVersion];
NSString *curVersion = pushyInfo[paramCurrentVersion];
if (lastVersion != nil && ![lastVersion isEqualToString:curVersion]) {
[pushyInfo removeObjectForKey:[keyHashInfo stringByAppendingString:lastVersion]];
}
[defaults setObject:pushyInfo forKey:keyPushyInfo];
[defaults synchronize];
// clear other package dir
[self clearInvalidFiles];
resolve(@true);
}
@catch (NSException *exception) {
reject(@"执行报错", nil, nil);
} }
[defaults setObject:pushyInfo forKey:keyPushyInfo];
[defaults synchronize];
// clear other package dir
[self clearInvalidFiles];
} }
@@ -351,6 +401,19 @@ RCT_EXPORT_METHOD(markSuccess)
// Remove upstream listeners, stop unnecessary background tasks // Remove upstream listeners, stop unnecessary background tasks
} }
- (BOOL) isBlankString:(NSString *)string {
if (string == nil || string == NULL) {
return YES;
}
if ([string isKindOfClass:[NSNull class]]) {
return YES;
}
if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) {
return YES;
}
return NO;
}
- (void)doPushy:(PushyType)type options:(NSDictionary *)options callback:(void (^)(NSError *error))callback - (void)doPushy:(PushyType)type options:(NSDictionary *)options callback:(void (^)(NSError *error))callback
{ {
@@ -362,7 +425,7 @@ RCT_EXPORT_METHOD(markSuccess)
return; return;
} }
NSString *originHash = [RCTConvert NSString:options[@"originHash"]]; NSString *originHash = [RCTConvert NSString:options[@"originHash"]];
if (type == PushyTypePatchFromPpk && originHash <= 0) { if (type == PushyTypePatchFromPpk && [self isBlankString:originHash]) {
callback([self errorWithMessage:ERROR_OPTIONS]); callback([self errorWithMessage:ERROR_OPTIONS]);
return; return;
} }
@@ -562,4 +625,13 @@ RCT_EXPORT_METHOD(markSuccess)
#endif #endif
} }
// Thanks to this guard, we won't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeUpdateSpecJSI>(params);
}
#endif
@end @end

View File

@@ -1 +1 @@
1574665292 1680488830

View File

@@ -1,93 +0,0 @@
let currentEndpoint = 'https://update.react-native.cn/api';
function ping(url, rejectImmediate) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = (e) => {
if (xhr.readyState !== 4) {
return;
}
if (xhr.status === 200) {
resolve(url);
} else {
rejectImmediate ? reject() : setTimeout(reject, 5000);
}
};
xhr.open('HEAD', url);
xhr.send();
xhr.timeout = 5000;
xhr.ontimeout = reject;
});
}
function logger(...args) {
// console.warn('pushy', ...args);
}
let backupEndpoints = [];
let backupEndpointsQueryUrl =
'https://cdn.jsdelivr.net/gh/reactnativecn/react-native-pushy@master/endpoints.json';
export async function tryBackupEndpoints() {
if (!backupEndpoints.length && !backupEndpointsQueryUrl) {
return;
}
try {
await ping(getStatusUrl(), true);
logger('current endpoint ok');
return;
} catch (e) {
logger('current endpoint failed');
}
if (!backupEndpoints.length && backupEndpointsQueryUrl) {
try {
const resp = await fetch(backupEndpointsQueryUrl);
backupEndpoints = await resp.json();
logger('get remote endpoints:', backupEndpoints);
} catch (e) {
logger('get remote endpoints failed');
return;
}
}
await pickFatestAvailableEndpoint();
}
async function pickFatestAvailableEndpoint(endpoints = backupEndpoints) {
const fastestEndpoint = await Promise.race(
endpoints.map(pingAndReturnEndpoint),
);
if (typeof fastestEndpoint === 'string') {
logger(`pick endpoint: ${fastestEndpoint}`);
currentEndpoint = fastestEndpoint;
} else {
logger('all remote endpoints failed');
}
}
async function pingAndReturnEndpoint(endpoint = currentEndpoint) {
return ping(getStatusUrl(endpoint)).then(() => endpoint);
}
function getStatusUrl(endpoint = currentEndpoint) {
return `${endpoint}/status`;
}
export function getCheckUrl(APPKEY, endpoint = currentEndpoint) {
return `${endpoint}/checkUpdate/${APPKEY}`;
}
export function getReportUrl(endpoint = currentEndpoint) {
return `${endpoint}/report`;
}
export function setCustomEndpoints({ main, backups, backupQueryUrl }) {
currentEndpoint = main;
backupEndpointsQueryUrl = null;
if (Array.isArray(backups) && backups.length > 0) {
backupEndpoints = backups;
pickFatestAvailableEndpoint();
}
if (typeof backupQueryUrl === 'string') {
backupEndpointsQueryUrl = backupQueryUrl;
}
}

94
lib/index.d.ts vendored
View File

@@ -1,94 +0,0 @@
export const downloadRootDir: string;
export const packageVersion: string;
export const currentVersion: string;
export const isFirstTime: boolean;
export const isRolledBack: boolean;
export interface ExpiredResult {
upToDate?: false;
expired: true;
downloadUrl: string;
}
export interface UpTodateResult {
expired?: false;
upToDate: true;
paused?: 'app' | 'package';
}
export interface UpdateAvailableResult {
expired?: false;
upToDate?: false;
update: true;
name: string; // version name
hash: string;
description: string;
metaInfo: string;
pdiffUrl: string;
diffUrl?: string;
}
export type CheckResult =
| ExpiredResult
| UpTodateResult
| UpdateAvailableResult;
export function checkUpdate(appkey: string): Promise<CheckResult>;
export function downloadUpdate(
info: UpdateAvailableResult,
eventListeners?: {
onDownloadProgress?: (data: ProgressData) => void;
},
): Promise<undefined | string>;
export function switchVersion(hash: string): void;
export function switchVersionLater(hash: string): void;
export function markSuccess(): void;
export function downloadAndInstallApk({
url,
onDownloadProgress,
}: {
url: string;
onDownloadProgress?: (data: ProgressData) => void;
}): Promise<void>;
/**
* @param {string} main - The main api endpoint
* @param {string[]} [backups] - The back up endpoints.
* @param {string} [backupQueryUrl] - An url that return a json file containing an array of endpoint.
* like: ["https://backup.api/1", "https://backup.api/2"]
*/
export function setCustomEndpoints({
main,
backups,
backupQueryUrl,
}: {
main: string;
backups?: string[];
backupQueryUrl?: string;
}): void;
export function getCurrentVersionInfo(): Promise<{
name?: string;
description?: string;
metaInfo?: string;
}>;
interface ProgressData {
hash: string;
received: number;
total: number;
}
interface SimpleUpdateOptions {
appKey: string;
}
export function simpleUpdate(
wrappedComponent: any,
options: SimpleUpdateOptions,
): any;

View File

@@ -1,2 +0,0 @@
export * from './main';
export * from './simpleUpdate';

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