mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-09-16 12:51:44 +08:00
Compare commits
214 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d000c40e0f | ||
![]() |
5659c79726 | ||
![]() |
b20d987473 | ||
![]() |
14c9c0b1f5 | ||
![]() |
10178e1e64 | ||
![]() |
6d980a4c04 | ||
![]() |
084fbf35ee | ||
![]() |
d666e8c0f3 | ||
![]() |
5e89fb4a25 | ||
![]() |
ab01b6010a | ||
![]() |
92bc830d98 | ||
![]() |
7531e8ca3a | ||
![]() |
b2305cff3f | ||
![]() |
c5cdb6031b | ||
![]() |
20ebf8979e | ||
![]() |
3929fc2f8e | ||
![]() |
31ee269717 | ||
![]() |
adcd57b6b5 | ||
![]() |
c595e4e54a | ||
![]() |
4f80f96a8d | ||
![]() |
a77c3c85f3 | ||
![]() |
2357a0b78d | ||
![]() |
88bacdfb15 | ||
![]() |
90fee03c45 | ||
![]() |
7243512d3c | ||
![]() |
11b383d10b | ||
![]() |
af65b2660c | ||
![]() |
28b8e122af | ||
![]() |
0fdb33ab10 | ||
![]() |
a5893d8022 | ||
![]() |
54036c0f16 | ||
![]() |
454fc28c08 | ||
![]() |
3355751bd5 | ||
![]() |
e960b67cff | ||
![]() |
93b775dd5a | ||
![]() |
b6202e43d3 | ||
![]() |
13d8cf7b80 | ||
![]() |
7780f9985e | ||
![]() |
de69746937 | ||
![]() |
7cce998277 | ||
![]() |
9faeaf881f | ||
![]() |
e0f526aac8 | ||
![]() |
da2046b213 | ||
![]() |
78186ddf1e | ||
![]() |
d9f1c2edb2 | ||
![]() |
4fb0c691e6 | ||
![]() |
b62e6d64cf | ||
![]() |
9af0538a2a | ||
![]() |
e63fa0fdb6 | ||
![]() |
6244bb9af2 | ||
![]() |
9fd6293037 | ||
![]() |
e9e67b011c | ||
![]() |
5996a7aa75 | ||
![]() |
ad9b0778ba | ||
![]() |
3e60cfd80f | ||
![]() |
782b0e5227 | ||
![]() |
d1ecfb3f93 | ||
![]() |
571c2819b9 | ||
![]() |
1f75688b92 | ||
![]() |
de332c1796 | ||
![]() |
80e0451983 | ||
![]() |
b512ae18b7 | ||
![]() |
fe75a2ca9e | ||
![]() |
d84ad103fb | ||
![]() |
208034fa7d | ||
![]() |
c6430a9ed4 | ||
![]() |
f2aec36705 | ||
![]() |
71e5b947d3 | ||
![]() |
5dc8d8defc | ||
![]() |
30687dddf2 | ||
![]() |
57ddcc7758 | ||
![]() |
a93bbe553d | ||
![]() |
356050d839 | ||
![]() |
5df3cb65b3 | ||
![]() |
699eb0ea05 | ||
![]() |
36c4ff085c | ||
![]() |
8c13dd69b1 | ||
![]() |
2df04cb377 | ||
![]() |
e39d4fa370 | ||
![]() |
94cf96a0e5 | ||
![]() |
22c4b01ead | ||
![]() |
f655a1d954 | ||
![]() |
2bdc64ba1b | ||
![]() |
f5242017b9 | ||
![]() |
42e2051290 | ||
![]() |
a66f354c3b | ||
![]() |
592e13b77b | ||
![]() |
2845a4302a | ||
![]() |
84ef668102 | ||
![]() |
c63e1501fe | ||
![]() |
45bfa2560e | ||
![]() |
ab9c40bf2e | ||
![]() |
d184beabaf | ||
![]() |
68a6235145 | ||
![]() |
a98a48d665 | ||
![]() |
4bf004a274 | ||
![]() |
f01716bcb2 | ||
![]() |
4f9e1495c8 | ||
![]() |
9c06bac91b | ||
![]() |
4923aff184 | ||
![]() |
f6a38c1f48 | ||
![]() |
92cfbb3fdf | ||
![]() |
64ef8e129d | ||
![]() |
ce51b2ca81 | ||
![]() |
6c1662fce1 | ||
![]() |
d9e4575964 | ||
![]() |
190103687c | ||
![]() |
f6f055be64 | ||
![]() |
05e5c5a1a7 | ||
![]() |
296498e20a | ||
![]() |
2a3b8e5707 | ||
![]() |
e86df57476 | ||
![]() |
40b2e9dea0 | ||
![]() |
1afc896306 | ||
![]() |
36533d43c4 | ||
![]() |
e5405b4977 | ||
![]() |
9d93faab31 | ||
![]() |
7229f8847a | ||
![]() |
1daafb0142 | ||
![]() |
c1679a4cea | ||
![]() |
7ab7dffb0f | ||
![]() |
8622935bdf | ||
![]() |
b747b1f356 | ||
![]() |
7752581470 | ||
![]() |
33eb89d2a7 | ||
![]() |
d111bf5a9c | ||
![]() |
23346a5f1d | ||
![]() |
5aca2104c2 | ||
![]() |
fe0a05db3d | ||
![]() |
2b287786ff | ||
![]() |
7d128900cd | ||
![]() |
189e3ec78e | ||
![]() |
821722165a | ||
![]() |
6cb53ac655 | ||
![]() |
7b9a24168a | ||
![]() |
c6354bbedc | ||
![]() |
b53878c291 | ||
![]() |
ab01312f8d | ||
![]() |
44784b6d3e | ||
![]() |
30c21fed91 | ||
![]() |
15af7802ad | ||
![]() |
8bed6ef979 | ||
![]() |
7d03dc24b7 | ||
![]() |
18849ee441 | ||
![]() |
3ba1df2020 | ||
![]() |
7152ef7304 | ||
![]() |
094eb3f267 | ||
![]() |
6d01ce5152 | ||
![]() |
8bf1fed3f8 | ||
![]() |
39c4a6d339 | ||
![]() |
f1e9244a14 | ||
![]() |
546f287b6c | ||
![]() |
175e43d524 | ||
![]() |
b200766aa3 | ||
![]() |
7e65457cc1 | ||
![]() |
6c5ccd98b7 | ||
![]() |
d7abd590b0 | ||
![]() |
ffb2bf4afa | ||
![]() |
94c177512e | ||
![]() |
a16a73e754 | ||
![]() |
40df51db0f | ||
![]() |
97fec1e79e | ||
![]() |
75b4447437 | ||
![]() |
f9c6a97a50 | ||
![]() |
90aa07cc55 | ||
![]() |
26cda39451 | ||
![]() |
3d5012fced | ||
![]() |
533696e34d | ||
![]() |
9c98aaa899 | ||
![]() |
706cd8c415 | ||
![]() |
e76747f7d3 | ||
![]() |
65a2477932 | ||
![]() |
581cd3310e | ||
![]() |
f24bfd6f2a | ||
![]() |
c57802e2d2 | ||
![]() |
ca4f363e6d | ||
![]() |
6fcfa0b505 | ||
![]() |
12edc1df7a | ||
![]() |
4acba40f6c | ||
![]() |
0adda18b50 | ||
![]() |
6cd256b7f4 | ||
![]() |
bd04badbe8 | ||
![]() |
f0c52b0acd | ||
![]() |
76e5c6c59b | ||
![]() |
d2f53e17c5 | ||
![]() |
a182c5d3c6 | ||
![]() |
4e4c686f4d | ||
![]() |
301243b502 | ||
![]() |
b23898ec48 | ||
![]() |
909788c6f6 | ||
![]() |
507576795c | ||
![]() |
48526430a1 | ||
![]() |
aaab2d77c8 | ||
![]() |
b4b8856ed2 | ||
![]() |
eb1c9ff5de | ||
![]() |
6f346d7990 | ||
![]() |
27c053a645 | ||
![]() |
55506483f9 | ||
![]() |
5f28b75abd | ||
![]() |
4bf921c82c | ||
![]() |
68cc6d3fad | ||
![]() |
63c4825006 | ||
![]() |
aa5f5b9340 | ||
![]() |
6216fdfd35 | ||
![]() |
1d11fc64a8 | ||
![]() |
87a2004b2b | ||
![]() |
92675ed37c | ||
![]() |
992b17d25a | ||
![]() |
d538782b01 | ||
![]() |
d6c268f533 | ||
![]() |
55879198e8 | ||
![]() |
f8115c3a85 | ||
![]() |
e859900df6 | ||
![]() |
65a332b88a |
29
.eslintrc
29
.eslintrc
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"extends": "eslint-config-airbnb/base",
|
||||
"parser": "babel-eslint",
|
||||
"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
|
||||
}
|
||||
}
|
4
.eslintrc.js
Normal file
4
.eslintrc.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native',
|
||||
};
|
49
.github/workflows/e2e_android.yml
vendored
Normal file
49
.github/workflows/e2e_android.yml
vendored
Normal 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
182
.github/workflows/e2e_ios.yml
vendored
Normal 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-14-arm64
|
||||
# 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@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- 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
|
10
.github/workflows/scripts/adb_all_emulators.sh
vendored
Executable file
10
.github/workflows/scripts/adb_all_emulators.sh
vendored
Executable 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."
|
13
.github/workflows/scripts/database.rules
vendored
Normal file
13
.github/workflows/scripts/database.rules
vendored
Normal 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
39
.github/workflows/scripts/firebase.json
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
72
.github/workflows/scripts/firestore.indexes.json
vendored
Normal file
72
.github/workflows/scripts/firestore.indexes.json
vendored
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
17
.github/workflows/scripts/firestore.rules
vendored
Normal file
17
.github/workflows/scripts/firestore.rules
vendored
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
10
.github/workflows/scripts/functions/.gitignore
vendored
Normal file
10
.github/workflows/scripts/functions/.gitignore
vendored
Normal 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
|
24
.github/workflows/scripts/functions/package.json
vendored
Normal file
24
.github/workflows/scripts/functions/package.json
vendored
Normal 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
|
||||
}
|
13
.github/workflows/scripts/functions/src/exports.ts
vendored
Normal file
13
.github/workflows/scripts/functions/src/exports.ts
vendored
Normal 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'),
|
||||
};
|
12
.github/workflows/scripts/functions/src/index.ts
vendored
Normal file
12
.github/workflows/scripts/functions/src/index.ts
vendored
Normal 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';
|
80
.github/workflows/scripts/functions/src/sample-data.ts
vendored
Normal file
80
.github/workflows/scripts/functions/src/sample-data.ts
vendored
Normal 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;
|
14
.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
vendored
Normal file
14
.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
vendored
Normal 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');
|
73
.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
vendored
Normal file
73
.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
*
|
||||
* 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: any) {
|
||||
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;
|
||||
});
|
16
.github/workflows/scripts/functions/tsconfig.json
vendored
Normal file
16
.github/workflows/scripts/functions/tsconfig.json
vendored
Normal 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"
|
||||
]
|
||||
}
|
6
.github/workflows/scripts/start-firebase-emulator.bat
vendored
Normal file
6
.github/workflows/scripts/start-firebase-emulator.bat
vendored
Normal 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
|
44
.github/workflows/scripts/start-firebase-emulator.sh
vendored
Executable file
44
.github/workflows/scripts/start-firebase-emulator.sh
vendored
Executable 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
21
.github/workflows/scripts/storage.rules
vendored
Normal 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
6
.gitignore
vendored
@@ -41,6 +41,8 @@ local.properties
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
Example/**/update.json
|
||||
Example/**/.update
|
||||
Example/**/.pushy
|
||||
Example/testHotUpdate/artifacts
|
||||
|
||||
yarn-error.log
|
||||
Example/testHotUpdate/.pushy
|
||||
|
@@ -47,4 +47,6 @@ Example
|
||||
yarn.lock
|
||||
|
||||
domains.json
|
||||
endpoints.json
|
||||
endpoints.json
|
||||
|
||||
tea.yaml
|
@@ -1,4 +1,6 @@
|
||||
module.exports = {
|
||||
trailingComma: 'all',
|
||||
arrowParens: 'avoid',
|
||||
bracketSameLine: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
};
|
||||
|
94
Example/testHotUpdate/.detoxrc.js
Normal file
94
Example/testHotUpdate/.detoxrc.js
Normal 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',
|
||||
},
|
||||
},
|
||||
};
|
@@ -52,7 +52,6 @@ nonstrict-import=warn
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
@@ -64,4 +63,4 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.170.0
|
||||
^0.176.3
|
||||
|
8
Example/testHotUpdate/.gitignore
vendored
8
Example/testHotUpdate/.gitignore
vendored
@@ -20,6 +20,7 @@ DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
ios/.xcode.env.local
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
@@ -49,9 +50,10 @@ buck-out/
|
||||
# For more information about the recommended setup visit:
|
||||
# https://docs.fastlane.tools/best-practices/source-control/
|
||||
|
||||
*/fastlane/report.xml
|
||||
*/fastlane/Preview.html
|
||||
*/fastlane/screenshots
|
||||
**/fastlane/report.xml
|
||||
**/fastlane/Preview.html
|
||||
**/fastlane/screenshots
|
||||
**/fastlane/test_output
|
||||
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
1
Example/testHotUpdate/.nvmrc
Normal file
1
Example/testHotUpdate/.nvmrc
Normal file
@@ -0,0 +1 @@
|
||||
18
|
@@ -1 +1 @@
|
||||
2.7.4
|
||||
2.7.5
|
||||
|
@@ -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;
|
@@ -1,6 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby '2.7.4'
|
||||
ruby '3.1.1'
|
||||
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
||||
|
@@ -1,30 +1,29 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
activesupport (6.1.5.1)
|
||||
activesupport (7.0.4.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.11.3)
|
||||
cocoapods (1.12.0)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.3)
|
||||
cocoapods-core (= 1.12.0)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-downloader (>= 1.6.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
@@ -32,10 +31,10 @@ GEM
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.3)
|
||||
activesupport (>= 5.0, < 7)
|
||||
cocoapods-core (1.12.0)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
@@ -54,19 +53,19 @@ GEM
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.10)
|
||||
concurrent-ruby (1.2.2)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.10.0)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.6.1)
|
||||
minitest (5.15.0)
|
||||
json (2.6.3)
|
||||
minitest (5.18.0)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
@@ -76,16 +75,15 @@ GEM
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.21.0)
|
||||
xcodeproj (1.22.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.5.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -94,7 +92,7 @@ DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.4p191
|
||||
ruby 3.1.1p18
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.27
|
||||
2.1.4
|
||||
|
66
Example/testHotUpdate/README.md
Normal file
66
Example/testHotUpdate/README.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# react-native-android-detox
|
||||
|
||||
[](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
|
||||
```
|
@@ -35,12 +35,12 @@ android_library(
|
||||
|
||||
android_build_config(
|
||||
name = "build_config",
|
||||
package = "com.testhotupdate",
|
||||
package = "com.awesomeproject",
|
||||
)
|
||||
|
||||
android_resource(
|
||||
name = "res",
|
||||
package = "com.testhotupdate",
|
||||
package = "com.awesomeproject",
|
||||
res = "src/main/res",
|
||||
)
|
||||
|
||||
|
@@ -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 org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
@@ -92,7 +94,7 @@ apply from: "../../node_modules/react-native/react.gradle"
|
||||
* Upload all the APKs to the Play Store and people will download
|
||||
* the correct one based on the CPU architecture of their device.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
def enableSeparateBuildPerCPUArchitecture = true
|
||||
|
||||
/**
|
||||
* Run Proguard to shrink the Java bytecode in release builds.
|
||||
@@ -135,11 +137,13 @@ android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.testhotupdate"
|
||||
applicationId "com.awesomeproject"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionName "2.0"
|
||||
testBuildType System.getProperty('testBuildType', 'debug')
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
@@ -152,16 +156,13 @@ android {
|
||||
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||
"PROJECT_BUILD_DIR=$buildDir",
|
||||
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
|
||||
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
|
||||
"NODE_MODULES_DIR=$rootDir/../node_modules"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "testhotupdate_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"
|
||||
}
|
||||
targets "awesomeproject_appmodules"
|
||||
}
|
||||
}
|
||||
if (!enableSeparateBuildPerCPUArchitecture) {
|
||||
@@ -236,9 +237,11 @@ android {
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
// see https://reactnative.dev/docs/signed-apk-android.
|
||||
crunchPngs false
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +263,8 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation('com.wix:detox:+')
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
@@ -281,9 +286,10 @@ dependencies {
|
||||
}
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
@@ -296,7 +302,11 @@ if (isNewArchitectureEnabled()) {
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
|
||||
.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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -4,7 +4,7 @@
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package com.testhotupdate;
|
||||
package com.awesomeproject;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
@@ -1,7 +1,9 @@
|
||||
<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.CAMERA" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
@@ -9,7 +11,8 @@
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
@@ -18,8 +21,14 @@
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="testhotupdate" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package com.testhotupdate;
|
||||
package com.awesomeproject;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
@@ -12,12 +12,13 @@ public class MainActivity extends ReactActivity {
|
||||
*/
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "testHotupdate";
|
||||
return "AwesomeProject";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
@@ -36,5 +37,12 @@ public class MainActivity extends ReactActivity {
|
||||
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||
return reactRootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConcurrentRootEnabled() {
|
||||
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
|
||||
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,46 +1,54 @@
|
||||
package com.testhotupdate;
|
||||
package com.awesomeproject;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.testhotupdate.newarchitecture.MainApplicationReactNativeHost;
|
||||
import com.awesomeproject.newarchitecture.MainApplicationReactNativeHost;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import cn.reactnative.modules.update.UpdateContext;
|
||||
import cn.reactnative.modules.update.UpdatePackage;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new ReactNativeHost(this) {
|
||||
@Override
|
||||
protected String getJSBundleFile() {
|
||||
return UpdateContext.getBundleUrl(MainApplication.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new ReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
return packages;
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getJSBundleFile() {
|
||||
return UpdateContext.getBundleUrl(MainApplication.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
|
||||
private final ReactNativeHost mNewArchitectureNativeHost =
|
||||
new MainApplicationReactNativeHost(this);
|
||||
@@ -78,7 +86,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.testhotupdate.ReactNativeFlipper");
|
||||
Class<?> aClass = Class.forName("com.awesomeproject.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
@@ -1,4 +1,4 @@
|
||||
package com.testhotupdate.newarchitecture;
|
||||
package com.awesomeproject.newarchitecture;
|
||||
|
||||
import android.app.Application;
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -16,12 +16,12 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.fabric.ComponentFactory;
|
||||
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||
import com.facebook.react.fabric.EmptyReactNativeConfig;
|
||||
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||
import com.facebook.react.fabric.ReactNativeConfig;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import com.testhotupdate.BuildConfig;
|
||||
import com.testhotupdate.newarchitecture.components.MainComponentsRegistry;
|
||||
import com.testhotupdate.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||
import com.awesomeproject.BuildConfig;
|
||||
import com.awesomeproject.newarchitecture.components.MainComponentsRegistry;
|
||||
import com.awesomeproject.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||
return new FabricJSIModuleProvider(
|
||||
reactApplicationContext,
|
||||
componentFactory,
|
||||
new EmptyReactNativeConfig(),
|
||||
ReactNativeConfig.DEFAULT_CONFIG,
|
||||
viewManagerRegistry);
|
||||
}
|
||||
});
|
@@ -1,4 +1,4 @@
|
||||
package com.testhotupdate.newarchitecture.components;
|
||||
package com.awesomeproject.newarchitecture.components;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
@@ -1,4 +1,4 @@
|
||||
package com.testhotupdate.newarchitecture.modules;
|
||||
package com.awesomeproject.newarchitecture.modules;
|
||||
|
||||
import com.facebook.jni.HybridData;
|
||||
import com.facebook.react.ReactPackage;
|
||||
@@ -41,7 +41,7 @@ public class MainApplicationTurboModuleManagerDelegate
|
||||
if (!sIsSoLibraryLoaded) {
|
||||
// If you change the name of your application .so file in the Android.mk file,
|
||||
// make sure you update the name here as well.
|
||||
SoLoader.loadLibrary("testhotupdate_appmodules");
|
||||
SoLoader.loadLibrary("awesomeproject_appmodules");
|
||||
sIsSoLibraryLoaded = true;
|
||||
}
|
||||
}
|
@@ -10,14 +10,14 @@ include $(CLEAR_VARS)
|
||||
LOCAL_PATH := $(THIS_DIR)
|
||||
|
||||
# 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_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
|
||||
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# will have to uncomment those lines to include the generated source
|
||||
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||
#
|
||||
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||
@@ -28,8 +28,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libfabricjni \
|
||||
libfbjni \
|
||||
libfolly_futures \
|
||||
libfolly_json \
|
||||
libfolly_runtime \
|
||||
libglog \
|
||||
libjsi \
|
||||
libreact_codegen_rncore \
|
||||
|
@@ -14,7 +14,7 @@ class MainApplicationTurboModuleManagerDelegate
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
static constexpr auto kJavaDescriptor =
|
||||
"Lcom/testhotupdate/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||
"Lcom/awesomeproject/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
|
||||
|
||||
|
@@ -13,7 +13,7 @@ class MainComponentsRegistry
|
||||
public:
|
||||
// Adapt it to the package you used for your Java class.
|
||||
constexpr static auto kJavaDescriptor =
|
||||
"Lcom/testhotupdate/newarchitecture/components/MainComponentsRegistry;";
|
||||
"Lcom/awesomeproject/newarchitecture/components/MainComponentsRegistry;";
|
||||
|
||||
static void registerNatives();
|
||||
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">testHotupdate</string>
|
||||
<string name="app_name">AwesomeProject</string>
|
||||
</resources>
|
||||
|
@@ -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>
|
@@ -5,9 +5,11 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
||||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "31.0.0"
|
||||
minSdkVersion = 21
|
||||
minSdkVersion = 23
|
||||
compileSdkVersion = 31
|
||||
targetSdkVersion = 31
|
||||
kotlinVersion = '1.7.20'
|
||||
kotlin_version = '1.7.20'
|
||||
|
||||
if (System.properties['os.arch'] == "aarch64") {
|
||||
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||
@@ -22,11 +24,12 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
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("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
|
||||
// in the individual module build.gradle files
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +51,9 @@ allprojects {
|
||||
}
|
||||
}
|
||||
google()
|
||||
maven {
|
||||
url("$rootDir/../node_modules/detox/Detox-android")
|
||||
}
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
include ':app'
|
||||
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") {
|
||||
include(":ReactAndroid")
|
||||
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||
include(":ReactAndroid:hermes-engine")
|
||||
project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"name": "testHotupdate",
|
||||
"displayName": "testHotupdate"
|
||||
"name": "AwesomeProject",
|
||||
"displayName": "AwesomeProject"
|
||||
}
|
@@ -1,3 +1,8 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
env: {
|
||||
production: {
|
||||
plugins: ['react-native-paper/babel'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
116
Example/testHotUpdate/e2e/NativeModule.test.ts
Normal file
116
Example/testHotUpdate/e2e/NativeModule.test.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
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();
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
});
|
15
Example/testHotUpdate/e2e/jest.config.js
Normal file
15
Example/testHotUpdate/e2e/jest.config.js
Normal 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,
|
||||
};
|
11
Example/testHotUpdate/ios/.xcode.env
Normal file
11
Example/testHotUpdate/ios/.xcode.env
Normal 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)
|
@@ -7,78 +7,43 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* testHotupdateTests.m */; };
|
||||
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */; };
|
||||
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */; };
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||
remoteInfo = testHotupdate;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = testHotupdateTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
00E356F21AD99517003FC87E /* testHotupdateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testHotupdateTests.m; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* testHotupdate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testHotupdate.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = testHotupdate/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = testHotupdate/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = testHotupdate/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = testHotupdate/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testHotupdate/main.m; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotupdate.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = testHotupdate/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* AwesomeProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AwesomeProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = AwesomeProject/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = AwesomeProject/AppDelegate.mm; sourceTree = "<group>"; };
|
||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AwesomeProject/Images.xcassets; sourceTree = "<group>"; };
|
||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AwesomeProject/Info.plist; sourceTree = "<group>"; };
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AwesomeProject/main.m; sourceTree = "<group>"; };
|
||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject-AwesomeProjectTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject.debug.xcconfig"; path = "Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject.release.xcconfig"; path = "Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig"; path = "Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AwesomeProject/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig"; path = "Target Support Files/Pods-AwesomeProject-AwesomeProjectTests/Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
00E356EB1AD99517003FC87E /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */,
|
||||
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
00E356EF1AD99517003FC87E /* testHotupdateTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F21AD99517003FC87E /* testHotupdateTests.m */,
|
||||
00E356F01AD99517003FC87E /* Supporting Files */,
|
||||
);
|
||||
path = testHotupdateTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
00E356F01AD99517003FC87E /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
00E356F11AD99517003FC87E /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
13B07FAE1A68108700A75B9A /* testHotupdate */ = {
|
||||
13B07FAE1A68108700A75B9A /* AwesomeProject */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||
@@ -88,14 +53,15 @@
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
);
|
||||
name = testHotupdate;
|
||||
name = AwesomeProject;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */,
|
||||
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */,
|
||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -110,9 +76,8 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07FAE1A68108700A75B9A /* testHotupdate */,
|
||||
13B07FAE1A68108700A75B9A /* AwesomeProject */,
|
||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||
00E356EF1AD99517003FC87E /* testHotupdateTests */,
|
||||
83CBBA001A601CBA00E9B192 /* Products */,
|
||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||
BBD78D7AC51CEA395F1C20DB /* Pods */,
|
||||
@@ -125,8 +90,7 @@
|
||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
13B07F961A680F5B00A75B9A /* testHotupdate.app */,
|
||||
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */,
|
||||
13B07F961A680F5B00A75B9A /* AwesomeProject.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -134,8 +98,10 @@
|
||||
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */,
|
||||
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */,
|
||||
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */,
|
||||
5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */,
|
||||
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */,
|
||||
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
@@ -143,27 +109,9 @@
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
00E356ED1AD99517003FC87E /* testHotupdateTests */ = {
|
||||
13B07F861A680F5B00A75B9A /* AwesomeProject */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */;
|
||||
buildPhases = (
|
||||
00E356EA1AD99517003FC87E /* Sources */,
|
||||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */,
|
||||
);
|
||||
name = testHotupdateTests;
|
||||
productName = testHotupdateTests;
|
||||
productReference = 00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
13B07F861A680F5B00A75B9A /* testHotupdate */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */;
|
||||
buildPhases = (
|
||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F022414F080027D42C /* Start Packager */,
|
||||
@@ -171,16 +119,15 @@
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
|
||||
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = testHotupdate;
|
||||
productName = testHotupdate;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* testHotupdate.app */;
|
||||
name = AwesomeProject;
|
||||
productName = AwesomeProject;
|
||||
productReference = 13B07F961A680F5B00A75B9A /* AwesomeProject.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
@@ -191,16 +138,12 @@
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1210;
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||
};
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
LastSwiftMigration = 1120;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */;
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */;
|
||||
compatibilityVersion = "Xcode 12.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
@@ -213,20 +156,12 @@
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
13B07F861A680F5B00A75B9A /* testHotupdate */,
|
||||
00E356ED1AD99517003FC87E /* testHotupdateTests */,
|
||||
13B07F861A680F5B00A75B9A /* AwesomeProject */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
00E356EC1AD99517003FC87E /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -245,30 +180,15 @@
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"$(SRCROOT)/.xcode.env.local",
|
||||
"$(SRCROOT)/.xcode.env",
|
||||
);
|
||||
name = "Bundle React Native code and images";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
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";
|
||||
};
|
||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -285,7 +205,7 @@
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-testHotupdate-checkManifestLockResult.txt",
|
||||
"$(DERIVED_FILE_DIR)/Pods-AwesomeProject-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -298,15 +218,15 @@
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources.sh\"\n";
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||
@@ -331,14 +251,6 @@
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
00E356EA1AD99517003FC87E /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -350,73 +262,16 @@
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 13B07F861A680F5B00A75B9A /* testHotupdate */;
|
||||
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
00E356F61AD99517003FC87E /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = testHotupdateTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
"$(inherited)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
00E356F71AD99517003FC87E /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
INFOPLIST_FILE = testHotupdateTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
"-lc++",
|
||||
"$(inherited)",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/testHotupdate.app/testHotupdate";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */;
|
||||
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = testHotupdate/Info.plist;
|
||||
INFOPLIST_FILE = AwesomeProject/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@@ -427,7 +282,7 @@
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = testHotupdate;
|
||||
PRODUCT_NAME = AwesomeProject;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -436,12 +291,12 @@
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */;
|
||||
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
INFOPLIST_FILE = testHotupdate/Info.plist;
|
||||
INFOPLIST_FILE = AwesomeProject/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
@@ -452,7 +307,7 @@
|
||||
"-lc++",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = testHotupdate;
|
||||
PRODUCT_NAME = AwesomeProject;
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
@@ -507,7 +362,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
@@ -525,6 +380,7 @@
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -571,7 +427,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
/usr/lib/swift,
|
||||
"$(inherited)",
|
||||
@@ -588,6 +444,7 @@
|
||||
"-DFOLLY_MOBILE=1",
|
||||
"-DFOLLY_USE_LIBCPP=1",
|
||||
);
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
@@ -596,16 +453,7 @@
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "testHotupdateTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
00E356F61AD99517003FC87E /* Debug */,
|
||||
00E356F71AD99517003FC87E /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "testHotupdate" */ = {
|
||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
13B07F941A680F5B00A75B9A /* Debug */,
|
||||
@@ -614,7 +462,7 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */ = {
|
||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
@@ -15,9 +15,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "testHotupdate.app"
|
||||
BlueprintName = "testHotupdate"
|
||||
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||
BuildableName = "AwesomeProject.app"
|
||||
BlueprintName = "AwesomeProject"
|
||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
@@ -33,9 +33,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||
BuildableName = "testHotupdateTests.xctest"
|
||||
BlueprintName = "testHotupdateTests"
|
||||
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||
BuildableName = "AwesomeProjectTests.xctest"
|
||||
BlueprintName = "AwesomeProjectTests"
|
||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
@@ -55,9 +55,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "testHotupdate.app"
|
||||
BlueprintName = "testHotupdate"
|
||||
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||
BuildableName = "AwesomeProject.app"
|
||||
BlueprintName = "AwesomeProject"
|
||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
@@ -72,9 +72,9 @@
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "testHotupdate.app"
|
||||
BlueprintName = "testHotupdate"
|
||||
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||
BuildableName = "AwesomeProject.app"
|
||||
BlueprintName = "AwesomeProject"
|
||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
@@ -2,7 +2,7 @@
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:testHotupdate.xcodeproj">
|
||||
location = "group:AwesomeProject.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
@@ -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>
|
@@ -1,9 +1,8 @@
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RCTPushy.h"
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import "RCTPushy.h"
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
@@ -17,6 +16,8 @@
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
static NSString *const kRNConcurrentRoot = @"concurrentRoot";
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
@@ -42,7 +43,8 @@
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"testHotupdate", nil);
|
||||
NSDictionary *initProps = [self prepareInitialProps];
|
||||
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"AwesomeProject", initProps);
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
@@ -58,12 +60,33 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
/// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
|
||||
///
|
||||
/// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
/// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
|
||||
/// @return: `true` if the `concurrentRoot` feture is enabled. Otherwise, it returns `false`.
|
||||
- (BOOL)concurrentRootEnabled
|
||||
{
|
||||
// Switch this bool to turn on and off the concurrent root
|
||||
return true;
|
||||
}
|
||||
|
||||
- (NSDictionary *)prepareInitialProps
|
||||
{
|
||||
NSMutableDictionary *initProps = [NSMutableDictionary new];
|
||||
|
||||
#ifdef RCT_NEW_ARCH_ENABLED
|
||||
initProps[kRNConcurrentRoot] = @([self concurrentRootEnabled]);
|
||||
#endif
|
||||
|
||||
return initProps;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
// 非DEBUG情况下替换为热更新bundle
|
||||
return [RCTPushy bundleURL];
|
||||
#endif
|
||||
}
|
@@ -5,7 +5,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>testHotupdate</string>
|
||||
<string>AwesomeProject</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -26,6 +26,8 @@
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
@@ -51,5 +53,10 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>For taking photos</string>
|
||||
|
||||
<key>NSPhotoLibraryUsageDescription</key>
|
||||
<string>For saving photos</string>
|
||||
</dict>
|
||||
</plist>
|
@@ -16,7 +16,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="testHotupdate" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AwesomeProject" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
|
||||
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<nil key="highlightedColor"/>
|
@@ -1,10 +1,12 @@
|
||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
platform :ios, '11.0'
|
||||
platform :ios, '12.4'
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
target 'testHotupdate' do
|
||||
production = ENV["PRODUCTION"] == "1"
|
||||
|
||||
target 'AwesomeProject' do
|
||||
config = use_native_modules!
|
||||
|
||||
# Flags change depending on the env values.
|
||||
@@ -13,19 +15,14 @@ target 'testHotupdate' do
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||
:production => production,
|
||||
:hermes_enabled => flags[:hermes_enabled],
|
||||
:fabric_enabled => flags[:fabric_enabled],
|
||||
:flipper_configuration => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
use_flipper!()
|
||||
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
|
@@ -1,80 +1,16 @@
|
||||
PODS:
|
||||
- boost (1.76.0)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.68.2)
|
||||
- FBReactNativeSpec (0.68.2):
|
||||
- FBLazyVector (0.69.8)
|
||||
- FBReactNativeSpec (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Core (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- Flipper (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (3.2.0)
|
||||
- Flipper-Fmt (7.1.7)
|
||||
- Flipper-Folly (2.6.10):
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Glog
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- Flipper-Glog (0.5.0.4)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.125.0):
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/Core (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- SocketRocket (~> 0.6.0)
|
||||
- FlipperKit/CppBridge (0.125.0):
|
||||
- Flipper (~> 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.125.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.125.0)
|
||||
- FlipperKit/FKPortForwarding (0.125.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.125.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- RCTRequired (= 0.69.8)
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Core (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.1100)
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
@@ -86,320 +22,307 @@ PODS:
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.68.2)
|
||||
- RCTTypeSafety (0.68.2):
|
||||
- FBLazyVector (= 0.68.2)
|
||||
- RCTRequired (0.69.8)
|
||||
- RCTTypeSafety (0.69.8):
|
||||
- FBLazyVector (= 0.69.8)
|
||||
- RCTRequired (= 0.69.8)
|
||||
- React-Core (= 0.69.8)
|
||||
- React (0.69.8):
|
||||
- React-Core (= 0.69.8)
|
||||
- React-Core/DevSupport (= 0.69.8)
|
||||
- React-Core/RCTWebSocket (= 0.69.8)
|
||||
- React-RCTActionSheet (= 0.69.8)
|
||||
- React-RCTAnimation (= 0.69.8)
|
||||
- React-RCTBlob (= 0.69.8)
|
||||
- React-RCTImage (= 0.69.8)
|
||||
- React-RCTLinking (= 0.69.8)
|
||||
- React-RCTNetwork (= 0.69.8)
|
||||
- React-RCTSettings (= 0.69.8)
|
||||
- React-RCTText (= 0.69.8)
|
||||
- React-RCTVibration (= 0.69.8)
|
||||
- React-bridging (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.2)
|
||||
- React-Core (= 0.68.2)
|
||||
- React (0.68.2):
|
||||
- React-Core (= 0.68.2)
|
||||
- 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)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-callinvoker (0.69.8)
|
||||
- React-Codegen (0.69.8):
|
||||
- FBReactNativeSpec (= 0.69.8)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Core (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-Core (0.68.2):
|
||||
- RCTRequired (= 0.69.8)
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Core (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-Core (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-Core/Default (= 0.69.8)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.68.2):
|
||||
- React-Core/CoreModulesHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/Default (0.68.2):
|
||||
- React-Core/Default (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.68.2):
|
||||
- React-Core/DevSupport (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.2)
|
||||
- React-Core/RCTWebSocket (= 0.68.2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-jsinspector (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-Core/Default (= 0.69.8)
|
||||
- React-Core/RCTWebSocket (= 0.69.8)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-jsinspector (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.68.2):
|
||||
- React-Core/RCTActionSheetHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.68.2):
|
||||
- React-Core/RCTAnimationHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.68.2):
|
||||
- React-Core/RCTBlobHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.68.2):
|
||||
- React-Core/RCTImageHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.68.2):
|
||||
- React-Core/RCTLinkingHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.68.2):
|
||||
- React-Core/RCTNetworkHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.68.2):
|
||||
- React-Core/RCTSettingsHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.68.2):
|
||||
- React-Core/RCTTextHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.68.2):
|
||||
- React-Core/RCTVibrationHeaders (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.68.2):
|
||||
- React-Core/RCTWebSocket (0.69.8):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsiexecutor (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-Core/Default (= 0.69.8)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsiexecutor (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- Yoga
|
||||
- React-CoreModules (0.68.2):
|
||||
- React-CoreModules (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-RCTImage (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-cxxreact (0.68.2):
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/CoreModulesHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-RCTImage (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-cxxreact (0.69.8):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-jsinspector (= 0.68.2)
|
||||
- React-logger (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-runtimeexecutor (= 0.68.2)
|
||||
- React-jsi (0.68.2):
|
||||
- React-callinvoker (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-jsinspector (= 0.69.8)
|
||||
- React-logger (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- React-runtimeexecutor (= 0.69.8)
|
||||
- React-jsi (0.69.8):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.68.2)
|
||||
- React-jsi/Default (0.68.2):
|
||||
- React-jsi/Default (= 0.69.8)
|
||||
- React-jsi/Default (0.69.8):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.68.2):
|
||||
- React-jsiexecutor (0.69.8):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- React-jsinspector (0.68.2)
|
||||
- React-logger (0.68.2):
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- React-jsinspector (0.69.8)
|
||||
- React-logger (0.69.8):
|
||||
- glog
|
||||
- react-native-update (7.4.2):
|
||||
- react-native-safe-area-context (4.8.2):
|
||||
- React-Core
|
||||
- react-native-update (10.10.0):
|
||||
- React
|
||||
- react-native-update/HDiffPatch (= 7.4.2)
|
||||
- react-native-update/RCTPushy (= 7.4.2)
|
||||
- React-Core
|
||||
- react-native-update/HDiffPatch (= 10.10.0)
|
||||
- react-native-update/RCTPushy (= 10.10.0)
|
||||
- SSZipArchive
|
||||
- react-native-update/HDiffPatch (7.4.2):
|
||||
- react-native-update/HDiffPatch (10.10.0):
|
||||
- React
|
||||
- React-Core
|
||||
- SSZipArchive
|
||||
- react-native-update/RCTPushy (7.4.2):
|
||||
- react-native-update/RCTPushy (10.10.0):
|
||||
- React
|
||||
- React-Core
|
||||
- SSZipArchive
|
||||
- React-perflogger (0.68.2)
|
||||
- React-RCTActionSheet (0.68.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.68.2)
|
||||
- React-RCTAnimation (0.68.2):
|
||||
- React-perflogger (0.69.8)
|
||||
- React-RCTActionSheet (0.69.8):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.69.8)
|
||||
- React-RCTAnimation (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTBlob (0.68.2):
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTAnimationHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTBlob (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTBlobHeaders (= 0.68.2)
|
||||
- React-Core/RCTWebSocket (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-RCTNetwork (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTImage (0.68.2):
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTBlobHeaders (= 0.69.8)
|
||||
- React-Core/RCTWebSocket (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-RCTNetwork (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTImage (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTImageHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-RCTNetwork (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTLinking (0.68.2):
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTNetwork (0.68.2):
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTImageHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-RCTNetwork (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTLinking (0.69.8):
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTLinkingHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTNetwork (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTSettings (0.68.2):
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTNetworkHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTSettings (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-RCTText (0.68.2):
|
||||
- React-Core/RCTTextHeaders (= 0.68.2)
|
||||
- React-RCTVibration (0.68.2):
|
||||
- RCTTypeSafety (= 0.69.8)
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTSettingsHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-RCTText (0.69.8):
|
||||
- React-Core/RCTTextHeaders (= 0.69.8)
|
||||
- React-RCTVibration (0.69.8):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (= 0.68.2)
|
||||
- React-runtimeexecutor (0.68.2):
|
||||
- React-jsi (= 0.68.2)
|
||||
- ReactCommon/turbomodule/core (0.68.2):
|
||||
- React-Codegen (= 0.69.8)
|
||||
- React-Core/RCTVibrationHeaders (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (= 0.69.8)
|
||||
- React-runtimeexecutor (0.69.8):
|
||||
- React-jsi (= 0.69.8)
|
||||
- ReactCommon/turbomodule/core (0.69.8):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.2)
|
||||
- React-Core (= 0.68.2)
|
||||
- React-cxxreact (= 0.68.2)
|
||||
- React-jsi (= 0.68.2)
|
||||
- React-logger (= 0.68.2)
|
||||
- React-perflogger (= 0.68.2)
|
||||
- SocketRocket (0.6.0)
|
||||
- React-bridging (= 0.69.8)
|
||||
- React-callinvoker (= 0.69.8)
|
||||
- React-Core (= 0.69.8)
|
||||
- React-cxxreact (= 0.69.8)
|
||||
- React-jsi (= 0.69.8)
|
||||
- React-logger (= 0.69.8)
|
||||
- React-perflogger (= 0.69.8)
|
||||
- ReactNativeCameraKit (14.0.0-beta9):
|
||||
- React-Core
|
||||
- RNVectorIcons (10.0.3):
|
||||
- React-Core
|
||||
- SSZipArchive (2.4.3)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (= 0.125.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 3.2.0)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Folly (= 2.6.10)
|
||||
- Flipper-Glog (= 0.5.0.4)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.125.0)
|
||||
- FlipperKit/Core (= 0.125.0)
|
||||
- FlipperKit/CppBridge (= 0.125.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.125.0)
|
||||
- FlipperKit/FBDefines (= 0.125.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.125.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.125.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.125.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- OpenSSL-Universal (= 1.1.1100)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-bridging (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
@@ -407,7 +330,8 @@ DEPENDENCIES:
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- 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-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
@@ -420,26 +344,14 @@ DEPENDENCIES:
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- ReactNativeCameraKit (from `../node_modules/react-native-camera-kit`)
|
||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt
|
||||
- Flipper-Folly
|
||||
- Flipper-Glog
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- fmt
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- SocketRocket
|
||||
- SSZipArchive
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
@@ -460,6 +372,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-bridging:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Codegen:
|
||||
@@ -478,8 +392,10 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-update:
|
||||
:path: "../../.."
|
||||
:path: "../node_modules/react-native-update"
|
||||
React-perflogger:
|
||||
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
|
||||
React-RCTActionSheet:
|
||||
@@ -504,59 +420,53 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
ReactNativeCameraKit:
|
||||
:path: "../node_modules/react-native-camera-kit"
|
||||
RNVectorIcons:
|
||||
:path: "../node_modules/react-native-vector-icons"
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: a7a655862f6b09625d11c772296b01cd5164b648
|
||||
FBReactNativeSpec: 81ce99032d5b586fddd6a38d450f8595f7e04be4
|
||||
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 3d3d04a078d4f3a1b6c6916587f159dc11f232c4
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
|
||||
Flipper-Glog: 87bc98ff48de90cb5b0b5114ed3da79d85ee2dd4
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
FBLazyVector: c7b6997d41fffaaaf4d18c82bc93885df731e2d0
|
||||
FBReactNativeSpec: b1217c558a3ae84c2057d9c2ddce88af21379a68
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
||||
RCTRequired: 3e917ea5377751094f38145fdece525aa90545a0
|
||||
RCTTypeSafety: c43c072a4bd60feb49a9570b0517892b4305c45e
|
||||
React: 176dd882de001854ced260fad41bb68a31aa4bd0
|
||||
React-callinvoker: c2864d1818d6e64928d2faf774a3800dfc38fe1f
|
||||
React-Codegen: 98b6f97f0a7abf7d67e4ce435c77c05b7a95cf05
|
||||
React-Core: fdaa2916b1c893f39f02cff0476d1fb0cab1e352
|
||||
React-CoreModules: fd8705b80699ec36c2cdd635c2ce9d874b9cfdfc
|
||||
React-cxxreact: 1832d971f7b0cb2c7b943dc0ec962762c90c906e
|
||||
React-jsi: 72af715135abe8c3f0dcf3b2548b71d048b69a7e
|
||||
React-jsiexecutor: b7b553412f2ec768fe6c8f27cd6bafdb9d8719e6
|
||||
React-jsinspector: c5989c77cb89ae6a69561095a61cce56a44ae8e8
|
||||
React-logger: a0833912d93b36b791b7a521672d8ee89107aff1
|
||||
react-native-update: 35b44bdcfd37e0f0bbef8ceb1bdda85067e591ff
|
||||
React-perflogger: a18b4f0bd933b8b24ecf9f3c54f9bf65180f3fe6
|
||||
React-RCTActionSheet: 547fe42fdb4b6089598d79f8e1d855d7c23e2162
|
||||
React-RCTAnimation: bc9440a1c37b06ae9ebbb532d244f607805c6034
|
||||
React-RCTBlob: a1295c8e183756d7ef30ba6e8f8144dfe8a19215
|
||||
React-RCTImage: a30d1ee09b1334067fbb6f30789aae2d7ac150c9
|
||||
React-RCTLinking: ffc6d5b88d1cb9aca13c54c2ec6507fbf07f2ac4
|
||||
React-RCTNetwork: f807a2facab6cf5cf36d592e634611de9cf12d81
|
||||
React-RCTSettings: 861806819226ed8332e6a8f90df2951a34bb3e7f
|
||||
React-RCTText: f3fb464cc41a50fc7a1aba4deeb76a9ad8282cb9
|
||||
React-RCTVibration: 79040b92bfa9c3c2d2cb4f57e981164ec7ab9374
|
||||
React-runtimeexecutor: b960b687d2dfef0d3761fbb187e01812ebab8b23
|
||||
ReactCommon: 095366164a276d91ea704ce53cb03825c487a3f2
|
||||
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
|
||||
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
|
||||
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
|
||||
RCTRequired: 344fd6fb3c669da87e91294be7ee0199bf35c701
|
||||
RCTTypeSafety: ca608cc1d3a81229632bc0c1136b698b9337c1d8
|
||||
React: 1d76bae8d73113b202224075f0b0bd546996b328
|
||||
React-bridging: 2eb62dc8ba31194d285705cb62e24a15753aeaec
|
||||
React-callinvoker: f3cfb045a0fb185445542555d88b6acf385cbedc
|
||||
React-Codegen: 808e2d4d4201583ac89fb40d6862aaa26cb88999
|
||||
React-Core: 82c5392ab182252ce4ffbc16794e0e38b32ea9a1
|
||||
React-CoreModules: 4e891a6c0a59b01ca8406e041c7e49ab12e51d48
|
||||
React-cxxreact: 0dc4ba3d97839bd36d422592ddb0bdfa9940a990
|
||||
React-jsi: dcd936ff5e580dba0d8644ac9ee4ca47bb166df1
|
||||
React-jsiexecutor: 2cf8ea3753afb81dfcc386613dbbb0b5d155fb34
|
||||
React-jsinspector: 0eda09e9cf22bbb5dbb1d23143b03a31acf37d67
|
||||
React-logger: 5997ab008583826c10ffe4e1ff990363e975639d
|
||||
react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89
|
||||
react-native-update: a7f136a3c87183b13c7ff5c4f9d2b614930968ad
|
||||
React-perflogger: ad1416a715d86b32f456e5d0aed99c3b52f1de37
|
||||
React-RCTActionSheet: cbf7c6a953982562418ee72a1084ff7b9447b558
|
||||
React-RCTAnimation: 33df3e25824dd7313edec28dded2745542f9352b
|
||||
React-RCTBlob: 2434411df0d2d0e6567445a995f6678e2cc1d8e3
|
||||
React-RCTImage: 0b912ab4255ea5ec903d06c77f5a23cea9e9c988
|
||||
React-RCTLinking: eb239c24f4f5fe79c57a2fedf45f34f40481dda3
|
||||
React-RCTNetwork: db173a6c35c1212909944920a5aa03eb8b7b9cf4
|
||||
React-RCTSettings: 687fa7538972467d80cd7729b6f86598e1369813
|
||||
React-RCTText: 605ef414f8e72bd111945d3612cd0518de612b24
|
||||
React-RCTVibration: 5462287ee85304ba1a00474665ab292e63a41663
|
||||
React-runtimeexecutor: 9df680f18497367bcf5c15b6b6406c0f2dfa2b6a
|
||||
ReactCommon: c10f046f3ef8561e7c8e7e9b9dae2ecc9ffc48ef
|
||||
ReactNativeCameraKit: 4bec78d688adcd68772af2834d5c30a6a8e2a384
|
||||
RNVectorIcons: bc7ee28cadf39c77a49232a14738dfce690f66cd
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
Yoga: 99652481fcd320aefa4a7ef90095b95acd181952
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
Yoga: d3820731e0ca3a4933f061ad29defaf7726e3251
|
||||
|
||||
PODFILE CHECKSUM: 3360a41d7ffd204bbb0ce92d9f9025f372649143
|
||||
PODFILE CHECKSUM: d91298a06dc138c1778443a87db930ad51725939
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.15.2
|
||||
|
@@ -1,24 +0,0 @@
|
||||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
@@ -1,66 +0,0 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#define TIMEOUT_SECONDS 600
|
||||
#define TEXT_TO_LOOK_FOR @"Welcome to React"
|
||||
|
||||
@interface testHotupdateTests : XCTestCase
|
||||
|
||||
@end
|
||||
|
||||
@implementation testHotupdateTests
|
||||
|
||||
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test
|
||||
{
|
||||
if (test(view)) {
|
||||
return YES;
|
||||
}
|
||||
for (UIView *subview in [view subviews]) {
|
||||
if ([self findSubviewInView:subview matching:test]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)testRendersWelcomeScreen
|
||||
{
|
||||
UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
|
||||
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
|
||||
BOOL foundElement = NO;
|
||||
|
||||
__block NSString *redboxError = nil;
|
||||
#ifdef DEBUG
|
||||
RCTSetLogFunction(
|
||||
^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
|
||||
if (level >= RCTLogLevelError) {
|
||||
redboxError = message;
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
|
||||
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
|
||||
|
||||
foundElement = [self findSubviewInView:vc.view
|
||||
matching:^BOOL(UIView *view) {
|
||||
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
RCTSetLogFunction(RCTDefaultLogFunction);
|
||||
#endif
|
||||
|
||||
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
|
||||
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
|
||||
}
|
||||
|
||||
@end
|
@@ -1,11 +1,12 @@
|
||||
const path = require('path');
|
||||
// const path = require('path');
|
||||
|
||||
const extraNodeModules = {
|
||||
'react-native': path.resolve(__dirname, 'node_modules/react-native'),
|
||||
'react-native-update': path.resolve(__dirname, '../..'),
|
||||
'@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
|
||||
};
|
||||
const watchFolders = [path.resolve(__dirname, '../..')];
|
||||
// const extraNodeModules = {
|
||||
// react: path.resolve(__dirname, 'node_modules/react'),
|
||||
// 'react-native': path.resolve(__dirname, 'node_modules/react-native'),
|
||||
// 'react-native-update': path.resolve(__dirname, '../..'),
|
||||
// '@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
|
||||
// };
|
||||
// const watchFolders = [path.resolve(__dirname, '../..')];
|
||||
|
||||
module.exports = {
|
||||
transformer: {
|
||||
@@ -16,8 +17,8 @@ module.exports = {
|
||||
},
|
||||
}),
|
||||
},
|
||||
resolver: {
|
||||
extraNodeModules,
|
||||
},
|
||||
watchFolders,
|
||||
// resolver: {
|
||||
// extraNodeModules,
|
||||
// },
|
||||
// watchFolders,
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "testhotupdate",
|
||||
"name": "testHotUpdate",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -7,23 +7,35 @@
|
||||
"ios": "react-native run-ios",
|
||||
"start": "react-native start",
|
||||
"test": "jest",
|
||||
"test:e2e": "detox test --configuration android.emu.debug",
|
||||
"lint": "eslint .",
|
||||
"apk": "(cd android && ./gradlew aR)"
|
||||
"postinstall": "patch-package",
|
||||
"apk": "cd android && ./gradlew assembleRelease"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.68.5",
|
||||
"react-native-update": "link:../.."
|
||||
"patch-package": "^6.5.1",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"react": "18.0.0",
|
||||
"react-native": "0.69.8",
|
||||
"react-native-camera-kit": "^14.0.0-beta15",
|
||||
"react-native-paper": "^5.12.1",
|
||||
"react-native-safe-area-context": "^4.8.2",
|
||||
"react-native-update": "^10.11.3",
|
||||
"react-native-vector-icons": "^10.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"eslint": "^7.32.0",
|
||||
"jest": "^26.6.3",
|
||||
"metro-react-native-babel-preset": "^0.67.0",
|
||||
"react-test-renderer": "17.0.2"
|
||||
"@babel/core": "^7.21.0",
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@react-native-community/eslint-config": "^3.2.0",
|
||||
"babel-jest": "^29.5.0",
|
||||
"detox": "^20.5.0",
|
||||
"eslint": "^8.36.0",
|
||||
"jest": "^29.5.0",
|
||||
"metro-react-native-babel-preset": "^0.76.0",
|
||||
"pod-install": "^0.1.37",
|
||||
"prettier": "^2.8.4",
|
||||
"react-test-renderer": "18.2.0",
|
||||
"ts-jest": "^29.0.5"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
|
13
Example/testHotUpdate/patches/react-native+0.69.8.patch
Normal file
13
Example/testHotUpdate/patches/react-native+0.69.8.patch
Normal 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" =>
|
10
Example/testHotUpdate/scripts/start-rn.sh
Executable file
10
Example/testHotUpdate/scripts/start-rn.sh
Executable 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
|
@@ -1,21 +1,140 @@
|
||||
import React from 'react';
|
||||
/* eslint-disable react-native/no-inline-styles */
|
||||
/* eslint-disable react/react-in-jsx-scope */
|
||||
import {useCallback, useMemo, useState} from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Modal,
|
||||
TextInput,
|
||||
Button,
|
||||
NativeModules,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
Text,
|
||||
View,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
|
||||
const Pushy = NativeModules.Pushy;
|
||||
import {PushyModule} from 'react-native-update';
|
||||
const Hash = '9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474';
|
||||
const UUID = '00000000-0000-0000-0000-000000000000';
|
||||
const DownloadUrl =
|
||||
'http://cos.pgyer.com/697913e94d7441f20c686e2b0996a1aa.apk?sign=7a8f11b1df82cba45c8ac30b1acec88c&t=1680404102&response-content-disposition=attachment%3Bfilename%3DtestHotupdate_1.0.apk';
|
||||
|
||||
const CustomDialog = ({title, visible, onConfirm}) => {
|
||||
if (!visible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.overlay}>
|
||||
<View style={styles.dialog}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<TouchableOpacity
|
||||
testID="done"
|
||||
style={styles.button}
|
||||
onLongPress={onConfirm}>
|
||||
<Text style={styles.buttonText}>确认</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
export default function TestConsole({visible}) {
|
||||
const [text, setText] = React.useState('');
|
||||
const [running, setRunning] = React.useState(false);
|
||||
const [text, setText] = useState('');
|
||||
const [running, setRunning] = useState(false);
|
||||
const [options, setOptions] = useState();
|
||||
const [alertVisible, setAlertVisible] = useState(false);
|
||||
const [alertMsg, setAlertMsg] = useState('');
|
||||
const NativeTestMethod = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
name: 'setLocalHashInfo',
|
||||
invoke: () => {
|
||||
setText(
|
||||
`setLocalHashInfo\n${Hash}\n{\"version\":\"1.0.0\",\"size\":\"19M\"}`,
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'getLocalHashInfo',
|
||||
invoke: () => {
|
||||
setText(`getLocalHashInfo\n${Hash}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'setUuid',
|
||||
invoke: () => {
|
||||
setText(`setUuid\n${UUID}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'reloadUpdate',
|
||||
invoke: () => {
|
||||
setText('reloadUpdate');
|
||||
setOptions({hash: Hash});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'setNeedUpdate',
|
||||
invoke: () => {
|
||||
setText('setNeedUpdate');
|
||||
setOptions({hash: Hash});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'markSuccess',
|
||||
invoke: () => {
|
||||
setText('markSuccess');
|
||||
setOptions(undefined);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'downloadPatchFromPpk',
|
||||
invoke: () => {
|
||||
setText('downloadPatchFromPpk');
|
||||
setOptions({updateUrl: DownloadUrl, hash: Hash, originHash: Hash});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'downloadPatchFromPackage',
|
||||
invoke: () => {
|
||||
setText('downloadPatchFromPackage');
|
||||
setOptions({updateUrl: DownloadUrl, hash: Hash});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'downloadFullUpdate',
|
||||
invoke: () => {
|
||||
setText('downloadFullUpdate');
|
||||
setOptions({updateUrl: DownloadUrl, hash: Hash});
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'downloadAndInstallApk',
|
||||
invoke: () => {
|
||||
setText('downloadAndInstallApk');
|
||||
setOptions({url: DownloadUrl, target: Hash, hash: Hash});
|
||||
},
|
||||
},
|
||||
];
|
||||
}, []);
|
||||
|
||||
const renderTestView = useCallback(() => {
|
||||
const views = [];
|
||||
for (let i = 0; i < NativeTestMethod.length; i++) {
|
||||
views.push(
|
||||
<TouchableOpacity
|
||||
key={i}
|
||||
testID={NativeTestMethod[i].name}
|
||||
onLongPress={() => {
|
||||
NativeTestMethod[i].invoke();
|
||||
}}>
|
||||
<Text>{NativeTestMethod[i].name}</Text>
|
||||
</TouchableOpacity>,
|
||||
);
|
||||
}
|
||||
return <View>{views}</View>;
|
||||
}, [NativeTestMethod]);
|
||||
|
||||
return (
|
||||
<Modal visible={visible}>
|
||||
<SafeAreaView style={{flex: 1, padding: 10}}>
|
||||
@@ -38,39 +157,97 @@ export default function TestConsole({visible}) {
|
||||
onChangeText={setText}
|
||||
/>
|
||||
{running && <ActivityIndicator />}
|
||||
<Button
|
||||
title="执行"
|
||||
onPress={async () => {
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
backgroundColor: 'rgb(0,140,237)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
marginBottom: 5,
|
||||
}}
|
||||
testID="submit"
|
||||
onLongPress={async () => {
|
||||
setRunning(true);
|
||||
try {
|
||||
const inputs = text.split('\n');
|
||||
const methodName = inputs[0];
|
||||
let params;
|
||||
let params = [];
|
||||
if (inputs.length === 1) {
|
||||
await Pushy[methodName]();
|
||||
if (options) {
|
||||
await PushyModule[methodName](options);
|
||||
} else {
|
||||
await PushyModule[methodName]();
|
||||
}
|
||||
} else {
|
||||
if (inputs.length === 2) {
|
||||
params = inputs[1];
|
||||
params = [inputs[1]];
|
||||
} else {
|
||||
params = {};
|
||||
for (let i = 1; i < inputs.length; i += 2) {
|
||||
params[inputs[i]] = inputs[i + 1];
|
||||
}
|
||||
params = [inputs[1], inputs[2]];
|
||||
console.log({inputs, params});
|
||||
}
|
||||
await Pushy[methodName](params);
|
||||
await PushyModule[methodName](...params);
|
||||
}
|
||||
Alert.alert('done');
|
||||
setAlertVisible(true);
|
||||
setAlertMsg('done');
|
||||
} catch (e) {
|
||||
Alert.alert(e.message);
|
||||
setAlertVisible(true);
|
||||
setAlertMsg(e.message);
|
||||
}
|
||||
setRunning(false);
|
||||
}}>
|
||||
<Text style={{color: 'white'}}>执行</Text>
|
||||
</TouchableOpacity>
|
||||
<Button title="重置" onPress={() => setText('')} />
|
||||
{renderTestView()}
|
||||
<CustomDialog
|
||||
title={alertMsg}
|
||||
visible={alertVisible}
|
||||
onConfirm={() => {
|
||||
setAlertVisible(false);
|
||||
}}
|
||||
/>
|
||||
<View style={{marginTop: 15}}>
|
||||
<Button title="重置" onPress={() => setText('')} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
overlay: {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
dialog: {
|
||||
backgroundColor: 'white',
|
||||
borderRadius: 10,
|
||||
padding: 20,
|
||||
width: '80%',
|
||||
alignItems: 'center',
|
||||
},
|
||||
title: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
marginBottom: 20,
|
||||
},
|
||||
button: {
|
||||
backgroundColor: '#2196F3',
|
||||
borderRadius: 5,
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
buttonText: {
|
||||
color: 'white',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
});
|
||||
|
@@ -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: {},
|
||||
});
|
204
Example/testHotUpdate/src/index.tsx
Normal file
204
Example/testHotUpdate/src/index.tsx
Normal file
@@ -0,0 +1,204 @@
|
||||
/* eslint-disable react/no-unstable-nested-components */
|
||||
/* eslint-disable react-native/no-inline-styles */
|
||||
import React, {useRef, useState} from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Platform,
|
||||
Text,
|
||||
View,
|
||||
TouchableOpacity,
|
||||
Image,
|
||||
Switch,
|
||||
} from 'react-native';
|
||||
import {
|
||||
Icon,
|
||||
PaperProvider,
|
||||
Snackbar,
|
||||
Banner,
|
||||
Button,
|
||||
Modal,
|
||||
Portal,
|
||||
} from 'react-native-paper';
|
||||
import {Camera} from 'react-native-camera-kit';
|
||||
|
||||
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,
|
||||
parseTestQrCode,
|
||||
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;
|
||||
const [showCamera, setShowCamera] = useState(false);
|
||||
const lastParsedCode = useRef('');
|
||||
|
||||
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({
|
||||
updateStrategy: v ? null : 'alwaysAlert',
|
||||
});
|
||||
setShowUpdateSnackbar(!v);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<Button onPress={() => setShowCamera(true)}>打开相机</Button>
|
||||
<Portal>
|
||||
<Modal visible={showCamera} onDismiss={() => setShowCamera(false)}>
|
||||
<Camera
|
||||
style={{minHeight: 320}}
|
||||
scanBarcode={true}
|
||||
onReadCode={({nativeEvent: {codeStringValue}}) => {
|
||||
// 防止重复扫码
|
||||
if (lastParsedCode.current === codeStringValue) {
|
||||
return;
|
||||
}
|
||||
lastParsedCode.current = codeStringValue;
|
||||
setTimeout(() => {
|
||||
lastParsedCode.current = '';
|
||||
}, 1000);
|
||||
setShowCamera(false);
|
||||
parseTestQrCode(codeStringValue);
|
||||
}} // optional
|
||||
showFrame={true} // (default false) optional, show frame with transparent layer (qr code or barcode will be read on this area ONLY), start animation for scanner, that stops when a code has been found. Frame always at center of the screen
|
||||
laserColor="red" // (default red) optional, color of laser in scanner frame
|
||||
frameColor="white" // (default white) optional, color of border of scanner frame
|
||||
/>
|
||||
</Modal>
|
||||
</Portal>
|
||||
<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>
|
||||
);
|
||||
}
|
10
Example/testHotUpdate/update.json
Normal file
10
Example/testHotUpdate/update.json
Normal 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
@@ -8,9 +8,9 @@
|
||||
|
||||
### 优势
|
||||
|
||||
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
|
||||
1. 对中国用户使用阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。对国外用户则智能分流至 cloudflare,同样享受高速更新服务。
|
||||
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
|
||||
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。(暂不支持新架构,会待其相对稳定后跟进)
|
||||
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。支持新架构。
|
||||
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
||||
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||
6. 支持崩溃回滚,安全可靠。
|
||||
|
@@ -5,9 +5,40 @@ def safeExtGet(prop, fallback) {
|
||||
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
||||
}
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||
}
|
||||
|
||||
def supportsNamespace() {
|
||||
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
||||
def major = parsed[0].toInteger()
|
||||
def minor = parsed[1].toInteger()
|
||||
|
||||
// Namespace support was added in 7.3.0
|
||||
if (major == 7 && minor >= 3) {
|
||||
return true
|
||||
}
|
||||
|
||||
return major >= 8
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
if (isNewArchitectureEnabled()) {
|
||||
apply plugin: 'com.facebook.react'
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
|
||||
if (supportsNamespace()) {
|
||||
namespace "cn.reactnative.modules.update"
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile "src/main/AndroidManifestNew.xml"
|
||||
}
|
||||
}
|
||||
}
|
||||
compileSdkVersion safeExtGet('compileSdkVersion', 28)
|
||||
buildToolsVersion safeExtGet('buildToolsVersion', '28.0.3')
|
||||
|
||||
@@ -17,11 +48,17 @@ android {
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
consumerProguardFiles "proguard.pro"
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
// let gradle pack the shared library into apk
|
||||
jniLibs.srcDirs = ['./lib']
|
||||
if (isNewArchitectureEnabled()) {
|
||||
java.srcDirs += ['src/newarch']
|
||||
} else {
|
||||
java.srcDirs += ['src/oldarch']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +81,12 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
implementation 'com.facebook.react:react-native:+'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
|
||||
}
|
||||
if (isNewArchitectureEnabled()) {
|
||||
react {
|
||||
jsRootDir = file("../lib/")
|
||||
libraryName = "update"
|
||||
codegenJavaPackageName = "cn.reactnative.modules.update"
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
|
||||
mem_as_hStreamInput(&patStream,pat,pat+patsize);
|
||||
if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0))
|
||||
return kHPatch_error_info;//data error;
|
||||
return kHPatch_ok; //ok
|
||||
return kHPatch_ok; //ok
|
||||
}
|
||||
|
||||
static hpatch_TDecompress* getDecompressPlugin(const char* compressType){
|
||||
@@ -68,7 +68,7 @@ static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOld
|
||||
_check(decompressPlugin,kHPatch_error_compressType);
|
||||
}
|
||||
}
|
||||
{// mem
|
||||
{// mem
|
||||
size_t mem_size;
|
||||
size_t oldSize=(size_t)old->streamSize;
|
||||
isLoadOldAllToMem=isLoadOldAllToMem&&(old->streamSize<=kMaxLoadMemOldSize);
|
||||
@@ -76,7 +76,7 @@ static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOld
|
||||
mem_size=temp_cache_size+(isLoadOldAllToMem?oldSize:0);
|
||||
temp_cache=malloc(mem_size);
|
||||
_check(temp_cache,kHPatch_error_malloc);
|
||||
if (isLoadOldAllToMem){//load old to mem
|
||||
if (isLoadOldAllToMem){//load old to mem
|
||||
uint8_t* oldMem=temp_cache+temp_cache_size;
|
||||
_check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread);
|
||||
mem_as_hStreamInput(&_old,oldMem,oldMem+oldSize);
|
||||
@@ -95,7 +95,7 @@ _clear:
|
||||
}
|
||||
|
||||
int hpatch_by_mem(const uint8_t* old,size_t oldsize,uint8_t* newBuf,size_t newsize,
|
||||
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
|
||||
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
|
||||
hpatch_TStreamInput oldStream;
|
||||
hpatch_TStreamInput patStream;
|
||||
hpatch_TStreamOutput newStream;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
// hpatch.h
|
||||
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
|
||||
// hpatch.h
|
||||
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
|
||||
// Copyright 2021 housisong, All rights reserved
|
||||
|
||||
#ifndef HDIFFPATCH_PATCH_H
|
||||
@@ -41,4 +41,4 @@ int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfi
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //HDIFFPATCH_PATCH_H
|
||||
#endif //HDIFFPATCH_PATCH_H
|
||||
|
1
android/proguard.pro
vendored
1
android/proguard.pro
vendored
@@ -1,2 +1,3 @@
|
||||
-keepnames class cn.reactnative.modules.update.DownloadTask { *; }
|
||||
-keepnames class cn.reactnative.modules.update.UpdateModuleImpl { *; }
|
||||
-keepnames class com.facebook.react.ReactInstanceManager { *; }
|
@@ -1,9 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.reactnative.modules.update">
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<application>
|
||||
<meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
|
||||
<provider
|
||||
|
14
android/src/main/AndroidManifestNew.xml
Normal file
14
android/src/main/AndroidManifestNew.xml
Normal 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>
|
@@ -75,7 +75,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
.build();
|
||||
Response response = client.newCall(request).execute();
|
||||
if (response.code() > 299) {
|
||||
throw new Error("Server return code " + response.code());
|
||||
throw new Error("Server error:" + response.code() + " " + response.message());
|
||||
}
|
||||
ResponseBody body = response.body();
|
||||
long contentLength = body.contentLength();
|
||||
@@ -237,19 +237,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
|
||||
String fn = ze.getName();
|
||||
File fmd = new File(param.unzipDirectory, fn);
|
||||
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzipping " + fn);
|
||||
}
|
||||
|
||||
if (ze.isDirectory()) {
|
||||
fmd.mkdirs();
|
||||
continue;
|
||||
}
|
||||
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
zipFile.unzipToPath(ze, param.unzipDirectory);
|
||||
}
|
||||
|
||||
zipFile.close();
|
||||
@@ -324,8 +312,15 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
} else {
|
||||
target = copyList.get((from));
|
||||
}
|
||||
target.add(new File(param.unzipDirectory, to));
|
||||
//copyFromResource(from, new File(param.unzipDirectory, to));
|
||||
File toFile = new File(param.unzipDirectory, to);
|
||||
|
||||
// Fixing a Zip Path Traversal Vulnerability
|
||||
// https://support.google.com/faqs/answer/9294009
|
||||
String canonicalPath = toFile.getCanonicalPath();
|
||||
if (!canonicalPath.startsWith(param.unzipDirectory.getCanonicalPath() + File.separator)) {
|
||||
throw new SecurityException("Illegal name: " + to);
|
||||
}
|
||||
target.add(toFile);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -339,18 +334,9 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
fout.close();
|
||||
continue;
|
||||
}
|
||||
File fmd = new File(param.unzipDirectory, fn);
|
||||
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzipping " + fn);
|
||||
}
|
||||
|
||||
if (ze.isDirectory()) {
|
||||
fmd.mkdirs();
|
||||
continue;
|
||||
}
|
||||
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
zipFile.unzipToPath(ze, param.unzipDirectory);
|
||||
}
|
||||
|
||||
zipFile.close();
|
||||
@@ -419,18 +405,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
fout.close();
|
||||
continue;
|
||||
}
|
||||
File fmd = new File(param.unzipDirectory, fn);
|
||||
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzipping " + fn);
|
||||
}
|
||||
|
||||
if (ze.isDirectory()) {
|
||||
fmd.mkdirs();
|
||||
continue;
|
||||
}
|
||||
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
zipFile.unzipToPath(ze, param.unzipDirectory);
|
||||
}
|
||||
|
||||
zipFile.close();
|
||||
|
@@ -1,7 +1,5 @@
|
||||
package cn.reactnative.modules.update;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package cn.reactnative.modules.update;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
@@ -10,12 +12,15 @@ import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
||||
public class SafeZipFile extends ZipFile {
|
||||
|
||||
public SafeZipFile(File file) throws IOException {
|
||||
super(file);
|
||||
}
|
||||
|
||||
private static final int BUFFER_SIZE = 8192;
|
||||
|
||||
@Override
|
||||
public Enumeration<? extends ZipEntry> entries() {
|
||||
return new SafeZipEntryIterator(super.entries());
|
||||
@@ -43,40 +48,46 @@ public class SafeZipFile extends ZipFile {
|
||||
* avoid ZipperDown
|
||||
*/
|
||||
if (null != name && (name.contains("../") || name.contains("..\\"))) {
|
||||
throw new SecurityException("illegal entry: " + entry.getName());
|
||||
throw new SecurityException("illegal entry: " + name);
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
public void unzipToFile(ZipEntry entry, File output) throws IOException {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = getInputStream(entry);
|
||||
writeOutInputStream(output, inputStream);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
public void unzipToPath(ZipEntry ze, File targetPath) throws IOException {
|
||||
String name = ze.getName();
|
||||
File target = new File(targetPath, name);
|
||||
|
||||
// Fixing a Zip Path Traversal Vulnerability
|
||||
// https://support.google.com/faqs/answer/9294009
|
||||
String canonicalPath = target.getCanonicalPath();
|
||||
if (!canonicalPath.startsWith(targetPath.getCanonicalPath() + File.separator)) {
|
||||
throw new SecurityException("Illegal name: " + name);
|
||||
}
|
||||
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzipping " + name);
|
||||
}
|
||||
|
||||
if (ze.isDirectory()) {
|
||||
target.mkdirs();
|
||||
return;
|
||||
}
|
||||
unzipToFile(ze, target);
|
||||
}
|
||||
|
||||
public void unzipToFile(ZipEntry ze, File target) throws IOException {
|
||||
try (InputStream inputStream = getInputStream(ze)) {
|
||||
try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(target));
|
||||
BufferedInputStream input = new BufferedInputStream(inputStream)) {
|
||||
byte[] buffer = new byte[BUFFER_SIZE];
|
||||
int n;
|
||||
while ((n = input.read(buffer, 0, BUFFER_SIZE)) >= 0) {
|
||||
output.write(buffer, 0, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOutInputStream(File file, InputStream inputStream) throws IOException {
|
||||
BufferedOutputStream output = null;
|
||||
try {
|
||||
output = new BufferedOutputStream(
|
||||
new FileOutputStream(file));
|
||||
BufferedInputStream input = new BufferedInputStream(inputStream);
|
||||
byte b[] = new byte[8192];
|
||||
int n;
|
||||
while ((n = input.read(b, 0, 8192)) >= 0) {
|
||||
output.write(b, 0, n);
|
||||
}
|
||||
} finally {
|
||||
if (output != null) {
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -69,13 +69,6 @@ public class UpdateContext {
|
||||
return context.getString(R.string.pushy_build_time);
|
||||
}
|
||||
|
||||
public Map getBlockUpdate() {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("until", sp.getInt("blockUntil", 0));
|
||||
put("reason", sp.getString("blockReason", null));
|
||||
}};
|
||||
}
|
||||
|
||||
public boolean getIsUsingBundleUrl() {
|
||||
return isUsingBundleUrl;
|
||||
}
|
||||
@@ -166,13 +159,6 @@ public class UpdateContext {
|
||||
return sp.getString(key, null);
|
||||
}
|
||||
|
||||
public void setBlockUpdate(int until, String reason) {
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putInt("blockUntil", until);
|
||||
editor.putString("blockReason", reason);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public String getCurrentVersion() {
|
||||
return sp.getString("currentVersion", null);
|
||||
}
|
||||
|
@@ -0,0 +1,248 @@
|
||||
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 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字符串格式错误");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -1,34 +1,45 @@
|
||||
package cn.reactnative.modules.update;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.JavaScriptModule;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.TurboReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import com.facebook.react.module.model.ReactModuleInfo;
|
||||
import com.facebook.react.module.model.ReactModuleInfoProvider;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by tdzl2003 on 3/31/16.
|
||||
*/
|
||||
public class UpdatePackage implements ReactPackage {
|
||||
|
||||
public class UpdatePackage extends TurboReactPackage {
|
||||
@Nullable
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
return Arrays.asList(new NativeModule[]{
|
||||
// Modules from third-party
|
||||
new UpdateModule(reactContext),
|
||||
});
|
||||
}
|
||||
|
||||
public List<Class<? extends JavaScriptModule>> createJSModules() {
|
||||
return Collections.emptyList();
|
||||
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
|
||||
if (name.equals(UpdateModuleImpl.NAME)) {
|
||||
return new UpdateModule(reactContext);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
public ReactModuleInfoProvider getReactModuleInfoProvider() {
|
||||
return () -> {
|
||||
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
|
||||
boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
moduleInfos.put(
|
||||
UpdateModuleImpl.NAME,
|
||||
new ReactModuleInfo(
|
||||
UpdateModuleImpl.NAME,
|
||||
UpdateModuleImpl.NAME,
|
||||
false, // canOverrideExistingModule
|
||||
false, // needsEagerInit
|
||||
true, // hasConstants
|
||||
false, // isCxxModule
|
||||
isTurboModule // isTurboModule
|
||||
));
|
||||
return moduleInfos;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,141 @@
|
||||
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 NativePushySpec {
|
||||
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("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 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);
|
||||
}
|
||||
}
|
@@ -59,14 +59,13 @@ public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
if (rolledBackVersion != null) {
|
||||
updateContext.clearRollbackMark();
|
||||
}
|
||||
constants.put("blockUpdate", updateContext.getBlockUpdate());
|
||||
constants.put("uuid", updateContext.getKv("uuid"));
|
||||
return constants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "RCTPushy";
|
||||
return UpdateModuleImpl.NAME;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -169,7 +168,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void reloadUpdate(ReadableMap options) {
|
||||
public void reloadUpdate(ReadableMap options, final Promise promise) {
|
||||
final String hash = options.getString("hash");
|
||||
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@@ -191,6 +190,7 @@ public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
loadField.setAccessible(true);
|
||||
loadField.set(instanceManager, loader);
|
||||
} catch (Throwable err) {
|
||||
promise.reject(err);
|
||||
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
|
||||
jsBundleField.setAccessible(true);
|
||||
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
|
||||
@@ -198,11 +198,14 @@ public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
|
||||
try {
|
||||
instanceManager.recreateReactContextInBackground();
|
||||
promise.resolve(null);
|
||||
} catch (Throwable err) {
|
||||
activity.recreate();
|
||||
promise.reject(err);
|
||||
}
|
||||
|
||||
} catch (Throwable err) {
|
||||
promise.reject(err);
|
||||
Log.e("pushy", "switchVersion failed", err);
|
||||
}
|
||||
}
|
||||
@@ -235,18 +238,6 @@ public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBlockUpdate(ReadableMap options) {
|
||||
final int until = options.getInt("until");
|
||||
final String reason = options.getString("reason");
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateContext.setBlockUpdate(until, reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setUuid(final String uuid) {
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
3
babel.config.js
Normal file
3
babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
};
|
@@ -1 +1 @@
|
||||
["update.react-native.cn", "update.reactnative.cn"]
|
||||
["update.react-native.cn", "update.reactnative.cn", "p.reactnative.cn"]
|
||||
|
12
e2e/jest.config.js
Normal file
12
e2e/jest.config.js
Normal 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
23
e2e/starter.test.js
Normal 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();
|
||||
});
|
||||
});
|
@@ -1 +1 @@
|
||||
["https://update.react-native.cn/api", "https://update.reactnative.cn/api"]
|
||||
["https://pushy-koa-qgbgqmcpis.cn-beijing.fcapp.run", "https://p.reactnative.cn/api"]
|
||||
|
@@ -14,11 +14,8 @@
|
||||
249F2F64261C58C700A1E60E /* Lzma2Dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F60261C58C700A1E60E /* Lzma2Dec.c */; };
|
||||
249F2F65261C58C700A1E60E /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F62261C58C700A1E60E /* LzmaDec.c */; };
|
||||
91C5F0031C76ECA90037E727 /* RCTPushy.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 91C5F0021C76ECA90037E727 /* RCTPushy.h */; };
|
||||
91C5F0051C76ECA90037E727 /* RCTPushy.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C5F0041C76ECA90037E727 /* RCTPushy.m */; };
|
||||
9F1BCB1D1CAE5937000EF2CB /* RCTPushyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F1BCB1C1CAE5937000EF2CB /* RCTPushyManager.m */; };
|
||||
9F1BCB461CAF6B3E000EF2CB /* bspatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F1BCB3B1CAF6B3E000EF2CB /* bspatch.c */; };
|
||||
9F1BCB4F1CAF6B68000EF2CB /* BSDiff.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F1BCB4E1CAF6B68000EF2CB /* BSDiff.m */; };
|
||||
9F292F7D1C7C44290095945D /* RCTPushyDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F292F7C1C7C44290095945D /* RCTPushyDownloader.m */; };
|
||||
9F394D7D1C7C25DC00C794C0 /* aescrypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D5B1C7C25DC00C794C0 /* aescrypt.c */; };
|
||||
9F394D7E1C7C25DC00C794C0 /* aeskey.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D5C1C7C25DC00C794C0 /* aeskey.c */; };
|
||||
9F394D7F1C7C25DC00C794C0 /* aestab.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D5E1C7C25DC00C794C0 /* aestab.c */; };
|
||||
@@ -33,6 +30,9 @@
|
||||
9F394D881C7C25DC00C794C0 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D761C7C25DC00C794C0 /* unzip.c */; };
|
||||
9F394D891C7C25DC00C794C0 /* zip.c in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D781C7C25DC00C794C0 /* zip.c */; };
|
||||
9F394D8A1C7C25DC00C794C0 /* SSZipArchive.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F394D7B1C7C25DC00C794C0 /* SSZipArchive.m */; };
|
||||
A3FD91A62C3C01600022D27F /* RCTPushy.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3FD91A52C3C01600022D27F /* RCTPushy.mm */; };
|
||||
A3FD91A82C3C01640022D27F /* RCTPushyDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3FD91A72C3C01640022D27F /* RCTPushyDownloader.mm */; };
|
||||
A3FD91AA2C3C01680022D27F /* RCTPushyManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = A3FD91A92C3C01680022D27F /* RCTPushyManager.mm */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@@ -64,15 +64,12 @@
|
||||
249F2F63261C58C700A1E60E /* LzmaDec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaDec.h; path = ../../../android/jni/lzma/C/LzmaDec.h; sourceTree = "<group>"; };
|
||||
91C5EFFF1C76ECA90037E727 /* libRCTPushy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTPushy.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
91C5F0021C76ECA90037E727 /* RCTPushy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTPushy.h; sourceTree = "<group>"; };
|
||||
91C5F0041C76ECA90037E727 /* RCTPushy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTPushy.m; sourceTree = "<group>"; };
|
||||
9F1BCB1B1CAE5937000EF2CB /* RCTPushyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPushyManager.h; sourceTree = "<group>"; };
|
||||
9F1BCB1C1CAE5937000EF2CB /* RCTPushyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPushyManager.m; sourceTree = "<group>"; };
|
||||
9F1BCB3B1CAF6B3E000EF2CB /* bspatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bspatch.c; sourceTree = "<group>"; };
|
||||
9F1BCB3C1CAF6B3E000EF2CB /* bspatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bspatch.h; sourceTree = "<group>"; };
|
||||
9F1BCB4D1CAF6B68000EF2CB /* BSDiff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSDiff.h; sourceTree = "<group>"; };
|
||||
9F1BCB4E1CAF6B68000EF2CB /* BSDiff.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSDiff.m; sourceTree = "<group>"; };
|
||||
9F292F7B1C7C44290095945D /* RCTPushyDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPushyDownloader.h; sourceTree = "<group>"; };
|
||||
9F292F7C1C7C44290095945D /* RCTPushyDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPushyDownloader.m; sourceTree = "<group>"; };
|
||||
9F394D591C7C25DC00C794C0 /* aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes.h; sourceTree = "<group>"; };
|
||||
9F394D5A1C7C25DC00C794C0 /* aes_via_ace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes_via_ace.h; sourceTree = "<group>"; };
|
||||
9F394D5B1C7C25DC00C794C0 /* aescrypt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aescrypt.c; sourceTree = "<group>"; };
|
||||
@@ -108,6 +105,9 @@
|
||||
9F394D7A1C7C25DC00C794C0 /* SSZipArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSZipArchive.h; sourceTree = "<group>"; };
|
||||
9F394D7B1C7C25DC00C794C0 /* SSZipArchive.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSZipArchive.m; sourceTree = "<group>"; };
|
||||
9F394D7C1C7C25DC00C794C0 /* ZipArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ZipArchive.h; sourceTree = "<group>"; };
|
||||
A3FD91A52C3C01600022D27F /* RCTPushy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTPushy.mm; sourceTree = "<group>"; };
|
||||
A3FD91A72C3C01640022D27F /* RCTPushyDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTPushyDownloader.mm; sourceTree = "<group>"; };
|
||||
A3FD91A92C3C01680022D27F /* RCTPushyManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTPushyManager.mm; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -172,11 +172,11 @@
|
||||
9F1BCB381CAF6B3E000EF2CB /* BSDiff */,
|
||||
9F394D571C7C25DC00C794C0 /* SSZipArchive */,
|
||||
91C5F0021C76ECA90037E727 /* RCTPushy.h */,
|
||||
91C5F0041C76ECA90037E727 /* RCTPushy.m */,
|
||||
9F1BCB1B1CAE5937000EF2CB /* RCTPushyManager.h */,
|
||||
9F1BCB1C1CAE5937000EF2CB /* RCTPushyManager.m */,
|
||||
9F292F7B1C7C44290095945D /* RCTPushyDownloader.h */,
|
||||
9F292F7C1C7C44290095945D /* RCTPushyDownloader.m */,
|
||||
A3FD91A52C3C01600022D27F /* RCTPushy.mm */,
|
||||
A3FD91A72C3C01640022D27F /* RCTPushyDownloader.mm */,
|
||||
A3FD91A92C3C01680022D27F /* RCTPushyManager.mm */,
|
||||
);
|
||||
path = RCTPushy;
|
||||
sourceTree = "<group>";
|
||||
@@ -321,25 +321,25 @@
|
||||
9F394D821C7C25DC00C794C0 /* hmac.c in Sources */,
|
||||
9F394D881C7C25DC00C794C0 /* unzip.c in Sources */,
|
||||
249F2F65261C58C700A1E60E /* LzmaDec.c in Sources */,
|
||||
9F1BCB1D1CAE5937000EF2CB /* RCTPushyManager.m in Sources */,
|
||||
249F2F5E261C589D00A1E60E /* patch.c in Sources */,
|
||||
9F1BCB4F1CAF6B68000EF2CB /* BSDiff.m in Sources */,
|
||||
9F394D7E1C7C25DC00C794C0 /* aeskey.c in Sources */,
|
||||
9F394D7F1C7C25DC00C794C0 /* aestab.c in Sources */,
|
||||
9F394D7D1C7C25DC00C794C0 /* aescrypt.c in Sources */,
|
||||
9F394D801C7C25DC00C794C0 /* entropy.c in Sources */,
|
||||
9F292F7D1C7C44290095945D /* RCTPushyDownloader.m in Sources */,
|
||||
249F2F64261C58C700A1E60E /* Lzma2Dec.c in Sources */,
|
||||
249F2F55261C584900A1E60E /* hpatch.c in Sources */,
|
||||
9F394D831C7C25DC00C794C0 /* prng.c in Sources */,
|
||||
9F394D861C7C25DC00C794C0 /* ioapi.c in Sources */,
|
||||
A3FD91A82C3C01640022D27F /* RCTPushyDownloader.mm in Sources */,
|
||||
9F1BCB461CAF6B3E000EF2CB /* bspatch.c in Sources */,
|
||||
A3FD91A62C3C01600022D27F /* RCTPushy.mm in Sources */,
|
||||
9F394D8A1C7C25DC00C794C0 /* SSZipArchive.m in Sources */,
|
||||
249F2F50261C577300A1E60E /* HDiffPatch.m in Sources */,
|
||||
A3FD91AA2C3C01680022D27F /* RCTPushyManager.mm in Sources */,
|
||||
9F394D891C7C25DC00C794C0 /* zip.c in Sources */,
|
||||
9F394D841C7C25DC00C794C0 /* pwd2key.c in Sources */,
|
||||
249F2F59261C586900A1E60E /* file_for_patch.c in Sources */,
|
||||
91C5F0051C76ECA90037E727 /* RCTPushy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user