mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-09-17 19:16:10 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
baebeff7cb | ||
![]() |
c7b78f0d46 | ||
![]() |
21f2c3918e | ||
![]() |
c3689e560c | ||
![]() |
ab1e62dba5 | ||
![]() |
fcfc8c3dbb | ||
![]() |
41af560a39 | ||
![]() |
5784f2f046 | ||
![]() |
e192964185 | ||
![]() |
9240c3db23 | ||
![]() |
427b05f3a4 | ||
![]() |
73c3dc538c |
29
.eslintrc
Normal file
29
.eslintrc
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
extends: '@react-native',
|
|
||||||
};
|
|
49
.github/workflows/e2e_android.yml
vendored
49
.github/workflows/e2e_android.yml
vendored
@@ -1,49 +0,0 @@
|
|||||||
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
182
.github/workflows/e2e_ios.yml
vendored
@@ -1,182 +0,0 @@
|
|||||||
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
10
.github/workflows/scripts/adb_all_emulators.sh
vendored
@@ -1,10 +0,0 @@
|
|||||||
#!/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
13
.github/workflows/scripts/database.rules
vendored
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"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
39
.github/workflows/scripts/firebase.json
vendored
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"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
72
.github/workflows/scripts/firestore.indexes.json
vendored
@@ -1,72 +0,0 @@
|
|||||||
{
|
|
||||||
"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
17
.github/workflows/scripts/firestore.rules
vendored
@@ -1,17 +0,0 @@
|
|||||||
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
10
.github/workflows/scripts/functions/.gitignore
vendored
@@ -1,10 +0,0 @@
|
|||||||
# 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
24
.github/workflows/scripts/functions/package.json
vendored
@@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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
12
.github/workflows/scripts/functions/src/index.ts
vendored
@@ -1,12 +0,0 @@
|
|||||||
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';
|
|
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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');
|
|
@@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
});
|
|
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"module": "commonjs",
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"outDir": "lib",
|
|
||||||
"sourceMap": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": true,
|
|
||||||
"target": "es2017"
|
|
||||||
},
|
|
||||||
"compileOnSave": true,
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
@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
|
|
@@ -1,44 +0,0 @@
|
|||||||
#!/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
21
.github/workflows/scripts/storage.rules
vendored
@@ -1,21 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
10
.gitignore
vendored
10
.gitignore
vendored
@@ -41,12 +41,6 @@ local.properties
|
|||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|
||||||
Example/**/.update
|
Example/**/update.json
|
||||||
Example/**/.pushy
|
|
||||||
Example/testHotUpdate/artifacts
|
|
||||||
|
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
Example/testHotUpdate/.yarn
|
Example/testHotUpdate/.pushy
|
||||||
android/bin
|
|
||||||
Example/testHotUpdate/harmony
|
|
||||||
Example/testHotUpdate/android/app/.cxx
|
|
||||||
|
@@ -47,6 +47,4 @@ Example
|
|||||||
yarn.lock
|
yarn.lock
|
||||||
|
|
||||||
domains.json
|
domains.json
|
||||||
endpoints.json
|
endpoints.json
|
||||||
|
|
||||||
tea.yaml
|
|
@@ -1,6 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
arrowParens: 'avoid',
|
|
||||||
bracketSameLine: true,
|
|
||||||
singleQuote: true,
|
|
||||||
trailingComma: 'all',
|
trailingComma: 'all',
|
||||||
|
singleQuote: true,
|
||||||
};
|
};
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
nodeLinker: node-modules
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
6
Example/testHotUpdate/.buckconfig
Normal file
6
Example/testHotUpdate/.buckconfig
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
[android]
|
||||||
|
target = Google Inc.:Google APIs:23
|
||||||
|
|
||||||
|
[maven_repositories]
|
||||||
|
central = https://repo1.maven.org/maven2
|
2
Example/testHotUpdate/.bundle/config
Normal file
2
Example/testHotUpdate/.bundle/config
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
BUNDLE_PATH: "vendor/bundle"
|
||||||
|
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
@@ -1,94 +0,0 @@
|
|||||||
/** @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',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
@@ -1,4 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
extends: '@react-native',
|
extends: '@react-native-community',
|
||||||
};
|
};
|
||||||
|
67
Example/testHotUpdate/.flowconfig
Normal file
67
Example/testHotUpdate/.flowconfig
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
[ignore]
|
||||||
|
; We fork some components by platform
|
||||||
|
.*/*[.]android.js
|
||||||
|
|
||||||
|
; Ignore "BUCK" generated dirs
|
||||||
|
<PROJECT_ROOT>/\.buckd/
|
||||||
|
|
||||||
|
; Ignore polyfills
|
||||||
|
node_modules/react-native/Libraries/polyfills/.*
|
||||||
|
|
||||||
|
; Flow doesn't support platforms
|
||||||
|
.*/Libraries/Utilities/LoadingView.js
|
||||||
|
|
||||||
|
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||||
|
|
||||||
|
[untyped]
|
||||||
|
.*/node_modules/@react-native-community/cli/.*/.*
|
||||||
|
|
||||||
|
[include]
|
||||||
|
|
||||||
|
[libs]
|
||||||
|
node_modules/react-native/interface.js
|
||||||
|
node_modules/react-native/flow/
|
||||||
|
|
||||||
|
[options]
|
||||||
|
emoji=true
|
||||||
|
|
||||||
|
exact_by_default=true
|
||||||
|
|
||||||
|
format.bracket_spacing=false
|
||||||
|
|
||||||
|
module.file_ext=.js
|
||||||
|
module.file_ext=.json
|
||||||
|
module.file_ext=.ios.js
|
||||||
|
|
||||||
|
munge_underscores=true
|
||||||
|
|
||||||
|
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
|
||||||
|
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
|
||||||
|
|
||||||
|
suppress_type=$FlowIssue
|
||||||
|
suppress_type=$FlowFixMe
|
||||||
|
suppress_type=$FlowFixMeProps
|
||||||
|
suppress_type=$FlowFixMeState
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
sketchy-null-number=warn
|
||||||
|
sketchy-null-mixed=warn
|
||||||
|
sketchy-number=warn
|
||||||
|
untyped-type-import=warn
|
||||||
|
nonstrict-import=warn
|
||||||
|
deprecated-type=warn
|
||||||
|
unsafe-getters-setters=warn
|
||||||
|
unnecessary-invariant=warn
|
||||||
|
signature-verification-failure=warn
|
||||||
|
|
||||||
|
[strict]
|
||||||
|
deprecated-type
|
||||||
|
nonstrict-import
|
||||||
|
sketchy-null
|
||||||
|
unclear-type
|
||||||
|
unsafe-getters-setters
|
||||||
|
untyped-import
|
||||||
|
untyped-type-import
|
||||||
|
|
||||||
|
[version]
|
||||||
|
^0.170.0
|
8
Example/testHotUpdate/.gitignore
vendored
8
Example/testHotUpdate/.gitignore
vendored
@@ -20,7 +20,6 @@ DerivedData
|
|||||||
*.hmap
|
*.hmap
|
||||||
*.ipa
|
*.ipa
|
||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
ios/.xcode.env.local
|
|
||||||
|
|
||||||
# Android/IntelliJ
|
# Android/IntelliJ
|
||||||
#
|
#
|
||||||
@@ -50,10 +49,9 @@ buck-out/
|
|||||||
# For more information about the recommended setup visit:
|
# For more information about the recommended setup visit:
|
||||||
# https://docs.fastlane.tools/best-practices/source-control/
|
# https://docs.fastlane.tools/best-practices/source-control/
|
||||||
|
|
||||||
**/fastlane/report.xml
|
*/fastlane/report.xml
|
||||||
**/fastlane/Preview.html
|
*/fastlane/Preview.html
|
||||||
**/fastlane/screenshots
|
*/fastlane/screenshots
|
||||||
**/fastlane/test_output
|
|
||||||
|
|
||||||
# Bundle artifact
|
# Bundle artifact
|
||||||
*.jsbundle
|
*.jsbundle
|
||||||
|
@@ -1 +0,0 @@
|
|||||||
18
|
|
1
Example/testHotUpdate/.ruby-version
Normal file
1
Example/testHotUpdate/.ruby-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
2.7.4
|
112
Example/testHotUpdate/App.js
Normal file
112
Example/testHotUpdate/App.js
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
6
Example/testHotUpdate/Gemfile
Normal file
6
Example/testHotUpdate/Gemfile
Normal file
@@ -0,0 +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'
|
||||||
|
|
||||||
|
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
100
Example/testHotUpdate/Gemfile.lock
Normal file
100
Example/testHotUpdate/Gemfile.lock
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
CFPropertyList (3.0.5)
|
||||||
|
rexml
|
||||||
|
activesupport (6.1.5.1)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
cocoapods-core (= 1.11.3)
|
||||||
|
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||||
|
cocoapods-downloader (>= 1.4.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-try (>= 1.1.0, < 2.0)
|
||||||
|
colored2 (~> 3.1)
|
||||||
|
escape (~> 0.0.4)
|
||||||
|
fourflusher (>= 2.3.0, < 3.0)
|
||||||
|
gh_inspector (~> 1.0)
|
||||||
|
molinillo (~> 0.8.0)
|
||||||
|
nap (~> 1.0)
|
||||||
|
ruby-macho (>= 1.0, < 3.0)
|
||||||
|
xcodeproj (>= 1.21.0, < 2.0)
|
||||||
|
cocoapods-core (1.11.3)
|
||||||
|
activesupport (>= 5.0, < 7)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
algoliasearch (~> 1.0)
|
||||||
|
concurrent-ruby (~> 1.1)
|
||||||
|
fuzzy_match (~> 2.0.4)
|
||||||
|
nap (~> 1.0)
|
||||||
|
netrc (~> 0.11)
|
||||||
|
public_suffix (~> 4.0)
|
||||||
|
typhoeus (~> 1.0)
|
||||||
|
cocoapods-deintegrate (1.0.5)
|
||||||
|
cocoapods-downloader (1.6.3)
|
||||||
|
cocoapods-plugins (1.0.0)
|
||||||
|
nap
|
||||||
|
cocoapods-search (1.0.1)
|
||||||
|
cocoapods-trunk (1.6.0)
|
||||||
|
nap (>= 0.8, < 2.0)
|
||||||
|
netrc (~> 0.11)
|
||||||
|
cocoapods-try (1.2.0)
|
||||||
|
colored2 (3.1.2)
|
||||||
|
concurrent-ruby (1.1.10)
|
||||||
|
escape (0.0.4)
|
||||||
|
ethon (0.15.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)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
json (2.6.1)
|
||||||
|
minitest (5.15.0)
|
||||||
|
molinillo (0.8.0)
|
||||||
|
nanaimo (0.3.0)
|
||||||
|
nap (1.1.0)
|
||||||
|
netrc (0.11.0)
|
||||||
|
public_suffix (4.0.7)
|
||||||
|
rexml (3.2.5)
|
||||||
|
ruby-macho (2.5.1)
|
||||||
|
typhoeus (1.4.0)
|
||||||
|
ethon (>= 0.9.0)
|
||||||
|
tzinfo (2.0.4)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
|
xcodeproj (1.21.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
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
cocoapods (~> 1.11, >= 1.11.2)
|
||||||
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.7.4p191
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.27
|
@@ -1,66 +0,0 @@
|
|||||||
# 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(
|
android_build_config(
|
||||||
name = "build_config",
|
name = "build_config",
|
||||||
package = "com.awesomeproject",
|
package = "com.testhotupdate",
|
||||||
)
|
)
|
||||||
|
|
||||||
android_resource(
|
android_resource(
|
||||||
name = "res",
|
name = "res",
|
||||||
package = "com.awesomeproject",
|
package = "com.testhotupdate",
|
||||||
res = "src/main/res",
|
res = "src/main/res",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -1,87 +1,225 @@
|
|||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
apply plugin: "com.facebook.react"
|
|
||||||
apply plugin: "kotlin-android"
|
import com.android.build.OutputFile
|
||||||
apply plugin: "kotlin-android-extensions"
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the configuration block to customize your React Native Android app.
|
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||||
* By default you don't need to apply any configuration, just uncomment the lines you need.
|
* and bundleReleaseJsAndAssets).
|
||||||
|
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||||
|
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||||
|
* bundle directly from the development server. Below you can see all the possible configurations
|
||||||
|
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||||
|
* `apply from: "../../node_modules/react-native/react.gradle"` line.
|
||||||
|
*
|
||||||
|
* project.ext.react = [
|
||||||
|
* // the name of the generated asset file containing your JS bundle
|
||||||
|
* bundleAssetName: "index.android.bundle",
|
||||||
|
*
|
||||||
|
* // the entry file for bundle generation. If none specified and
|
||||||
|
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
|
||||||
|
* // default. Can be overridden with ENTRY_FILE environment variable.
|
||||||
|
* entryFile: "index.android.js",
|
||||||
|
*
|
||||||
|
* // https://reactnative.dev/docs/performance#enable-the-ram-format
|
||||||
|
* bundleCommand: "ram-bundle",
|
||||||
|
*
|
||||||
|
* // whether to bundle JS and assets in debug mode
|
||||||
|
* bundleInDebug: false,
|
||||||
|
*
|
||||||
|
* // whether to bundle JS and assets in release mode
|
||||||
|
* bundleInRelease: true,
|
||||||
|
*
|
||||||
|
* // whether to bundle JS and assets in another build variant (if configured).
|
||||||
|
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
|
||||||
|
* // The configuration property can be in the following formats
|
||||||
|
* // 'bundleIn${productFlavor}${buildType}'
|
||||||
|
* // 'bundleIn${buildType}'
|
||||||
|
* // bundleInFreeDebug: true,
|
||||||
|
* // bundleInPaidRelease: true,
|
||||||
|
* // bundleInBeta: true,
|
||||||
|
*
|
||||||
|
* // whether to disable dev mode in custom build variants (by default only disabled in release)
|
||||||
|
* // for example: to disable dev mode in the staging build type (if configured)
|
||||||
|
* devDisabledInStaging: true,
|
||||||
|
* // The configuration property can be in the following formats
|
||||||
|
* // 'devDisabledIn${productFlavor}${buildType}'
|
||||||
|
* // 'devDisabledIn${buildType}'
|
||||||
|
*
|
||||||
|
* // the root of your project, i.e. where "package.json" lives
|
||||||
|
* root: "../../",
|
||||||
|
*
|
||||||
|
* // where to put the JS bundle asset in debug mode
|
||||||
|
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||||
|
*
|
||||||
|
* // where to put the JS bundle asset in release mode
|
||||||
|
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||||
|
*
|
||||||
|
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||||
|
* // require('./image.png')), in debug mode
|
||||||
|
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||||
|
*
|
||||||
|
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||||
|
* // require('./image.png')), in release mode
|
||||||
|
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||||
|
*
|
||||||
|
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||||
|
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||||
|
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||||
|
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||||
|
* // for example, you might want to remove it from here.
|
||||||
|
* inputExcludes: ["android/**", "ios/**"],
|
||||||
|
*
|
||||||
|
* // override which node gets called and with what additional arguments
|
||||||
|
* nodeExecutableAndArgs: ["node"],
|
||||||
|
*
|
||||||
|
* // supply additional arguments to the packager
|
||||||
|
* extraPackagerArgs: []
|
||||||
|
* ]
|
||||||
*/
|
*/
|
||||||
react {
|
|
||||||
/* Folders */
|
|
||||||
// The root of your project, i.e. where "package.json" lives. Default is '..'
|
|
||||||
// root = file("../")
|
|
||||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
|
|
||||||
// reactNativeDir = file("../node_modules/react-native")
|
|
||||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
|
|
||||||
// codegenDir = file("../node_modules/@react-native/codegen")
|
|
||||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
|
|
||||||
// cliFile = file("../node_modules/react-native/cli.js")
|
|
||||||
|
|
||||||
/* Variants */
|
project.ext.react = [
|
||||||
// The list of variants to that are debuggable. For those we're going to
|
enableHermes: false, // clean and rebuild if changing
|
||||||
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
|
]
|
||||||
// If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
|
|
||||||
// debuggableVariants = ["liteDebug", "prodDebug"]
|
|
||||||
|
|
||||||
/* Bundling */
|
apply from: "../../node_modules/react-native/react.gradle"
|
||||||
// A list containing the node command and its flags. Default is just 'node'.
|
|
||||||
// nodeExecutableAndArgs = ["node"]
|
|
||||||
//
|
|
||||||
// The command to run when bundling. By default is 'bundle'
|
|
||||||
// bundleCommand = "ram-bundle"
|
|
||||||
//
|
|
||||||
// The path to the CLI configuration file. Default is empty.
|
|
||||||
// bundleConfig = file(../rn-cli.config.js)
|
|
||||||
//
|
|
||||||
// The name of the generated asset file containing your JS bundle
|
|
||||||
// bundleAssetName = "MyApplication.android.bundle"
|
|
||||||
//
|
|
||||||
// The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
|
|
||||||
// entryFile = file("../js/MyApplication.android.js")
|
|
||||||
//
|
|
||||||
// A list of extra flags to pass to the 'bundle' commands.
|
|
||||||
// See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
|
|
||||||
// extraPackagerArgs = []
|
|
||||||
|
|
||||||
/* Hermes Commands */
|
|
||||||
// The hermes compiler command to run. By default it is 'hermesc'
|
|
||||||
// hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
|
|
||||||
//
|
|
||||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
|
|
||||||
// hermesFlags = ["-O", "-output-source-map"]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
|
* Set this to true to create two separate APKs instead of one:
|
||||||
|
* - An APK that only works on ARM devices
|
||||||
|
* - An APK that only works on x86 devices
|
||||||
|
* The advantage is the size of the APK is reduced by about 4MB.
|
||||||
|
* Upload all the APKs to the Play Store and people will download
|
||||||
|
* the correct one based on the CPU architecture of their device.
|
||||||
|
*/
|
||||||
|
def enableSeparateBuildPerCPUArchitecture = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run Proguard to shrink the Java bytecode in release builds.
|
||||||
*/
|
*/
|
||||||
def enableProguardInReleaseBuilds = false
|
def enableProguardInReleaseBuilds = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The preferred build flavor of JavaScriptCore (JSC)
|
* The preferred build flavor of JavaScriptCore.
|
||||||
*
|
*
|
||||||
* For example, to use the international variant, you can use:
|
* For example, to use the international variant, you can use:
|
||||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
||||||
*
|
*
|
||||||
* The international variant includes ICU i18n library and necessary data
|
* The international variant includes ICU i18n library and necessary data
|
||||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
||||||
* give correct results when using with locales other than en-US. Note that
|
* give correct results when using with locales other than en-US. Note that
|
||||||
* this variant is about 6MiB larger per architecture than default.
|
* this variant is about 6MiB larger per architecture than default.
|
||||||
*/
|
*/
|
||||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable the Hermes VM.
|
||||||
|
*
|
||||||
|
* This should be set on project.ext.react and that value will be read here. If it is not set
|
||||||
|
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||||
|
* and the benefits of using Hermes will therefore be sharply reduced.
|
||||||
|
*/
|
||||||
|
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Architectures to build native code for.
|
||||||
|
*/
|
||||||
|
def reactNativeArchitectures() {
|
||||||
|
def value = project.getProperties().get("reactNativeArchitectures")
|
||||||
|
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
ndkVersion rootProject.ext.ndkVersion
|
ndkVersion rootProject.ext.ndkVersion
|
||||||
|
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||||
|
|
||||||
namespace "com.awesomeproject"
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.awesomeproject"
|
applicationId "com.testhotupdate"
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||||
|
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_PLATFORM=android-21",
|
||||||
|
"APP_STL=c++_shared",
|
||||||
|
"NDK_TOOLCHAIN_VERSION=clang",
|
||||||
|
"GENERATED_SRC_DIR=$buildDir/generated/source",
|
||||||
|
"PROJECT_BUILD_DIR=$buildDir",
|
||||||
|
"REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
|
||||||
|
"REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build"
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!enableSeparateBuildPerCPUArchitecture) {
|
||||||
|
ndk {
|
||||||
|
abiFilters (*reactNativeArchitectures())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
path "$projectDir/src/main/jni/Android.mk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
|
||||||
|
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
|
||||||
|
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
|
||||||
|
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||||
|
into("$buildDir/react-ndk/exported")
|
||||||
|
}
|
||||||
|
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
|
||||||
|
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
|
||||||
|
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
|
||||||
|
into("$buildDir/react-ndk/exported")
|
||||||
|
}
|
||||||
|
afterEvaluate {
|
||||||
|
// If you wish to add a custom TurboModule or component locally,
|
||||||
|
// you should uncomment this line.
|
||||||
|
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||||
|
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||||
|
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||||
|
|
||||||
|
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||||
|
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||||
|
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||||
|
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||||
|
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||||
|
reactNativeArchitectures().each { architecture ->
|
||||||
|
tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
|
||||||
|
dependsOn("preDebugBuild")
|
||||||
|
}
|
||||||
|
tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
|
||||||
|
dependsOn("preReleaseBuild")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
splits {
|
||||||
|
abi {
|
||||||
|
reset()
|
||||||
|
enable enableSeparateBuildPerCPUArchitecture
|
||||||
|
universalApk false // If true, also generate a universal APK
|
||||||
|
include (*reactNativeArchitectures())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
debug {
|
debug {
|
||||||
@@ -96,7 +234,6 @@ android {
|
|||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
crunchPngs false
|
|
||||||
// Caution! In production, you need to generate your own keystore file.
|
// Caution! In production, you need to generate your own keystore file.
|
||||||
// see https://reactnative.dev/docs/signed-apk-android.
|
// see https://reactnative.dev/docs/signed-apk-android.
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
@@ -104,23 +241,79 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applicationVariants are e.g. debug, release
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
variant.outputs.each { output ->
|
||||||
|
// For each separate APK per architecture, set a unique version code as described here:
|
||||||
|
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||||
|
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
|
||||||
|
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||||
|
def abi = output.getFilter(OutputFile.ABI)
|
||||||
|
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||||
|
output.versionCodeOverride =
|
||||||
|
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// The version of react-native is set by the React Native Gradle Plugin
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation("com.facebook.react:react-android")
|
|
||||||
|
//noinspection GradleDynamicVersion
|
||||||
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||||
|
|
||||||
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||||
|
|
||||||
|
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||||
|
exclude group:'com.facebook.fbjni'
|
||||||
|
}
|
||||||
|
|
||||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
|
|
||||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||||
|
exclude group:'com.facebook.flipper'
|
||||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||||
}
|
}
|
||||||
|
|
||||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
|
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||||
if (hermesEnabled.toBoolean()) {
|
exclude group:'com.facebook.flipper'
|
||||||
implementation("com.facebook.react:hermes-android")
|
}
|
||||||
|
|
||||||
|
if (enableHermes) {
|
||||||
|
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||||
|
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||||
|
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||||
} else {
|
} else {
|
||||||
implementation jscFlavor
|
implementation jscFlavor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isNewArchitectureEnabled()) {
|
||||||
|
// If new architecture is enabled, we let you build RN from source
|
||||||
|
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||||
|
// This will be applied to all the imported transtitive dependency.
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy.dependencySubstitution {
|
||||||
|
substitute(module("com.facebook.react:react-native"))
|
||||||
|
.using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run this once to be able to run the application with BUCK
|
||||||
|
// puts all compile dependencies into folder libs for BUCK to use
|
||||||
|
task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
|
from configurations.implementation
|
||||||
|
into 'libs'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||||
|
|
||||||
|
def isNewArchitectureEnabled() {
|
||||||
|
// To opt-in for the New Architecture, you can either:
|
||||||
|
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||||
|
// - Invoke gradle with `-newArchEnabled=true`
|
||||||
|
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||||
|
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||||
|
}
|
||||||
|
@@ -1,29 +0,0 @@
|
|||||||
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
|
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||||
* directory of this source tree.
|
* directory of this source tree.
|
||||||
*/
|
*/
|
||||||
package com.awesomeproject;
|
package com.testhotupdate;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
import com.facebook.flipper.android.AndroidFlipperClient;
|
@@ -1,9 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.awesomeproject">
|
package="com.testhotupdate">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MainApplication"
|
android:name=".MainApplication"
|
||||||
@@ -11,8 +9,7 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme">
|
||||||
android:networkSecurityConfig="@xml/network_security_config">
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
@@ -21,14 +18,8 @@
|
|||||||
android:windowSoftInputMode="adjustResize"
|
android:windowSoftInputMode="adjustResize"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<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>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
@@ -1,32 +0,0 @@
|
|||||||
package com.awesomeproject;
|
|
||||||
|
|
||||||
import com.facebook.react.ReactActivity;
|
|
||||||
import com.facebook.react.ReactActivityDelegate;
|
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
|
||||||
import com.facebook.react.defaults.DefaultReactActivityDelegate;
|
|
||||||
|
|
||||||
public class MainActivity extends ReactActivity {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
|
||||||
* rendering of the component.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected String getMainComponentName() {
|
|
||||||
return "AwesomeProject";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
|
|
||||||
* DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
|
|
||||||
* (aka React 18) with two boolean flags.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
|
||||||
return new DefaultReactActivityDelegate(
|
|
||||||
this,
|
|
||||||
getMainComponentName(),
|
|
||||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
|
||||||
DefaultNewArchitectureEntryPoint.getFabricEnabled());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,70 +0,0 @@
|
|||||||
package com.awesomeproject;
|
|
||||||
|
|
||||||
import android.app.Application;
|
|
||||||
import com.facebook.react.PackageList;
|
|
||||||
import com.facebook.react.ReactApplication;
|
|
||||||
import com.facebook.react.ReactNativeHost;
|
|
||||||
import com.facebook.react.ReactPackage;
|
|
||||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
|
|
||||||
import com.facebook.react.defaults.DefaultReactNativeHost;
|
|
||||||
import com.facebook.soloader.SoLoader;
|
|
||||||
import java.util.List;
|
|
||||||
import cn.reactnative.modules.update.UpdateContext;
|
|
||||||
|
|
||||||
public class MainApplication extends Application implements ReactApplication {
|
|
||||||
|
|
||||||
private final ReactNativeHost mReactNativeHost =
|
|
||||||
new DefaultReactNativeHost(this) {
|
|
||||||
@Override
|
|
||||||
public boolean getUseDeveloperSupport() {
|
|
||||||
return BuildConfig.DEBUG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getJSBundleFile() {
|
|
||||||
return UpdateContext.getBundleUrl(MainApplication.this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<ReactPackage> getPackages() {
|
|
||||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
|
||||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
|
||||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
|
||||||
// packages.add(new MyReactNativePackage());
|
|
||||||
return packages;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isNewArchEnabled() {
|
|
||||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean isHermesEnabled() {
|
|
||||||
return BuildConfig.IS_HERMES_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getJSMainModuleName() {
|
|
||||||
return "index";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReactNativeHost getReactNativeHost() {
|
|
||||||
return mReactNativeHost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
|
||||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
||||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
|
||||||
DefaultNewArchitectureEntryPoint.load();
|
|
||||||
}
|
|
||||||
ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,40 @@
|
|||||||
|
package com.testhotupdate;
|
||||||
|
|
||||||
|
import com.facebook.react.ReactActivity;
|
||||||
|
import com.facebook.react.ReactActivityDelegate;
|
||||||
|
import com.facebook.react.ReactRootView;
|
||||||
|
|
||||||
|
public class MainActivity extends ReactActivity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
||||||
|
* rendering of the component.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getMainComponentName() {
|
||||||
|
return "testHotupdate";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||||
|
return new MainActivityDelegate(this, getMainComponentName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MainActivityDelegate extends ReactActivityDelegate {
|
||||||
|
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
|
||||||
|
super(activity, mainComponentName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ReactRootView createRootView() {
|
||||||
|
ReactRootView reactRootView = new ReactRootView(getContext());
|
||||||
|
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||||
|
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||||
|
return reactRootView;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,96 @@
|
|||||||
|
package com.testhotupdate;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
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.soloader.SoLoader;
|
||||||
|
import com.testhotupdate.newarchitecture.MainApplicationReactNativeHost;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ReactPackage> getPackages() {
|
||||||
|
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||||
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
|
// packages.add(new MyReactNativePackage());
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getJSMainModuleName() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final ReactNativeHost mNewArchitectureNativeHost =
|
||||||
|
new MainApplicationReactNativeHost(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReactNativeHost getReactNativeHost() {
|
||||||
|
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||||
|
return mNewArchitectureNativeHost;
|
||||||
|
} else {
|
||||||
|
return mReactNativeHost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||||
|
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||||
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
|
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||||
|
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param reactInstanceManager
|
||||||
|
*/
|
||||||
|
private static void initializeFlipper(
|
||||||
|
Context context, ReactInstanceManager reactInstanceManager) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
We use reflection here to pick up the class that initializes Flipper,
|
||||||
|
since Flipper library is not available in release mode
|
||||||
|
*/
|
||||||
|
Class<?> aClass = Class.forName("com.testhotupdate.ReactNativeFlipper");
|
||||||
|
aClass
|
||||||
|
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||||
|
.invoke(null, context, reactInstanceManager);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,116 @@
|
|||||||
|
package com.testhotupdate.newarchitecture;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import com.facebook.react.PackageList;
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
|
import com.facebook.react.ReactNativeHost;
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||||
|
import com.facebook.react.bridge.JSIModulePackage;
|
||||||
|
import com.facebook.react.bridge.JSIModuleProvider;
|
||||||
|
import com.facebook.react.bridge.JSIModuleSpec;
|
||||||
|
import com.facebook.react.bridge.JSIModuleType;
|
||||||
|
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.UIManager;
|
||||||
|
import com.facebook.react.fabric.ComponentFactory;
|
||||||
|
import com.facebook.react.fabric.CoreComponentsRegistry;
|
||||||
|
import com.facebook.react.fabric.EmptyReactNativeConfig;
|
||||||
|
import com.facebook.react.fabric.FabricJSIModuleProvider;
|
||||||
|
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||||
|
import com.testhotupdate.BuildConfig;
|
||||||
|
import com.testhotupdate.newarchitecture.components.MainComponentsRegistry;
|
||||||
|
import com.testhotupdate.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
|
||||||
|
* TurboModule delegates and the Fabric Renderer.
|
||||||
|
*
|
||||||
|
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||||
|
* `newArchEnabled` property). Is ignored otherwise.
|
||||||
|
*/
|
||||||
|
public class MainApplicationReactNativeHost extends ReactNativeHost {
|
||||||
|
public MainApplicationReactNativeHost(Application application) {
|
||||||
|
super(application);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getUseDeveloperSupport() {
|
||||||
|
return BuildConfig.DEBUG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ReactPackage> getPackages() {
|
||||||
|
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||||
|
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||||
|
// packages.add(new MyReactNativePackage());
|
||||||
|
// TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
|
||||||
|
// packages.add(new TurboReactPackage() { ... });
|
||||||
|
// If you have custom Fabric Components, their ViewManagers should also be loaded here
|
||||||
|
// inside a ReactPackage.
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getJSMainModuleName() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
protected ReactPackageTurboModuleManagerDelegate.Builder
|
||||||
|
getReactPackageTurboModuleManagerDelegateBuilder() {
|
||||||
|
// Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
|
||||||
|
// for the new architecture and to use TurboModules correctly.
|
||||||
|
return new MainApplicationTurboModuleManagerDelegate.Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JSIModulePackage getJSIModulePackage() {
|
||||||
|
return new JSIModulePackage() {
|
||||||
|
@Override
|
||||||
|
public List<JSIModuleSpec> getJSIModules(
|
||||||
|
final ReactApplicationContext reactApplicationContext,
|
||||||
|
final JavaScriptContextHolder jsContext) {
|
||||||
|
final List<JSIModuleSpec> specs = new ArrayList<>();
|
||||||
|
|
||||||
|
// Here we provide a new JSIModuleSpec that will be responsible of providing the
|
||||||
|
// custom Fabric Components.
|
||||||
|
specs.add(
|
||||||
|
new JSIModuleSpec() {
|
||||||
|
@Override
|
||||||
|
public JSIModuleType getJSIModuleType() {
|
||||||
|
return JSIModuleType.UIManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSIModuleProvider<UIManager> getJSIModuleProvider() {
|
||||||
|
final ComponentFactory componentFactory = new ComponentFactory();
|
||||||
|
CoreComponentsRegistry.register(componentFactory);
|
||||||
|
|
||||||
|
// Here we register a Components Registry.
|
||||||
|
// The one that is generated with the template contains no components
|
||||||
|
// and just provides you the one from React Native core.
|
||||||
|
MainComponentsRegistry.register(componentFactory);
|
||||||
|
|
||||||
|
final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
|
||||||
|
|
||||||
|
ViewManagerRegistry viewManagerRegistry =
|
||||||
|
new ViewManagerRegistry(
|
||||||
|
reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
|
||||||
|
|
||||||
|
return new FabricJSIModuleProvider(
|
||||||
|
reactApplicationContext,
|
||||||
|
componentFactory,
|
||||||
|
new EmptyReactNativeConfig(),
|
||||||
|
viewManagerRegistry);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return specs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
package com.testhotupdate.newarchitecture.components;
|
||||||
|
|
||||||
|
import com.facebook.jni.HybridData;
|
||||||
|
import com.facebook.proguard.annotations.DoNotStrip;
|
||||||
|
import com.facebook.react.fabric.ComponentFactory;
|
||||||
|
import com.facebook.soloader.SoLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible to load the custom Fabric Components. This class has native methods and needs a
|
||||||
|
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||||
|
* folder for you).
|
||||||
|
*
|
||||||
|
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||||
|
* `newArchEnabled` property). Is ignored otherwise.
|
||||||
|
*/
|
||||||
|
@DoNotStrip
|
||||||
|
public class MainComponentsRegistry {
|
||||||
|
static {
|
||||||
|
SoLoader.loadLibrary("fabricjni");
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoNotStrip private final HybridData mHybridData;
|
||||||
|
|
||||||
|
@DoNotStrip
|
||||||
|
private native HybridData initHybrid(ComponentFactory componentFactory);
|
||||||
|
|
||||||
|
@DoNotStrip
|
||||||
|
private MainComponentsRegistry(ComponentFactory componentFactory) {
|
||||||
|
mHybridData = initHybrid(componentFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DoNotStrip
|
||||||
|
public static MainComponentsRegistry register(ComponentFactory componentFactory) {
|
||||||
|
return new MainComponentsRegistry(componentFactory);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,48 @@
|
|||||||
|
package com.testhotupdate.newarchitecture.modules;
|
||||||
|
|
||||||
|
import com.facebook.jni.HybridData;
|
||||||
|
import com.facebook.react.ReactPackage;
|
||||||
|
import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.soloader.SoLoader;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible to load the TurboModules. This class has native methods and needs a
|
||||||
|
* corresponding C++ implementation/header file to work correctly (already placed inside the jni/
|
||||||
|
* folder for you).
|
||||||
|
*
|
||||||
|
* <p>Please note that this class is used ONLY if you opt-in for the New Architecture (see the
|
||||||
|
* `newArchEnabled` property). Is ignored otherwise.
|
||||||
|
*/
|
||||||
|
public class MainApplicationTurboModuleManagerDelegate
|
||||||
|
extends ReactPackageTurboModuleManagerDelegate {
|
||||||
|
|
||||||
|
private static volatile boolean sIsSoLibraryLoaded;
|
||||||
|
|
||||||
|
protected MainApplicationTurboModuleManagerDelegate(
|
||||||
|
ReactApplicationContext reactApplicationContext, List<ReactPackage> packages) {
|
||||||
|
super(reactApplicationContext, packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected native HybridData initHybrid();
|
||||||
|
|
||||||
|
native boolean canCreateTurboModule(String moduleName);
|
||||||
|
|
||||||
|
public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
|
||||||
|
protected MainApplicationTurboModuleManagerDelegate build(
|
||||||
|
ReactApplicationContext context, List<ReactPackage> packages) {
|
||||||
|
return new MainApplicationTurboModuleManagerDelegate(context, packages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected synchronized void maybeLoadOtherSoLibraries() {
|
||||||
|
if (!sIsSoLibraryLoaded) {
|
||||||
|
// If you change the name of your application .so file in the Android.mk file,
|
||||||
|
// make sure you update the name here as well.
|
||||||
|
SoLoader.loadLibrary("testhotupdate_appmodules");
|
||||||
|
sIsSoLibraryLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
Example/testHotUpdate/android/app/src/main/jni/Android.mk
Normal file
49
Example/testHotUpdate/android/app/src/main/jni/Android.mk
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
THIS_DIR := $(call my-dir)
|
||||||
|
|
||||||
|
include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
|
||||||
|
|
||||||
|
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||||
|
# will have to include the following autogenerated makefile.
|
||||||
|
# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_PATH := $(THIS_DIR)
|
||||||
|
|
||||||
|
# You can customize the name of your application .so file here.
|
||||||
|
LOCAL_MODULE := testhotupdate_appmodules
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||||
|
LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
|
||||||
|
|
||||||
|
# If you wish to add a custom TurboModule or Fabric component in your app you
|
||||||
|
# will have to uncomment those lines to include the generated source
|
||||||
|
# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
|
||||||
|
#
|
||||||
|
# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||||
|
# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
|
||||||
|
# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
|
||||||
|
|
||||||
|
# Here you should add any native library you wish to depend on.
|
||||||
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libfabricjni \
|
||||||
|
libfbjni \
|
||||||
|
libfolly_futures \
|
||||||
|
libfolly_json \
|
||||||
|
libglog \
|
||||||
|
libjsi \
|
||||||
|
libreact_codegen_rncore \
|
||||||
|
libreact_debug \
|
||||||
|
libreact_nativemodule_core \
|
||||||
|
libreact_render_componentregistry \
|
||||||
|
libreact_render_core \
|
||||||
|
libreact_render_debug \
|
||||||
|
libreact_render_graphics \
|
||||||
|
librrc_view \
|
||||||
|
libruntimeexecutor \
|
||||||
|
libturbomodulejsijni \
|
||||||
|
libyoga
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
|
||||||
|
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
@@ -0,0 +1,24 @@
|
|||||||
|
#include "MainApplicationModuleProvider.h"
|
||||||
|
|
||||||
|
#include <rncore.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||||
|
const std::string moduleName,
|
||||||
|
const JavaTurboModule::InitParams ¶ms) {
|
||||||
|
// Here you can provide your own module provider for TurboModules coming from
|
||||||
|
// either your application or from external libraries. The approach to follow
|
||||||
|
// is similar to the following (for a library called `samplelibrary`:
|
||||||
|
//
|
||||||
|
// auto module = samplelibrary_ModuleProvider(moduleName, params);
|
||||||
|
// if (module != nullptr) {
|
||||||
|
// return module;
|
||||||
|
// }
|
||||||
|
// return rncore_ModuleProvider(moduleName, params);
|
||||||
|
return rncore_ModuleProvider(moduleName, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <ReactCommon/JavaTurboModule.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
std::shared_ptr<TurboModule> MainApplicationModuleProvider(
|
||||||
|
const std::string moduleName,
|
||||||
|
const JavaTurboModule::InitParams ¶ms);
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@@ -0,0 +1,45 @@
|
|||||||
|
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||||
|
#include "MainApplicationModuleProvider.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
jni::local_ref<MainApplicationTurboModuleManagerDelegate::jhybriddata>
|
||||||
|
MainApplicationTurboModuleManagerDelegate::initHybrid(
|
||||||
|
jni::alias_ref<jhybridobject>) {
|
||||||
|
return makeCxxInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainApplicationTurboModuleManagerDelegate::registerNatives() {
|
||||||
|
registerHybrid({
|
||||||
|
makeNativeMethod(
|
||||||
|
"initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
|
||||||
|
makeNativeMethod(
|
||||||
|
"canCreateTurboModule",
|
||||||
|
MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TurboModule>
|
||||||
|
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||||
|
const std::string name,
|
||||||
|
const std::shared_ptr<CallInvoker> jsInvoker) {
|
||||||
|
// Not implemented yet: provide pure-C++ NativeModules here.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TurboModule>
|
||||||
|
MainApplicationTurboModuleManagerDelegate::getTurboModule(
|
||||||
|
const std::string name,
|
||||||
|
const JavaTurboModule::InitParams ¶ms) {
|
||||||
|
return MainApplicationModuleProvider(name, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
|
||||||
|
std::string name) {
|
||||||
|
return getTurboModule(name, nullptr) != nullptr ||
|
||||||
|
getTurboModule(name, {.moduleName = name}) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@@ -0,0 +1,38 @@
|
|||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <ReactCommon/TurboModuleManagerDelegate.h>
|
||||||
|
#include <fbjni/fbjni.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class MainApplicationTurboModuleManagerDelegate
|
||||||
|
: public jni::HybridClass<
|
||||||
|
MainApplicationTurboModuleManagerDelegate,
|
||||||
|
TurboModuleManagerDelegate> {
|
||||||
|
public:
|
||||||
|
// Adapt it to the package you used for your Java class.
|
||||||
|
static constexpr auto kJavaDescriptor =
|
||||||
|
"Lcom/testhotupdate/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
|
||||||
|
|
||||||
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jhybridobject>);
|
||||||
|
|
||||||
|
static void registerNatives();
|
||||||
|
|
||||||
|
std::shared_ptr<TurboModule> getTurboModule(
|
||||||
|
const std::string name,
|
||||||
|
const std::shared_ptr<CallInvoker> jsInvoker) override;
|
||||||
|
std::shared_ptr<TurboModule> getTurboModule(
|
||||||
|
const std::string name,
|
||||||
|
const JavaTurboModule::InitParams ¶ms) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test-only method. Allows user to verify whether a TurboModule can be
|
||||||
|
* created by instances of this class.
|
||||||
|
*/
|
||||||
|
bool canCreateTurboModule(std::string name);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@@ -0,0 +1,61 @@
|
|||||||
|
#include "MainComponentsRegistry.h"
|
||||||
|
|
||||||
|
#include <CoreComponentsRegistry.h>
|
||||||
|
#include <fbjni/fbjni.h>
|
||||||
|
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||||
|
#include <react/renderer/components/rncore/ComponentDescriptors.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
|
||||||
|
|
||||||
|
std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||||
|
MainComponentsRegistry::sharedProviderRegistry() {
|
||||||
|
auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
|
||||||
|
|
||||||
|
// Custom Fabric Components go here. You can register custom
|
||||||
|
// components coming from your App or from 3rd party libraries here.
|
||||||
|
//
|
||||||
|
// providerRegistry->add(concreteComponentDescriptorProvider<
|
||||||
|
// AocViewerComponentDescriptor>());
|
||||||
|
return providerRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
jni::local_ref<MainComponentsRegistry::jhybriddata>
|
||||||
|
MainComponentsRegistry::initHybrid(
|
||||||
|
jni::alias_ref<jclass>,
|
||||||
|
ComponentFactory *delegate) {
|
||||||
|
auto instance = makeCxxInstance(delegate);
|
||||||
|
|
||||||
|
auto buildRegistryFunction =
|
||||||
|
[](EventDispatcher::Weak const &eventDispatcher,
|
||||||
|
ContextContainer::Shared const &contextContainer)
|
||||||
|
-> ComponentDescriptorRegistry::Shared {
|
||||||
|
auto registry = MainComponentsRegistry::sharedProviderRegistry()
|
||||||
|
->createComponentDescriptorRegistry(
|
||||||
|
{eventDispatcher, contextContainer});
|
||||||
|
|
||||||
|
auto mutableRegistry =
|
||||||
|
std::const_pointer_cast<ComponentDescriptorRegistry>(registry);
|
||||||
|
|
||||||
|
mutableRegistry->setFallbackComponentDescriptor(
|
||||||
|
std::make_shared<UnimplementedNativeViewComponentDescriptor>(
|
||||||
|
ComponentDescriptorParameters{
|
||||||
|
eventDispatcher, contextContainer, nullptr}));
|
||||||
|
|
||||||
|
return registry;
|
||||||
|
};
|
||||||
|
|
||||||
|
delegate->buildRegistryFunction = buildRegistryFunction;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainComponentsRegistry::registerNatives() {
|
||||||
|
registerHybrid({
|
||||||
|
makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ComponentFactory.h>
|
||||||
|
#include <fbjni/fbjni.h>
|
||||||
|
#include <react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h>
|
||||||
|
#include <react/renderer/componentregistry/ComponentDescriptorRegistry.h>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace react {
|
||||||
|
|
||||||
|
class MainComponentsRegistry
|
||||||
|
: public facebook::jni::HybridClass<MainComponentsRegistry> {
|
||||||
|
public:
|
||||||
|
// Adapt it to the package you used for your Java class.
|
||||||
|
constexpr static auto kJavaDescriptor =
|
||||||
|
"Lcom/testhotupdate/newarchitecture/components/MainComponentsRegistry;";
|
||||||
|
|
||||||
|
static void registerNatives();
|
||||||
|
|
||||||
|
MainComponentsRegistry(ComponentFactory *delegate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::shared_ptr<ComponentDescriptorProviderRegistry const>
|
||||||
|
sharedProviderRegistry();
|
||||||
|
|
||||||
|
static jni::local_ref<jhybriddata> initHybrid(
|
||||||
|
jni::alias_ref<jclass>,
|
||||||
|
ComponentFactory *delegate);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace react
|
||||||
|
} // namespace facebook
|
11
Example/testHotUpdate/android/app/src/main/jni/OnLoad.cpp
Normal file
11
Example/testHotUpdate/android/app/src/main/jni/OnLoad.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <fbjni/fbjni.h>
|
||||||
|
#include "MainApplicationTurboModuleManagerDelegate.h"
|
||||||
|
#include "MainComponentsRegistry.h"
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
|
return facebook::jni::initialize(vm, [] {
|
||||||
|
facebook::react::MainApplicationTurboModuleManagerDelegate::
|
||||||
|
registerNatives();
|
||||||
|
facebook::react::MainComponentsRegistry::registerNatives();
|
||||||
|
});
|
||||||
|
}
|
@@ -1,3 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">AwesomeProject</string>
|
<string name="app_name">testHotupdate</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -1,8 +0,0 @@
|
|||||||
<?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>
|
|
@@ -1,23 +1,53 @@
|
|||||||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||||||
|
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
buildToolsVersion = "34.0.0"
|
buildToolsVersion = "31.0.0"
|
||||||
minSdkVersion = 23
|
minSdkVersion = 21
|
||||||
compileSdkVersion = 34
|
compileSdkVersion = 31
|
||||||
targetSdkVersion = 34
|
targetSdkVersion = 31
|
||||||
ndkVersion = "26.1.10909125"
|
|
||||||
kotlinVersion = "1.9.24"
|
|
||||||
|
|
||||||
kotlin_version = '1.9.24'
|
if (System.properties['os.arch'] == "aarch64") {
|
||||||
|
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||||
|
ndkVersion = "24.0.8215888"
|
||||||
|
} else {
|
||||||
|
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||||
|
ndkVersion = "21.4.7075529"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("com.android.tools.build:gradle")
|
classpath("com.android.tools.build:gradle:7.0.4")
|
||||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
|
classpath("de.undercouch:gradle-download-task:4.1.2")
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||||
|
url("$rootDir/../node_modules/react-native/android")
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
// Android JSC is installed from npm
|
||||||
|
url("$rootDir/../node_modules/jsc-android/dist")
|
||||||
|
}
|
||||||
|
mavenCentral {
|
||||||
|
// We don't want to fetch react-native from Maven Central as there are
|
||||||
|
// older versions over there.
|
||||||
|
content {
|
||||||
|
excludeGroup "com.facebook.react"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
google()
|
||||||
|
maven { url 'https://www.jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ android.useAndroidX=true
|
|||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
# Version of flipper SDK to use with React Native
|
# Version of flipper SDK to use with React Native
|
||||||
FLIPPER_VERSION=0.182.0
|
FLIPPER_VERSION=0.125.0
|
||||||
|
|
||||||
# Use this property to specify which architecture you want to build.
|
# Use this property to specify which architecture you want to build.
|
||||||
# You can also override it from the CLI using
|
# You can also override it from the CLI using
|
||||||
@@ -37,8 +37,4 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
|
|||||||
# your application. You should enable this flag either if you want
|
# your application. You should enable this flag either if you want
|
||||||
# to write custom TurboModules/Fabric components OR use libraries that
|
# to write custom TurboModules/Fabric components OR use libraries that
|
||||||
# are providing them.
|
# are providing them.
|
||||||
newArchEnabled=true
|
newArchEnabled=false
|
||||||
|
|
||||||
# Use this property to enable or disable the Hermes JS engine.
|
|
||||||
# If set to false, you will be using JSC instead.
|
|
||||||
hermesEnabled=true
|
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||||
networkTimeout=10000
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
18
Example/testHotUpdate/android/gradlew
vendored
18
Example/testHotUpdate/android/gradlew
vendored
@@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -80,11 +80,11 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# This is normally unused
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
APP_BASE_NAME=${0##*/}
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
@@ -143,16 +143,12 @@ fi
|
|||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
|
||||||
# shellcheck disable=SC3045
|
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
|
||||||
# shellcheck disable=SC3045
|
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -209,12 +205,6 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
|
||||||
if ! command -v xargs >/dev/null 2>&1
|
|
||||||
then
|
|
||||||
die "xargs is not available"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
15
Example/testHotUpdate/android/gradlew.bat
vendored
15
Example/testHotUpdate/android/gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
@rem This is normally unused
|
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -76,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
exit /b 1
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
@@ -1,4 +1,9 @@
|
|||||||
rootProject.name = 'AwesomeProject'
|
rootProject.name = 'testHotupdate'
|
||||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||||
include ':app'
|
include ':app'
|
||||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||||
|
|
||||||
|
if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
|
||||||
|
include(":ReactAndroid")
|
||||||
|
project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"name": "AwesomeProject",
|
"name": "testHotupdate",
|
||||||
"displayName": "AwesomeProject"
|
"displayName": "testHotupdate"
|
||||||
}
|
}
|
@@ -1,8 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: ['module:@react-native/babel-preset'],
|
presets: ['module:metro-react-native-babel-preset'],
|
||||||
env: {
|
|
||||||
production: {
|
|
||||||
plugins: ['react-native-paper/babel'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
Binary file not shown.
@@ -1,116 +0,0 @@
|
|||||||
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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
@@ -1,15 +0,0 @@
|
|||||||
/** @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,
|
|
||||||
};
|
|
@@ -1,11 +0,0 @@
|
|||||||
# 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)
|
|
@@ -1,8 +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>IDEDidComputeMac32BitWarning</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@@ -1,6 +0,0 @@
|
|||||||
#import <RCTAppDelegate.h>
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
|
|
||||||
@interface AppDelegate : RCTAppDelegate
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,27 +0,0 @@
|
|||||||
#import "AppDelegate.h"
|
|
||||||
#import "RCTPushy.h"
|
|
||||||
|
|
||||||
#import <React/RCTBundleURLProvider.h>
|
|
||||||
|
|
||||||
@implementation AppDelegate
|
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
|
||||||
{
|
|
||||||
self.moduleName = @"AwesomeProject";
|
|
||||||
// You can add your custom initial props in the dictionary below.
|
|
||||||
// They will be passed down to the ViewController used by React Native.
|
|
||||||
self.initialProps = @{};
|
|
||||||
|
|
||||||
return [super application:application didFinishLaunchingWithOptions:launchOptions];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
|
||||||
#else
|
|
||||||
return [RCTPushy bundleURL];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
@@ -1,31 +1,10 @@
|
|||||||
# Resolve react_native_pods.rb with node to allow for hoisting
|
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||||
require Pod::Executable.execute_command('node', ['-p',
|
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||||
'require.resolve(
|
|
||||||
"react-native/scripts/react_native_pods.rb",
|
|
||||||
{paths: [process.argv[1]]},
|
|
||||||
)', __dir__]).strip
|
|
||||||
|
|
||||||
platform :ios, min_ios_version_supported
|
platform :ios, '11.0'
|
||||||
prepare_react_native_project!
|
install! 'cocoapods', :deterministic_uuids => false
|
||||||
|
|
||||||
# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
|
target 'testHotupdate' do
|
||||||
# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
|
|
||||||
#
|
|
||||||
# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
|
|
||||||
# ```js
|
|
||||||
# module.exports = {
|
|
||||||
# dependencies: {
|
|
||||||
# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
|
|
||||||
# ```
|
|
||||||
flipper_config = FlipperConfiguration.disabled
|
|
||||||
|
|
||||||
linkage = ENV['USE_FRAMEWORKS']
|
|
||||||
if linkage != nil
|
|
||||||
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
|
|
||||||
use_frameworks! :linkage => linkage.to_sym
|
|
||||||
end
|
|
||||||
|
|
||||||
target 'AwesomeProject' do
|
|
||||||
config = use_native_modules!
|
config = use_native_modules!
|
||||||
|
|
||||||
# Flags change depending on the env values.
|
# Flags change depending on the env values.
|
||||||
@@ -33,25 +12,22 @@ target 'AwesomeProject' do
|
|||||||
|
|
||||||
use_react_native!(
|
use_react_native!(
|
||||||
:path => config[:reactNativePath],
|
:path => config[:reactNativePath],
|
||||||
# Hermes is now enabled by default. Disable by setting this flag to false.
|
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||||
:hermes_enabled => flags[:hermes_enabled],
|
:hermes_enabled => flags[:hermes_enabled],
|
||||||
:fabric_enabled => flags[:fabric_enabled],
|
:fabric_enabled => flags[:fabric_enabled],
|
||||||
# Enables Flipper.
|
|
||||||
#
|
|
||||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
|
||||||
# you should disable the next line.
|
|
||||||
:flipper_configuration => flipper_config,
|
|
||||||
# An absolute path to your application root.
|
# An absolute path to your application root.
|
||||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# 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|
|
post_install do |installer|
|
||||||
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
|
react_native_post_install(installer)
|
||||||
react_native_post_install(
|
|
||||||
installer,
|
|
||||||
config[:reactNativePath],
|
|
||||||
:mac_catalyst_enabled => false
|
|
||||||
)
|
|
||||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,43 +7,78 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */; };
|
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* testHotupdateTests.m */; };
|
||||||
|
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */; };
|
||||||
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; };
|
||||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
|
||||||
|
remoteInfo = testHotupdate;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
13B07F961A680F5B00A75B9A /* AwesomeProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AwesomeProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = testHotupdateTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = AwesomeProject/AppDelegate.h; sourceTree = "<group>"; };
|
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = AwesomeProject/AppDelegate.mm; sourceTree = "<group>"; };
|
00E356F21AD99517003FC87E /* testHotupdateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = testHotupdateTests.m; sourceTree = "<group>"; };
|
||||||
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = AwesomeProject/Images.xcassets; sourceTree = "<group>"; };
|
13B07F961A680F5B00A75B9A /* testHotupdate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testHotupdate.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = AwesomeProject/Info.plist; sourceTree = "<group>"; };
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = testHotupdate/AppDelegate.h; sourceTree = "<group>"; };
|
||||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = AwesomeProject/main.m; sourceTree = "<group>"; };
|
13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = testHotupdate/AppDelegate.mm; sourceTree = "<group>"; };
|
||||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject-AwesomeProjectTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = testHotupdate/Images.xcassets; sourceTree = "<group>"; };
|
||||||
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AwesomeProject.debug.xcconfig"; path = "Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject.debug.xcconfig"; sourceTree = "<group>"; };
|
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = testHotupdate/Info.plist; 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>"; };
|
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testHotupdate/main.m; 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>"; };
|
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>"; };
|
||||||
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AwesomeProject.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotupdate.release.xcconfig"; path = "Target Support Files/Pods-testHotupdate/Pods-testHotupdate.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = AwesomeProject/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotupdate.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
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>"; };
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = testHotupdate/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
00E356EB1AD99517003FC87E /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0C80B921A6F3F58F76C31292 /* libPods-AwesomeProject.a in Frameworks */,
|
0C80B921A6F3F58F76C31292 /* libPods-testHotupdate.a in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
13B07FAE1A68108700A75B9A /* AwesomeProject */ = {
|
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 */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
|
||||||
@@ -53,15 +88,14 @@
|
|||||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */,
|
||||||
13B07FB71A68108700A75B9A /* main.m */,
|
13B07FB71A68108700A75B9A /* main.m */,
|
||||||
);
|
);
|
||||||
name = AwesomeProject;
|
name = testHotupdate;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||||
5DCACB8F33CDC322A6C60F78 /* libPods-AwesomeProject.a */,
|
5DCACB8F33CDC322A6C60F78 /* libPods-testHotupdate.a */,
|
||||||
19F6CBCC0A4E27FBF8BF4A61 /* libPods-AwesomeProject-AwesomeProjectTests.a */,
|
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -76,8 +110,9 @@
|
|||||||
83CBB9F61A601CBA00E9B192 = {
|
83CBB9F61A601CBA00E9B192 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
13B07FAE1A68108700A75B9A /* AwesomeProject */,
|
13B07FAE1A68108700A75B9A /* testHotupdate */,
|
||||||
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
832341AE1AAA6A7D00B99B32 /* Libraries */,
|
||||||
|
00E356EF1AD99517003FC87E /* testHotupdateTests */,
|
||||||
83CBBA001A601CBA00E9B192 /* Products */,
|
83CBBA001A601CBA00E9B192 /* Products */,
|
||||||
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
2D16E6871FA4F8E400B85C8A /* Frameworks */,
|
||||||
BBD78D7AC51CEA395F1C20DB /* Pods */,
|
BBD78D7AC51CEA395F1C20DB /* Pods */,
|
||||||
@@ -90,7 +125,8 @@
|
|||||||
83CBBA001A601CBA00E9B192 /* Products */ = {
|
83CBBA001A601CBA00E9B192 /* Products */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
13B07F961A680F5B00A75B9A /* AwesomeProject.app */,
|
13B07F961A680F5B00A75B9A /* testHotupdate.app */,
|
||||||
|
00E356EE1AD99517003FC87E /* testHotupdateTests.xctest */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -98,10 +134,8 @@
|
|||||||
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */,
|
3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */,
|
||||||
5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */,
|
5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */,
|
||||||
5B7EB9410499542E8C5724F5 /* Pods-AwesomeProject-AwesomeProjectTests.debug.xcconfig */,
|
|
||||||
89C6BE57DB24E9ADA2F236DE /* Pods-AwesomeProject-AwesomeProjectTests.release.xcconfig */,
|
|
||||||
);
|
);
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -109,9 +143,27 @@
|
|||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
13B07F861A680F5B00A75B9A /* AwesomeProject */ = {
|
00E356ED1AD99517003FC87E /* testHotupdateTests */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */;
|
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" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
|
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */,
|
||||||
FD10A7F022414F080027D42C /* Start Packager */,
|
FD10A7F022414F080027D42C /* Start Packager */,
|
||||||
@@ -119,16 +171,16 @@
|
|||||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||||
|
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
|
||||||
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
|
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
|
||||||
2177C9C260D54703D642190E /* [CP] Embed Pods Frameworks */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = AwesomeProject;
|
name = testHotupdate;
|
||||||
productName = AwesomeProject;
|
productName = testHotupdate;
|
||||||
productReference = 13B07F961A680F5B00A75B9A /* AwesomeProject.app */;
|
productReference = 13B07F961A680F5B00A75B9A /* testHotupdate.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
};
|
};
|
||||||
/* End PBXNativeTarget section */
|
/* End PBXNativeTarget section */
|
||||||
@@ -139,12 +191,16 @@
|
|||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1210;
|
LastUpgradeCheck = 1210;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
00E356ED1AD99517003FC87E = {
|
||||||
|
CreatedOnToolsVersion = 6.2;
|
||||||
|
TestTargetID = 13B07F861A680F5B00A75B9A;
|
||||||
|
};
|
||||||
13B07F861A680F5B00A75B9A = {
|
13B07F861A680F5B00A75B9A = {
|
||||||
LastSwiftMigration = 1120;
|
LastSwiftMigration = 1120;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */;
|
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */;
|
||||||
compatibilityVersion = "Xcode 12.0";
|
compatibilityVersion = "Xcode 12.0";
|
||||||
developmentRegion = en;
|
developmentRegion = en;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
@@ -157,12 +213,20 @@
|
|||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
13B07F861A680F5B00A75B9A /* AwesomeProject */,
|
13B07F861A680F5B00A75B9A /* testHotupdate */,
|
||||||
|
00E356ED1AD99517003FC87E /* testHotupdateTests */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
00E356EC1AD99517003FC87E /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
13B07F8E1A680F5B00A75B9A /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -181,31 +245,29 @@
|
|||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"$(SRCROOT)/.xcode.env.local",
|
|
||||||
"$(SRCROOT)/.xcode.env",
|
|
||||||
);
|
);
|
||||||
name = "Bundle React Native code and images";
|
name = "Bundle React Native code and images";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "set -e\n\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";
|
shellScript = "set -e\n\nexport NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||||
};
|
};
|
||||||
2177C9C260D54703D642190E /* [CP] Embed Pods Frameworks */ = {
|
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-frameworks.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-frameworks.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
|
C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
@@ -223,7 +285,7 @@
|
|||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
);
|
);
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"$(DERIVED_FILE_DIR)/Pods-AwesomeProject-checkManifestLockResult.txt",
|
"$(DERIVED_FILE_DIR)/Pods-testHotupdate-checkManifestLockResult.txt",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
@@ -236,15 +298,15 @@
|
|||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputFileListPaths = (
|
inputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-input-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
);
|
);
|
||||||
name = "[CP] Copy Pods Resources";
|
name = "[CP] Copy Pods Resources";
|
||||||
outputFileListPaths = (
|
outputFileListPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources-${CONFIGURATION}-output-files.xcfilelist",
|
"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AwesomeProject/Pods-AwesomeProject-resources.sh\"\n";
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotupdate/Pods-testHotupdate-resources.sh\"\n";
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||||
@@ -269,6 +331,14 @@
|
|||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
00E356EA1AD99517003FC87E /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
00E356F31AD99517003FC87E /* testHotupdateTests.m in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
13B07F871A680F5B00A75B9A /* Sources */ = {
|
13B07F871A680F5B00A75B9A /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -280,16 +350,73 @@
|
|||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 13B07F861A680F5B00A75B9A /* testHotupdate */;
|
||||||
|
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration 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 */ = {
|
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-AwesomeProject.debug.xcconfig */;
|
baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-testHotupdate.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = AwesomeProject/Info.plist;
|
INFOPLIST_FILE = testHotupdate/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@@ -300,7 +427,7 @@
|
|||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||||
PRODUCT_NAME = AwesomeProject;
|
PRODUCT_NAME = testHotupdate;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
@@ -309,12 +436,12 @@
|
|||||||
};
|
};
|
||||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-AwesomeProject.release.xcconfig */;
|
baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-testHotupdate.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
INFOPLIST_FILE = AwesomeProject/Info.plist;
|
INFOPLIST_FILE = testHotupdate/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@@ -325,7 +452,7 @@
|
|||||||
"-lc++",
|
"-lc++",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||||
PRODUCT_NAME = AwesomeProject;
|
PRODUCT_NAME = testHotupdate;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@@ -364,7 +491,7 @@
|
|||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_DYNAMIC_NO_PIC = NO;
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
@@ -372,7 +499,6 @@
|
|||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
"DEBUG=1",
|
"DEBUG=1",
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
|
||||||
);
|
);
|
||||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
@@ -381,7 +507,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
/usr/lib/swift,
|
/usr/lib/swift,
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -393,21 +519,12 @@
|
|||||||
);
|
);
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
OTHER_CFLAGS = "$(inherited)";
|
|
||||||
OTHER_CPLUSPLUSFLAGS = (
|
OTHER_CPLUSPLUSFLAGS = (
|
||||||
"$(OTHER_CFLAGS)",
|
"$(OTHER_CFLAGS)",
|
||||||
"-DFOLLY_NO_CONFIG",
|
"-DFOLLY_NO_CONFIG",
|
||||||
"-DFOLLY_MOBILE=1",
|
"-DFOLLY_MOBILE=1",
|
||||||
"-DFOLLY_USE_LIBCPP=1",
|
"-DFOLLY_USE_LIBCPP=1",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"-Wl",
|
|
||||||
"-ld_classic",
|
|
||||||
" ",
|
|
||||||
"-Wl -ld_classic ",
|
|
||||||
);
|
|
||||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -445,20 +562,16 @@
|
|||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
ENABLE_NS_ASSERTIONS = NO;
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386;
|
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
|
||||||
"$(inherited)",
|
|
||||||
_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION,
|
|
||||||
);
|
|
||||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
/usr/lib/swift,
|
/usr/lib/swift,
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@@ -469,21 +582,12 @@
|
|||||||
"\"$(inherited)\"",
|
"\"$(inherited)\"",
|
||||||
);
|
);
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
OTHER_CFLAGS = "$(inherited)";
|
|
||||||
OTHER_CPLUSPLUSFLAGS = (
|
OTHER_CPLUSPLUSFLAGS = (
|
||||||
"$(OTHER_CFLAGS)",
|
"$(OTHER_CFLAGS)",
|
||||||
"-DFOLLY_NO_CONFIG",
|
"-DFOLLY_NO_CONFIG",
|
||||||
"-DFOLLY_MOBILE=1",
|
"-DFOLLY_MOBILE=1",
|
||||||
"-DFOLLY_USE_LIBCPP=1",
|
"-DFOLLY_USE_LIBCPP=1",
|
||||||
);
|
);
|
||||||
OTHER_LDFLAGS = (
|
|
||||||
"$(inherited)",
|
|
||||||
"-Wl",
|
|
||||||
"-ld_classic",
|
|
||||||
" ",
|
|
||||||
"-Wl -ld_classic ",
|
|
||||||
);
|
|
||||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
@@ -492,7 +596,16 @@
|
|||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "AwesomeProject" */ = {
|
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" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
13B07F941A680F5B00A75B9A /* Debug */,
|
13B07F941A680F5B00A75B9A /* Debug */,
|
||||||
@@ -501,7 +614,7 @@
|
|||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "AwesomeProject" */ = {
|
83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
83CBBA201A601CBA00E9B192 /* Debug */,
|
83CBBA201A601CBA00E9B192 /* Debug */,
|
@@ -15,9 +15,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||||
BuildableName = "AwesomeProject.app"
|
BuildableName = "testHotupdate.app"
|
||||||
BlueprintName = "AwesomeProject"
|
BlueprintName = "testHotupdate"
|
||||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
@@ -33,9 +33,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
|
||||||
BuildableName = "AwesomeProjectTests.xctest"
|
BuildableName = "testHotupdateTests.xctest"
|
||||||
BlueprintName = "AwesomeProjectTests"
|
BlueprintName = "testHotupdateTests"
|
||||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</TestableReference>
|
</TestableReference>
|
||||||
</Testables>
|
</Testables>
|
||||||
@@ -55,9 +55,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||||
BuildableName = "AwesomeProject.app"
|
BuildableName = "testHotupdate.app"
|
||||||
BlueprintName = "AwesomeProject"
|
BlueprintName = "testHotupdate"
|
||||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
@@ -72,9 +72,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||||
BuildableName = "AwesomeProject.app"
|
BuildableName = "testHotupdate.app"
|
||||||
BlueprintName = "AwesomeProject"
|
BlueprintName = "testHotupdate"
|
||||||
ReferencedContainer = "container:AwesomeProject.xcodeproj">
|
ReferencedContainer = "container:testHotupdate.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
@@ -2,7 +2,7 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:AwesomeProject.xcodeproj">
|
location = "group:testHotupdate.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
location = "group:Pods/Pods.xcodeproj">
|
8
Example/testHotUpdate/ios/testHotUpdate/AppDelegate.h
Normal file
8
Example/testHotUpdate/ios/testHotUpdate/AppDelegate.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#import <React/RCTBridgeDelegate.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic, strong) UIWindow *window;
|
||||||
|
|
||||||
|
@end
|
110
Example/testHotUpdate/ios/testHotUpdate/AppDelegate.mm
Normal file
110
Example/testHotUpdate/ios/testHotUpdate/AppDelegate.mm
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#import "AppDelegate.h"
|
||||||
|
|
||||||
|
#import <React/RCTBridge.h>
|
||||||
|
#import <React/RCTBundleURLProvider.h>
|
||||||
|
#import <React/RCTRootView.h>
|
||||||
|
#import "RCTPushy.h"
|
||||||
|
|
||||||
|
#import <React/RCTAppSetupUtils.h>
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
#import <React/CoreModulesPlugins.h>
|
||||||
|
#import <React/RCTCxxBridgeDelegate.h>
|
||||||
|
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||||
|
#import <React/RCTSurfacePresenter.h>
|
||||||
|
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||||
|
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||||
|
|
||||||
|
#import <react/config/ReactNativeConfig.h>
|
||||||
|
|
||||||
|
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||||
|
RCTTurboModuleManager *_turboModuleManager;
|
||||||
|
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||||
|
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||||
|
facebook::react::ContextContainer::Shared _contextContainer;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
|
{
|
||||||
|
RCTAppSetupPrepareApp(application);
|
||||||
|
|
||||||
|
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||||
|
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||||
|
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||||
|
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||||
|
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"testHotupdate", nil);
|
||||||
|
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
rootView.backgroundColor = [UIColor systemBackgroundColor];
|
||||||
|
} else {
|
||||||
|
rootView.backgroundColor = [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||||
|
UIViewController *rootViewController = [UIViewController new];
|
||||||
|
rootViewController.view = rootView;
|
||||||
|
self.window.rootViewController = rootViewController;
|
||||||
|
[self.window makeKeyAndVisible];
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||||
|
#else
|
||||||
|
// 非DEBUG情况下替换为热更新bundle
|
||||||
|
return [RCTPushy bundleURL];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RCT_NEW_ARCH_ENABLED
|
||||||
|
|
||||||
|
#pragma mark - RCTCxxBridgeDelegate
|
||||||
|
|
||||||
|
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||||
|
{
|
||||||
|
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||||
|
delegate:self
|
||||||
|
jsInvoker:bridge.jsCallInvoker];
|
||||||
|
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark RCTTurboModuleManagerDelegate
|
||||||
|
|
||||||
|
- (Class)getModuleClassFromName:(const char *)name
|
||||||
|
{
|
||||||
|
return RCTCoreModulesClassProvider(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||||
|
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||||
|
initParams:
|
||||||
|
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||||
|
{
|
||||||
|
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@end
|
@@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>en</string>
|
<string>en</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>AwesomeProject</string>
|
<string>testHotupdate</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
@@ -26,8 +26,6 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSExceptionDomains</key>
|
<key>NSExceptionDomains</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>localhost</key>
|
<key>localhost</key>
|
||||||
@@ -53,10 +51,5 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>For taking photos</string>
|
|
||||||
|
|
||||||
<key>NSPhotoLibraryUsageDescription</key>
|
|
||||||
<string>For saving photos</string>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
@@ -16,7 +16,7 @@
|
|||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="AwesomeProject" 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="testHotupdate" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
|
||||||
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
|
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
|
||||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
24
Example/testHotUpdate/ios/testHotupdateTests/Info.plist
Normal file
24
Example/testHotUpdate/ios/testHotupdateTests/Info.plist
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?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>
|
@@ -0,0 +1,66 @@
|
|||||||
|
#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,23 @@
|
|||||||
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
|
const path = require('path');
|
||||||
|
|
||||||
/**
|
const extraNodeModules = {
|
||||||
* Metro configuration
|
'react-native': path.resolve(__dirname, 'node_modules/react-native'),
|
||||||
* https://reactnative.dev/docs/metro
|
'react-native-update': path.resolve(__dirname, '../..'),
|
||||||
*
|
'@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
|
||||||
* @type {import('metro-config').MetroConfig}
|
};
|
||||||
*/
|
const watchFolders = [path.resolve(__dirname, '../..')];
|
||||||
const config = {};
|
|
||||||
|
|
||||||
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
|
module.exports = {
|
||||||
|
transformer: {
|
||||||
|
getTransformOptions: async () => ({
|
||||||
|
transform: {
|
||||||
|
experimentalImportSupport: false,
|
||||||
|
inlineRequires: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
resolver: {
|
||||||
|
extraNodeModules,
|
||||||
|
},
|
||||||
|
watchFolders,
|
||||||
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "testHotUpdate",
|
"name": "testhotupdate",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -7,47 +7,25 @@
|
|||||||
"ios": "react-native run-ios",
|
"ios": "react-native run-ios",
|
||||||
"start": "react-native start",
|
"start": "react-native start",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:e2e": "detox test --configuration android.emu.debug",
|
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"postinstall": "patch-package",
|
"apk": "(cd android && ./gradlew aR)"
|
||||||
"apk": "cd android && ./gradlew assembleRelease",
|
|
||||||
"dev:harmony": "react-native bundle-harmony --dev"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"patch-package": "^8.0.0",
|
"react": "17.0.2",
|
||||||
"postinstall-postinstall": "^2.1.0",
|
"react-native": "0.68.5",
|
||||||
"react": "18.3.1",
|
"react-native-update": "link:../.."
|
||||||
"react-native": "0.76.1",
|
|
||||||
"react-native-camera-kit": "^14.0.0-beta15",
|
|
||||||
"react-native-paper": "^5.12.5",
|
|
||||||
"react-native-safe-area-context": "^4.11.1",
|
|
||||||
"react-native-update": "^10.15.1",
|
|
||||||
"react-native-vector-icons": "^10.2.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.12.9",
|
||||||
"@babel/preset-env": "^7.25.3",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@babel/runtime": "^7.25.0",
|
"@react-native-community/eslint-config": "^2.0.0",
|
||||||
"@react-native-community/cli": "15.0.0-alpha.2",
|
"babel-jest": "^26.6.3",
|
||||||
"@react-native-community/cli-platform-android": "15.0.0-alpha.2",
|
"eslint": "^7.32.0",
|
||||||
"@react-native-community/cli-platform-ios": "15.0.0-alpha.2",
|
"jest": "^26.6.3",
|
||||||
"@react-native/babel-preset": "0.76.1",
|
"metro-react-native-babel-preset": "^0.67.0",
|
||||||
"@react-native/eslint-config": "0.76.1",
|
"react-test-renderer": "17.0.2"
|
||||||
"@react-native/metro-config": "0.76.1",
|
|
||||||
"@react-native/typescript-config": "0.76.1",
|
|
||||||
"@types/react": "^18.2.6",
|
|
||||||
"@types/react-test-renderer": "^18.0.0",
|
|
||||||
"babel-jest": "^29.6.3",
|
|
||||||
"eslint": "^8.19.0",
|
|
||||||
"jest": "^29.6.3",
|
|
||||||
"prettier": "2.8.8",
|
|
||||||
"react-test-renderer": "18.3.1",
|
|
||||||
"typescript": "5.0.4"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"jest": {
|
||||||
"node": ">=16"
|
"preset": "react-native"
|
||||||
},
|
}
|
||||||
"trustedDependencies": [
|
|
||||||
"postinstall-postinstall"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
#!/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,140 +1,21 @@
|
|||||||
/* eslint-disable react-native/no-inline-styles */
|
import React from 'react';
|
||||||
/* eslint-disable react/react-in-jsx-scope */
|
|
||||||
import {useCallback, useMemo, useState} from 'react';
|
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
|
Alert,
|
||||||
Modal,
|
Modal,
|
||||||
TextInput,
|
TextInput,
|
||||||
Button,
|
Button,
|
||||||
|
NativeModules,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
SafeAreaView,
|
SafeAreaView,
|
||||||
Text,
|
Text,
|
||||||
View,
|
View,
|
||||||
TouchableOpacity,
|
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
|
||||||
import {PushyModule} from 'react-native-update';
|
const Pushy = NativeModules.Pushy;
|
||||||
const Hash = '9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474';
|
|
||||||
const UUID = '00000000-0000-0000-0000-000000000000';
|
|
||||||
const DownloadUrl =
|
|
||||||
'http://cos.pgyer.com/697913e94d7441f20c686e2b0996a1aa.apk?sign=7a8f11b1df82cba45c8ac30b1acec88c&t=1680404102&response-content-disposition=attachment%3Bfilename%3DtestHotupdate_1.0.apk';
|
|
||||||
|
|
||||||
const CustomDialog = ({title, visible, onConfirm}) => {
|
|
||||||
if (!visible) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={styles.overlay}>
|
|
||||||
<View style={styles.dialog}>
|
|
||||||
<Text style={styles.title}>{title}</Text>
|
|
||||||
<TouchableOpacity
|
|
||||||
testID="done"
|
|
||||||
style={styles.button}
|
|
||||||
onLongPress={onConfirm}>
|
|
||||||
<Text style={styles.buttonText}>确认</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
export default function TestConsole({visible}) {
|
export default function TestConsole({visible}) {
|
||||||
const [text, setText] = useState('');
|
const [text, setText] = React.useState('');
|
||||||
const [running, setRunning] = useState(false);
|
const [running, setRunning] = React.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 (
|
return (
|
||||||
<Modal visible={visible}>
|
<Modal visible={visible}>
|
||||||
<SafeAreaView style={{flex: 1, padding: 10}}>
|
<SafeAreaView style={{flex: 1, padding: 10}}>
|
||||||
@@ -157,97 +38,39 @@ export default function TestConsole({visible}) {
|
|||||||
onChangeText={setText}
|
onChangeText={setText}
|
||||||
/>
|
/>
|
||||||
{running && <ActivityIndicator />}
|
{running && <ActivityIndicator />}
|
||||||
<TouchableOpacity
|
<Button
|
||||||
style={{
|
title="执行"
|
||||||
backgroundColor: 'rgb(0,140,237)',
|
onPress={async () => {
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
paddingTop: 10,
|
|
||||||
paddingBottom: 10,
|
|
||||||
marginBottom: 5,
|
|
||||||
}}
|
|
||||||
testID="submit"
|
|
||||||
onLongPress={async () => {
|
|
||||||
setRunning(true);
|
setRunning(true);
|
||||||
try {
|
try {
|
||||||
const inputs = text.split('\n');
|
const inputs = text.split('\n');
|
||||||
const methodName = inputs[0];
|
const methodName = inputs[0];
|
||||||
let params = [];
|
let params;
|
||||||
if (inputs.length === 1) {
|
if (inputs.length === 1) {
|
||||||
if (options) {
|
await Pushy[methodName]();
|
||||||
await PushyModule[methodName](options);
|
|
||||||
} else {
|
|
||||||
await PushyModule[methodName]();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (inputs.length === 2) {
|
if (inputs.length === 2) {
|
||||||
params = [inputs[1]];
|
params = inputs[1];
|
||||||
} else {
|
} else {
|
||||||
params = [inputs[1], inputs[2]];
|
params = {};
|
||||||
|
for (let i = 1; i < inputs.length; i += 2) {
|
||||||
|
params[inputs[i]] = inputs[i + 1];
|
||||||
|
}
|
||||||
console.log({inputs, params});
|
console.log({inputs, params});
|
||||||
}
|
}
|
||||||
await PushyModule[methodName](...params);
|
await Pushy[methodName](params);
|
||||||
}
|
}
|
||||||
setAlertVisible(true);
|
Alert.alert('done');
|
||||||
setAlertMsg('done');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setAlertVisible(true);
|
Alert.alert(e.message);
|
||||||
setAlertMsg(e.message);
|
|
||||||
}
|
}
|
||||||
setRunning(false);
|
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>
|
</SafeAreaView>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
overlay: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
dialog: {
|
|
||||||
backgroundColor: 'white',
|
|
||||||
borderRadius: 10,
|
|
||||||
padding: 20,
|
|
||||||
width: '80%',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
marginBottom: 20,
|
|
||||||
},
|
|
||||||
button: {
|
|
||||||
backgroundColor: '#2196F3',
|
|
||||||
borderRadius: 5,
|
|
||||||
paddingVertical: 10,
|
|
||||||
paddingHorizontal: 20,
|
|
||||||
},
|
|
||||||
buttonText: {
|
|
||||||
color: 'white',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
205
Example/testHotUpdate/src/index.js
Normal file
205
Example/testHotUpdate/src/index.js
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
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: {},
|
||||||
|
});
|
@@ -1,205 +0,0 @@
|
|||||||
/* 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,
|
|
||||||
debug: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function Root() {
|
|
||||||
return (
|
|
||||||
<PushyProvider client={pushyClient}>
|
|
||||||
<PaperProvider>
|
|
||||||
<App />
|
|
||||||
</PaperProvider>
|
|
||||||
</PushyProvider>
|
|
||||||
);
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"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 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。对国外用户则智能分流至 cloudflare,同样享受高速更新服务。
|
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
|
||||||
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
|
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在几十 KB 级别(其他全量热更新服务所需流量通常在几十 MB 级别)。
|
||||||
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。支持新架构(注:安卓 0.73.0 ~ 0.76.0 的新架构因官方 bug 不支持,0.73 以下或 0.76.1 以上的新架构可用)。
|
3. 始终跟进 RN 最新正式版本,第一时间提供支持。支持 hermes 字节码格式。(暂不支持新架构,会待其相对稳定后跟进)
|
||||||
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
4. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
||||||
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
5. 命令行工具 & 网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||||
6. 支持崩溃回滚,安全可靠。
|
6. 支持崩溃回滚,安全可靠。
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user