@flun/node-mobile-app 4.0.5 → 4.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Android /346/236/204/345/273/272/346/214/207/345/215/227.md" +84 -76
- package/CHANGELOG.md +9 -9
- package/LICENSE +9 -4
- package/README.md +206 -113
- package/bin/cli.js +9 -9
- package/cli-assets/server.js +7 -4
- package/mobileAppConfig.js +32 -32
- package/package.json +5 -5
- package/scripts/copy-files.js +1 -1
- package/src/commands/build.js +9 -4
- package/src/commands/clean.js +3 -2
- package/src/commands/test.js +13 -9
- package/src/config.js +3 -3
- package/src/copy.js +41 -36
- package/src/fingerprint.js +4 -3
- package/src/generate.js +5 -3
- package/src/install.js +38 -27
- package/src/optimize-node-modules.js +10 -5
- package/src/patcher.js +37 -32
- package/src/platform-ios.js +6 -6
- package/src/utils.js +26 -22
- package/template/App.tsx +4 -4
- package/template/Gemfile +1 -1
- package/template/android/app/build.gradle +1 -1
- package/template/android/app/proguard-rules.pro +1 -1
- package/template/android/app/src/main/java/com/myapp/MainActivity.kt +1 -1
- package/template/android/app/src/main/java/com/myapp/MainApplication.kt +1 -1
- package/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +6 -3
- package/template/android/app/src/main/res/raw/keep.xml +1 -1
- package/template/android/app/src/main/res/values/strings.xml +1 -1
- package/template/android/app/src/main/res/values/styles.xml +1 -1
- package/template/android/build.gradle +1 -1
- package/template/android/gradle.properties +1 -1
- package/template/android/gradlew +3 -2
- package/template/android/gradlew.bat +3 -2
- package/template/android/settings.gradle +1 -1
- package/template/app.json +1 -1
- package/template/index.js +2 -2
- package/template/ios/.xcode.env +1 -1
- package/template/ios/MyApp/Images.xcassets/AppIcon.appiconset/Contents.json +1 -1
- package/template/ios/MyApp/Images.xcassets/Contents.json +1 -1
- package/template/ios/MyApp/Info.plist +1 -1
- package/template/ios/MyApp/LaunchScreen.storyboard +30 -12
- package/template/ios/MyApp/PrivacyInfo.xcprivacy +1 -1
- package/template/ios/MyApp.xcodeproj/project.pbxproj +34 -15
- package/template/ios/MyApp.xcodeproj/xcshareddata/xcschemes/MyApp.xcscheme +1 -1
- package/template/ios/Podfile +1 -1
- package/template/package.json +1 -1
- package//350/207/252/345/256/232/344/271/211libnode/346/214/207/345/215/227.md +131 -98
package/src/utils.js
CHANGED
|
@@ -36,7 +36,7 @@ const ensureDir = dir => {
|
|
|
36
36
|
readJson = file => JSON.parse(fs.readFileSync(file, 'utf-8')),
|
|
37
37
|
writeJson = (file, obj) => fs.writeFileSync(file, JSON.stringify(obj, null, 2) + '\n', 'utf-8'),
|
|
38
38
|
/**
|
|
39
|
-
* 内容不同才写文件,避免不必要的 mtime
|
|
39
|
+
* 内容不同才写文件,避免不必要的 mtime 变化触发下游(Gradle/Metro)重编
|
|
40
40
|
* 返回 true 表示写入了,false 表示内容相同跳过
|
|
41
41
|
*/
|
|
42
42
|
writeIfChanged = (file, content) => {
|
|
@@ -62,17 +62,17 @@ const ensureDir = dir => {
|
|
|
62
62
|
fs.copyFileSync(src, dst);
|
|
63
63
|
return true;
|
|
64
64
|
},
|
|
65
|
-
// 把单个参数转成适合 Windows cmd.exe
|
|
65
|
+
// 把单个参数转成适合 Windows cmd.exe 的形式:含空白或 shell 元字符时加双引号;
|
|
66
66
|
quoteShellArg = (s) => {
|
|
67
67
|
const str = String(s);
|
|
68
68
|
if (str === '') return '""';
|
|
69
69
|
return /[\s"&|<>^()]/.test(str) ? '"' + str.replace(/"/g, '""') + '"' : str;
|
|
70
70
|
},
|
|
71
71
|
/**
|
|
72
|
-
*
|
|
73
|
-
* - Windows
|
|
74
|
-
* 避免 spawnSync(bin, args, { shell: true }) 触发 DEP0190
|
|
75
|
-
* -
|
|
72
|
+
* 统一的子进程启动:
|
|
73
|
+
* - Windows:.cmd / .bat 需经 shell;把命令与参数拼成单字符串,
|
|
74
|
+
* 避免 spawnSync(bin, args, { shell: true }) 触发 DEP0190;
|
|
75
|
+
* - 其它平台:不用 shell,参数交由 Node 转义;
|
|
76
76
|
*/
|
|
77
77
|
spawnCmd = (bin, args, baseOpts = {}) => {
|
|
78
78
|
if (process.platform === 'win32') {
|
|
@@ -82,7 +82,7 @@ const ensureDir = dir => {
|
|
|
82
82
|
return spawnSync(bin, args, { ...baseOpts, shell: false });
|
|
83
83
|
},
|
|
84
84
|
/**
|
|
85
|
-
* 异步 spawn
|
|
85
|
+
* 异步 spawn:参数同 spawnCmd,返回 ChildProcess
|
|
86
86
|
* @param {string} bin 命令
|
|
87
87
|
* @param {string[]} args 参数
|
|
88
88
|
* @param {object} [baseOpts] spawn 选项
|
|
@@ -96,7 +96,7 @@ const ensureDir = dir => {
|
|
|
96
96
|
return spawn(bin, args, { ...baseOpts, shell: false });
|
|
97
97
|
},
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
99
|
+
* 执行命令:默认实时输出(inherit);quiet=true 时捕获输出,成功静默、失败才打印
|
|
100
100
|
*/
|
|
101
101
|
run = (bin, args, opts = {}) => {
|
|
102
102
|
const { quiet, ...restOpts } = opts;
|
|
@@ -124,7 +124,7 @@ const ensureDir = dir => {
|
|
|
124
124
|
return r;
|
|
125
125
|
},
|
|
126
126
|
/**
|
|
127
|
-
*
|
|
127
|
+
* 执行命令:实时输出,仅首行加缩进前缀,其余行原样
|
|
128
128
|
* @param {string} bin 命令
|
|
129
129
|
* @param {string[]} args 参数
|
|
130
130
|
* @param {object} [opts] spawn 选项 + prefix
|
|
@@ -148,7 +148,7 @@ const ensureDir = dir => {
|
|
|
148
148
|
child.on('close', code => code === 0 ? resolve() : reject(new Error(`${bin} ${args.join(' ')} 退出码 ${code}`)));
|
|
149
149
|
}),
|
|
150
150
|
/**
|
|
151
|
-
* 定位 adb
|
|
151
|
+
* 定位 adb(配置 > 环境变量 > 默认路径 > PATH)
|
|
152
152
|
*/
|
|
153
153
|
findAdb = config => {
|
|
154
154
|
// 1. 用户显式配置的路径优先
|
|
@@ -165,7 +165,7 @@ const ensureDir = dir => {
|
|
|
165
165
|
if (fs.existsSync(p)) return p;
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
|
-
// 3.
|
|
168
|
+
// 3. 默认路径猜测(Windows / macOS / Linux)
|
|
169
169
|
const home = process.env.USERPROFILE || process.env.HOME || '', localAppData = process.env.LOCALAPPDATA || '',
|
|
170
170
|
candidates = [
|
|
171
171
|
path.join(localAppData, 'Android', 'Sdk', 'platform-tools', 'adb.exe'),
|
|
@@ -176,10 +176,10 @@ const ensureDir = dir => {
|
|
|
176
176
|
return 'adb';
|
|
177
177
|
},
|
|
178
178
|
/**
|
|
179
|
-
* 定位 hermesc
|
|
179
|
+
* 定位 hermesc(Hermes 编译器,用于把 JS bundle 编成字节码)
|
|
180
180
|
*/
|
|
181
181
|
/**
|
|
182
|
-
*
|
|
182
|
+
* 读取安装状态标志(记录上次由本工具安装的包与变体)
|
|
183
183
|
* @param {string} buildDir 构建目录
|
|
184
184
|
* @returns {{appId:string, variant:'debug'|'release'}|null} 状态或 null
|
|
185
185
|
*/
|
|
@@ -189,19 +189,22 @@ const ensureDir = dir => {
|
|
|
189
189
|
try { return JSON.parse(fs.readFileSync(f, 'utf-8')); } catch { return null; }
|
|
190
190
|
},
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
192
|
+
* 写入安装状态标志(安装成功后调用)
|
|
193
193
|
* @param {string} buildDir 构建目录
|
|
194
194
|
* @param {object} state 状态
|
|
195
195
|
* @returns {void}
|
|
196
196
|
*/
|
|
197
197
|
writeInstallState = (buildDir, state) => {
|
|
198
|
-
try {
|
|
198
|
+
try {
|
|
199
|
+
ensureDir(buildDir),
|
|
200
|
+
fs.writeFileSync(path.join(buildDir, '.install-state.json'), JSON.stringify(state, null, 2));
|
|
201
|
+
} catch { }
|
|
199
202
|
},
|
|
200
203
|
/**
|
|
201
204
|
* 查询设备上已安装包的 DEBUGGABLE 标志
|
|
202
205
|
* @param {string} adb adb 路径
|
|
203
206
|
* @param {string} appId 包名
|
|
204
|
-
* @returns {'debug'|'release'|null} 变体或 null
|
|
207
|
+
* @returns {'debug'|'release'|null} 变体或 null(未安装)
|
|
205
208
|
*/
|
|
206
209
|
getInstalledVariant = (adb, appId, serial) => {
|
|
207
210
|
const pre = serial ? ['-s', serial] : [],
|
|
@@ -210,12 +213,12 @@ const ensureDir = dir => {
|
|
|
210
213
|
return /\bDEBUGGABLE\b/.test(r.stdout) ? 'debug' : 'release';
|
|
211
214
|
},
|
|
212
215
|
/**
|
|
213
|
-
*
|
|
216
|
+
* 确保待装包可覆盖安装:标志不一致或变体不符时卸载已装包
|
|
214
217
|
* @param {string} adb adb 路径
|
|
215
218
|
* @param {string} appId 包名
|
|
216
219
|
* @param {'debug'|'release'} want 待装变体
|
|
217
220
|
* @param {string} buildDir 构建目录
|
|
218
|
-
* @param {string} [serial]
|
|
221
|
+
* @param {string} [serial] 设备序列号(多设备时指定)
|
|
219
222
|
* @returns {void}
|
|
220
223
|
*/
|
|
221
224
|
ensureInstallable = (adb, appId, want, buildDir, serial) => {
|
|
@@ -235,7 +238,7 @@ const ensureDir = dir => {
|
|
|
235
238
|
return fs.existsSync(p) ? p : null;
|
|
236
239
|
},
|
|
237
240
|
/**
|
|
238
|
-
*
|
|
241
|
+
* 文件名安全化:去除文件系统非法字符(/ \ : * ? " < > |)
|
|
239
242
|
* 空结果回退 'app'
|
|
240
243
|
*/
|
|
241
244
|
sanitizeFileName = s => {
|
|
@@ -243,7 +246,7 @@ const ensureDir = dir => {
|
|
|
243
246
|
return cleaned || 'app';
|
|
244
247
|
},
|
|
245
248
|
/**
|
|
246
|
-
* 生成 ESLint flat config
|
|
249
|
+
* 生成 ESLint flat config 源码(替代 @react-native/eslint-config/flat)
|
|
247
250
|
*/
|
|
248
251
|
buildEslintConfigSource = () => `import js from '@eslint/js';
|
|
249
252
|
import tsParser from '@typescript-eslint/parser';
|
|
@@ -272,6 +275,7 @@ import chalk from 'chalk';
|
|
|
272
275
|
rules: tsPlugin.configs.recommended.rules }, prettier];`;
|
|
273
276
|
|
|
274
277
|
export {
|
|
275
|
-
ensureDir, removeDir, isExcluded, copyDir, readJson, writeJson, writeIfChanged, copyFileIfChanged, spawnCmdAsync, run,
|
|
276
|
-
runSilent, findAdb, readInstallState, writeInstallState, getInstalledVariant, ensureInstallable,
|
|
278
|
+
ensureDir, removeDir, isExcluded, copyDir, readJson, writeJson, writeIfChanged, copyFileIfChanged, spawnCmdAsync, run,
|
|
279
|
+
runQuiet, runStream, runSilent, findAdb, readInstallState, writeInstallState, getInstalledVariant, ensureInstallable,
|
|
280
|
+
findHermesc, sanitizeFileName, buildEslintConfigSource
|
|
277
281
|
};
|
package/template/App.tsx
CHANGED
|
@@ -4,9 +4,9 @@ import { WebView } from 'react-native-webview';
|
|
|
4
4
|
import * as NodeMobile from '@flun/nodejs-mobile-react-native';
|
|
5
5
|
import runtime from './mobileApp.runtime';
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// 背景色解析:支持以下三种配置
|
|
8
8
|
// '#ffffff' / 'white' 等字符串 → 固定色
|
|
9
|
-
// 'system' →
|
|
9
|
+
// 'system' → 跟随系统(内部用默认浅/深色)
|
|
10
10
|
// { light: '#fff', dark: '#000' } → 按系统主题切换
|
|
11
11
|
const resolveBgColor = (bg: string | { light: string; dark: string }, theme: string | null | undefined): string => {
|
|
12
12
|
if (typeof bg === 'object' && bg !== null)
|
|
@@ -58,7 +58,7 @@ const resolveBgColor = (bg: string | { light: string; dark: string }, theme: str
|
|
|
58
58
|
return () => NodeMobile.channel.removeListener('message', listener);
|
|
59
59
|
}, []);
|
|
60
60
|
|
|
61
|
-
//
|
|
61
|
+
// 失败:显示错误页(用户看提示,开发者点开看详情)
|
|
62
62
|
if (failedReason) {
|
|
63
63
|
return (
|
|
64
64
|
<View style={styles.errorContainer}>
|
|
@@ -77,7 +77,7 @@ const resolveBgColor = (bg: string | { light: string; dark: string }, theme: str
|
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
//
|
|
80
|
+
// 尚未就绪:loading
|
|
81
81
|
if (!url) {
|
|
82
82
|
if (!runtime.showLoading) return <View style={styles.fill} />;
|
|
83
83
|
return (
|
package/template/Gemfile
CHANGED
|
@@ -24,9 +24,12 @@
|
|
|
24
24
|
<!--
|
|
25
25
|
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
|
|
26
26
|
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
|
|
27
|
-
NullPointerException:tempt to invoke virtual method
|
|
27
|
+
NullPointerException:tempt to invoke virtual method
|
|
28
|
+
'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(
|
|
29
|
+
android.content.res.Resources)'
|
|
28
30
|
|
|
29
|
-
<item android:state_pressed="false" android:state_focused="false"
|
|
31
|
+
<item android:state_pressed="false" android:state_focused="false"
|
|
32
|
+
android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
|
|
30
33
|
|
|
31
34
|
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
|
|
32
35
|
-->
|
|
@@ -34,4 +37,4 @@
|
|
|
34
37
|
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
|
|
35
38
|
</selector>
|
|
36
39
|
|
|
37
|
-
</inset>
|
|
40
|
+
</inset>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_close,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_alerttriangle,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_loader,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronleft,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronright" />
|
|
1
|
+
<resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_close,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_alerttriangle,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_loader,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronleft,@drawable/node_modules_reactnative_libraries_logbox_ui_logboximages_chevronright" />
|
package/template/android/gradlew
CHANGED
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
# Darwin, MinGW, and NonStop.
|
|
58
58
|
#
|
|
59
59
|
# (3) This script is generated from the Groovy template
|
|
60
|
-
# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/
|
|
60
|
+
# https://github.com/gradle/gradle/blob/2d6327017519d23b96af35865dc997fcb544fb40/
|
|
61
|
+
# platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
|
61
62
|
# within the Gradle project.
|
|
62
63
|
#
|
|
63
64
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
|
@@ -245,4 +246,4 @@ eval "set -- $(
|
|
|
245
246
|
tr '\n' ' '
|
|
246
247
|
)" '"$@"'
|
|
247
248
|
|
|
248
|
-
exec "$JAVACMD" "$@"
|
|
249
|
+
exec "$JAVACMD" "$@"
|
|
@@ -78,7 +78,8 @@ goto fail
|
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
@rem Execute Gradle
|
|
81
|
-
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS%
|
|
81
|
+
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% ^
|
|
82
|
+
"-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
|
82
83
|
|
|
83
84
|
:end
|
|
84
85
|
@rem End local scope for the variables with windows NT shell
|
|
@@ -95,4 +96,4 @@ exit /b %EXIT_CODE%
|
|
|
95
96
|
:mainEnd
|
|
96
97
|
if "%OS%"=="Windows_NT" endlocal
|
|
97
98
|
|
|
98
|
-
:omega
|
|
99
|
+
:omega
|
|
@@ -12,4 +12,4 @@ plugins { id("com.facebook.react.settings") }
|
|
|
12
12
|
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
|
|
13
13
|
rootProject.name = 'MyApp'
|
|
14
14
|
include ':app'
|
|
15
|
-
includeBuild('../../node_modules/@react-native/gradle-plugin')
|
|
15
|
+
includeBuild('../../node_modules/@react-native/gradle-plugin')
|
package/template/app.json
CHANGED
package/template/index.js
CHANGED
package/template/ios/.xcode.env
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702"
|
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15702"
|
|
3
|
+
targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES"
|
|
4
|
+
useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
|
|
3
5
|
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
|
4
6
|
<dependencies>
|
|
5
7
|
<deployment identifier="iOS"/>
|
|
@@ -16,32 +18,48 @@
|
|
|
16
18
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
17
19
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
18
20
|
<subviews>
|
|
19
|
-
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
|
|
21
|
+
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
|
|
22
|
+
horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MyApp"
|
|
23
|
+
textAlignment="center" lineBreakMode="middleTruncation"
|
|
24
|
+
baselineAdjustment="alignBaselines" minimumFontSize="18"
|
|
25
|
+
translatesAutoresizingMaskIntoConstraints="NO" id="GJd-Yh-RWb">
|
|
20
26
|
<rect key="frame" x="0.0" y="202" width="375" height="43"/>
|
|
21
27
|
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
|
22
28
|
<nil key="highlightedColor"/>
|
|
23
29
|
</label>
|
|
24
|
-
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
|
|
30
|
+
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left"
|
|
31
|
+
horizontalHuggingPriority="251" verticalHuggingPriority="251"
|
|
32
|
+
text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation"
|
|
33
|
+
baselineAdjustment="alignBaselines" minimumFontSize="9"
|
|
34
|
+
translatesAutoresizingMaskIntoConstraints="NO" id="MN2-I3-ftu">
|
|
25
35
|
<rect key="frame" x="0.0" y="626" width="375" height="21"/>
|
|
26
36
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
|
27
37
|
<nil key="highlightedColor"/>
|
|
28
38
|
</label>
|
|
29
39
|
</subviews>
|
|
30
|
-
<color key="backgroundColor" systemColor="systemBackgroundColor"
|
|
40
|
+
<color key="backgroundColor" systemColor="systemBackgroundColor"
|
|
41
|
+
cocoaTouchSystemColor="whiteColor"/>
|
|
31
42
|
<constraints>
|
|
32
|
-
<constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu"
|
|
33
|
-
|
|
34
|
-
<constraint firstItem="
|
|
35
|
-
|
|
36
|
-
<constraint firstItem="
|
|
37
|
-
|
|
43
|
+
<constraint firstItem="Bcu-3y-fUS" firstAttribute="bottom" secondItem="MN2-I3-ftu"
|
|
44
|
+
secondAttribute="bottom" constant="20" id="OZV-Vh-mqD"/>
|
|
45
|
+
<constraint firstItem="Bcu-3y-fUS" firstAttribute="centerX" secondItem="GJd-Yh-RWb"
|
|
46
|
+
secondAttribute="centerX" id="Q3B-4B-g5h"/>
|
|
47
|
+
<constraint firstItem="MN2-I3-ftu" firstAttribute="centerX" secondItem="Bcu-3y-fUS"
|
|
48
|
+
secondAttribute="centerX" id="akx-eg-2ui"/>
|
|
49
|
+
<constraint firstItem="MN2-I3-ftu" firstAttribute="leading" secondItem="Bcu-3y-fUS"
|
|
50
|
+
secondAttribute="leading" id="i1E-0Y-4RG"/>
|
|
51
|
+
<constraint firstItem="GJd-Yh-RWb" firstAttribute="centerY" secondItem="Ze5-6b-2t3"
|
|
52
|
+
secondAttribute="bottom" multiplier="1/3" constant="1" id="moa-c2-u7t"/>
|
|
53
|
+
<constraint firstItem="GJd-Yh-RWb" firstAttribute="leading" secondItem="Bcu-3y-fUS"
|
|
54
|
+
secondAttribute="leading" symbolic="YES" id="x7j-FC-K8j"/>
|
|
38
55
|
</constraints>
|
|
39
56
|
<viewLayoutGuide key="safeArea" id="Bcu-3y-fUS"/>
|
|
40
57
|
</view>
|
|
41
58
|
</viewController>
|
|
42
|
-
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder"
|
|
59
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder"
|
|
60
|
+
sceneMemberID="firstResponder"/>
|
|
43
61
|
</objects>
|
|
44
62
|
<point key="canvasLocation" x="52.173913043478265" y="375"/>
|
|
45
63
|
</scene>
|
|
46
64
|
</scenes>
|
|
47
|
-
</document>
|
|
65
|
+
</document>
|
|
@@ -7,23 +7,42 @@
|
|
|
7
7
|
objects = {
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
|
-
0C80B921A6F3F58F76C31292 /* libPods-MyApp.a in Frameworks */ = {isa = PBXBuildFile;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
0C80B921A6F3F58F76C31292 /* libPods-MyApp.a in Frameworks */ = {isa = PBXBuildFile;
|
|
11
|
+
fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */; };
|
|
12
|
+
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile;
|
|
13
|
+
fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
|
14
|
+
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile;
|
|
15
|
+
fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
|
|
16
|
+
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile;
|
|
17
|
+
fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
|
14
18
|
/* End PBXBuildFile section */
|
|
15
19
|
|
|
16
20
|
/* Begin PBXFileReference section */
|
|
17
|
-
13B07F961A680F5B00A75B9A /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
13B07F961A680F5B00A75B9A /* MyApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application;
|
|
22
|
+
includeInIndex = 0; path = MyApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
23
|
+
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog;
|
|
24
|
+
name = Images.xcassets; path = MyApp/Images.xcassets; sourceTree = "<group>"; };
|
|
25
|
+
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4;
|
|
26
|
+
lastKnownFileType = text.plist.xml; name = Info.plist; path = MyApp/Info.plist; sourceTree = "<group>"; };
|
|
27
|
+
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4;
|
|
28
|
+
lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = MyApp/PrivacyInfo.xcprivacy;
|
|
29
|
+
sourceTree = "<group>"; };
|
|
30
|
+
3B4392A12AC88292D35C810B /* Pods-MyApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1;
|
|
31
|
+
lastKnownFileType = text.xcconfig; name = "Pods-MyApp.debug.xcconfig";
|
|
32
|
+
path = "Target Support Files/Pods-MyApp/Pods-MyApp.debug.xcconfig"; sourceTree = "<group>"; };
|
|
33
|
+
5709B34CF0A7D63546082F79 /* Pods-MyApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1;
|
|
34
|
+
lastKnownFileType = text.xcconfig; name = "Pods-MyApp.release.xcconfig";
|
|
35
|
+
path = "Target Support Files/Pods-MyApp/Pods-MyApp.release.xcconfig"; sourceTree = "<group>"; };
|
|
36
|
+
5DCACB8F33CDC322A6C60F78 /* libPods-MyApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar;
|
|
37
|
+
includeInIndex = 0; path = "libPods-MyApp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
38
|
+
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift;
|
|
39
|
+
name = AppDelegate.swift; path = MyApp/AppDelegate.swift; sourceTree = "<group>"; };
|
|
40
|
+
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4;
|
|
41
|
+
lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = MyApp/LaunchScreen.storyboard;
|
|
42
|
+
sourceTree = "<group>"; };
|
|
43
|
+
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference;
|
|
44
|
+
lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework;
|
|
45
|
+
path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
|
27
46
|
/* End PBXFileReference section */
|
|
28
47
|
|
|
29
48
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -472,4 +491,4 @@
|
|
|
472
491
|
/* End XCConfigurationList section */
|
|
473
492
|
};
|
|
474
493
|
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
|
|
475
|
-
}
|
|
494
|
+
}
|
package/template/ios/Podfile
CHANGED
package/template/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"_comment": "
|
|
6
|
+
"_comment": "版本号由 @flun/node-mobile-app 在 copyTemplate 阶段从主包同步;此处 \"*\" 仅为占位;",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"react": "*",
|
|
9
9
|
"react-native": "*",
|