Author SHA1 Message Date
linfeng 15700f918b 重构记分数据模型,替换弓型和靶纸类型为 ID 及名称,更新相关页面以支持新配置。 2026-08-09 19:09:21 +08:00
linfeng e3d6fac6e1 更换靶面美术资源 2026-08-09 04:26:19 +08:00
linfengandCursor 6901b08a94 设置 App 图标与启动页,并修复记分详情回显与环值分布溢出。
同步恢复试用次数校验,免费额度调整为 2 次,便于验证 IAP 流程。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-09 03:50:03 +08:00
linfeng 4385c6941e 修复白屏BUG、UI 边界溢出 BUG 2026-08-09 01:35:48 +08:00
linfeng 4a357024bc 修复保存记分无法返回上一页 2026-08-08 13:29:05 +08:00
linfeng 636d936474 增加数据结构源 2026-08-08 11:20:14 +08:00
linfeng 9f70ac99b4 完善 IOS 配置 2026-08-08 11:06:26 +08:00
linfeng 604af909b0 init 2026-08-08 10:57:54 +08:00
234 changed files with 14809 additions and 12722 deletions
+7
View File
@@ -0,0 +1,7 @@
---
name: grill-me
description: A relentless interview to sharpen a plan or design.
disable-model-invocation: true
---
Run a `/grilling` session.
@@ -0,0 +1,5 @@
interface:
display_name: "Grill Me"
short_description: "Sharpen a plan through interview"
policy:
allow_implicit_invocation: false
+7
View File
@@ -0,0 +1,7 @@
---
name: grill-with-docs
description: A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.
disable-model-invocation: true
---
Run a `/grilling` session, using the `/domain-modeling` skill.
@@ -0,0 +1,5 @@
interface:
display_name: "Grill with Docs"
short_description: "Grill a design and write its docs"
policy:
allow_implicit_invocation: false
+22
View File
@@ -0,0 +1,22 @@
---
name: grilling
description: Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
---
Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled — the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
Each question should be formatted like so:
```
❓ **Q1** - **<question title>**: <question body, might be multiple paragraphs, including multiple choices>
➡️ <your recommended answer>
```
Each round the user answers reshapes the tree — settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it — don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report — ask the rest of the frontier now. The _decisions_ are the user's — put each to them and wait.
The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.
@@ -0,0 +1,3 @@
interface:
display_name: "Grilling"
short_description: "Stress-test thinking a round of questions at a time"
+44 -3
View File
@@ -1,4 +1,45 @@
unpackage # Miscellaneous
dist *.class
node_modules *.log
*.pyc
*.swp
.DS_Store .DS_Store
.atom/
.build/
.buildlog/
.history
.svn/
.swiftpm/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins-dependencies
.pub-cache/
.pub/
/build/
/coverage/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
+33
View File
@@ -0,0 +1,33 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "924134a44c189315be2148659913dda1671cbe99"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 924134a44c189315be2148659913dda1671cbe99
base_revision: 924134a44c189315be2148659913dda1671cbe99
- platform: android
create_revision: 924134a44c189315be2148659913dda1671cbe99
base_revision: 924134a44c189315be2148659913dda1671cbe99
- platform: ios
create_revision: 924134a44c189315be2148659913dda1671cbe99
base_revision: 924134a44c189315be2148659913dda1671cbe99
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
@@ -0,0 +1,164 @@
# 修复 UI 边界溢出与记分页白屏问题
## 问题概述
1. **记分页白屏(严重)**:进入记分页后白屏,由 `OutlinedButton` 收到无限宽度约束导致整个 `Scaffold` 布局失败引起
2. **首页环值分布卡片溢出**`score_distribution_card.dart:86` Column 底部溢出 13px
3. **创建页数字选择器溢出**`point_book_create_page.dart:187` Row 右侧溢出 14px
## 根因分析
### 白屏根因:`SizedBox(height: size)` 与 `Expanded` 的约束冲突
`point_book_edit_page.dart` 第 82-141 行的结构:
```
Expanded( // 给子节点 tight height = 剩余高度 (如 200px)
child: Padding(
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth; // 如 350px (屏幕宽度)
return SizedBox(
width: size, // 350
height: size, // 350 ← 与 Expanded 的 200px 冲突!
child: GestureDetector(...),
);
},
),
),
)
```
**约束冲突原理**
- `Expanded` 给子节点 `BoxConstraints(minHeight: 200, maxHeight: 200)` (tight)
- `SizedBox(height: 350)` 给子节点 `BoxConstraints(minHeight: 350, maxHeight: 350)` (tight)
- 交集:`minHeight: max(200,350)=350, maxHeight: min(200,350)=200`**350 > 200,不可能约束!**
- 布局失败级联到整个 Column → Scaffold → 白屏
### 环值分布卡片溢出根因
`score_distribution_card.dart` 第 84 行:`maxH = constraints.maxHeight - 28`
柱状图 `_Bar` 的 Column 内容总高度 = count文字(~15) + spacing(4) + bar(最大 maxH=112) + spacing(4) + label文字(~16) = 151px,但可用高度仅 140px,溢出 11-13px。
### 创建页溢出根因
`point_book_create_page.dart` 第 187 行:`_NumberPicker` 内的 Row 包含两个默认尺寸 `IconButton`(各 48px)+ 文字 + 标签文字,在半屏宽度内放不下。
## 修改方案
### 1. `point_book_edit_page.dart` — 修复白屏(关键)
**文件**`lib/features/scoring/presentation/point_book_edit_page.dart`
**行号**82-141
`Expanded > Padding > LayoutBuilder > SizedBox` 结构改为 `Expanded > Padding > Center > AspectRatio > LayoutBuilder`
```dart
// 修改前(第 85-90 行):
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth;
return SizedBox(
width: size,
height: size,
child: GestureDetector(
// 修改后:
child: Center(
child: AspectRatio(
aspectRatio: 1.0,
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth;
return GestureDetector(
```
关键变更:
-`Padding``LayoutBuilder` 之间插入 `Center(child: AspectRatio(aspectRatio: 1.0))`
- 删除 `SizedBox(width: size, height: size)` 包装层
- `Center` 松解 `Expanded` 的 tight height 约束 → `AspectRatio` 计算 min(宽,高) 的正方形 → `LayoutBuilder` 获取的 `constraints.maxWidth == constraints.maxHeight` → 无冲突
- `Image.asset``CustomPaint``size: Size(size, size)` 保持不变
- 对应关闭括号:需要增加 `),` (AspectRatio) 和 `),` (Center) 的闭合
### 2. `point_book_create_page.dart` — 修复 Row 溢出 14px
**文件**`lib/features/scoring/presentation/point_book_create_page.dart`
**行号**187-216`_NumberPicker` 的 build 方法)
修改 `_NumberPicker` 中的两个 `IconButton`,使其更紧凑:
```dart
// 修改前(第 193-198 行):
IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: () {
// 修改后:
IconButton(
icon: const Icon(Icons.remove_circle_outline),
iconSize: 20,
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () {
```
同样修改 `add` 按钮(第 207-211 行)。
并将标签文字包裹 `Flexible`(第 190 行):
```dart
// 修改前:
Text(label, style: const TextStyle(fontSize: 13)),
// 修改后:
Flexible(
child: Text(label, style: const TextStyle(fontSize: 13)),
),
```
### 3. `score_distribution_card.dart` — 修复 Column 溢出 13px
**文件**`lib/features/home/presentation/widgets/score_distribution_card.dart`
**行号**:第 84 行
```dart
// 修改前:
final maxH = constraints.maxHeight - 28; // reserve space for label
// 修改后:
final maxH = constraints.maxHeight - 40; // reserve space for count + label
```
将预留空间从 28px 增加到 40px,确保柱子最大高度不会导致 Column 溢出。
### 4. `heatmap_card.dart` — 修复 CustomPaint 尺寸为零(附带修复)
**文件**`lib/features/home/presentation/widgets/heatmap_card.dart`
**行号**:第 29 行
当前 `Stack``CustomPaint` 没有指定 `size`,在 `Stack` 中默认尺寸为 0x0,导致命中点不可见。
```dart
// 修改前(第 29 行):
child: Stack(
alignment: Alignment.center,
children: [
// 修改后:
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
children: [
```
添加 `fit: StackFit.expand` 使所有非定位子节点(`Image.asset``CustomPaint`)填满 Stack。
## 验证步骤
1. 运行 `flutter analyze` 确认无错误
2. 启动 APP,进入首页 → 确认无黄色溢出条纹
3. 点击"开始记分" → 进入创建页 → 确认数字选择器无溢出
4. 完成创建 → 进入记分页 → 确认 **不白屏**,靶面正常显示
5. 点击靶面 → 确认命中点准确渲染
6. 返回首页 → 查看热力图 → 确认命中点可见
+3
View File
@@ -0,0 +1,3 @@
{
"java.compile.nullAnalysis.mode": "disabled"
}
+17
View File
@@ -0,0 +1,17 @@
# arcx
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
+28
View File
@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
+14
View File
@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/
# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks
+45
View File
@@ -0,0 +1,45 @@
plugins {
id("com.android.application")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
android {
namespace = "com.shelingxingqiu.arcx"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.shelingxingqiu.arcx"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
}
}
flutter {
source = "../.."
}
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
+45
View File
@@ -0,0 +1,45 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="arcx"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
@@ -0,0 +1,5 @@
package com.shelingxingqiu.arcx
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>
Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="16%" />
</foreground>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#FFFFFF</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#FFFFFF</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#F5C400</color>
</resources>
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
+24
View File
@@ -0,0 +1,24 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
# This newDsl flag was added by the Flutter template
android.newDsl=false
# This builtInKotlin flag was added by the Flutter template
android.builtInKotlin=false
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-all.zip
+26
View File
@@ -0,0 +1,26 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "9.0.1" apply false
id("org.jetbrains.kotlin.android") version "2.3.20" apply false
}
include(":app")
Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

+91
View File
@@ -0,0 +1,91 @@
{
"bowOption": [
{
"id": 1,
"name": "反曲弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02c0mwlgpcihn.png"
},
{
"id": 2,
"name": "复合弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02d17qt8548j4.png"
},
{
"id": 3,
"name": "美洲猎弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02cv1b8ucjp4y.png"
},
{
"id": 4,
"name": "传统弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02cohc2omofsb.png"
},
{
"id": 5,
"name": "光弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n01ru48k0bwwz8.png"
}
],
"targetOption": [
{
"id": 1,
"name": "40 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 2,
"name": "80 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 3,
"name": "122 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 4,
"name": "40 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 5,
"name": "60 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 6,
"name": "80 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 7,
"name": "三连靶",
"icon": "https://static.shelingxingqiu.com/20260310target/%E4%B8%89%E8%BF%9E.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(2).png"
},
{
"id": 8,
"name": "品字靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%93%81%E5%AD%97%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(3).png"
},
{
"id": 9,
"name": "复合 三连靶",
"icon": "https://static.shelingxingqiu.com/20260310target/%E5%A4%8D%E5%90%88%E4%B8%89%E8%BF%9E.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(5).png"
},
{
"id": 10,
"name": "复合 品字靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%A4%8D%E5%90%88%E5%93%81%E5%AD%97%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(4).png"
}
]
}
+1
View File
@@ -0,0 +1 @@
Place image assets for the local-first Flutter app here.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

+58
View File
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="345px" height="345px" viewBox="0 0 345 345" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>40/80/122 全环靶@3x</title>
<g id="靶子与靶点-" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="靶" transform="translate(-15.000000, -51.000000)">
<g id="shoot" transform="translate(15.000000, 51.000000)">
<g id="编组">
<circle id="椭圆形" stroke="#666666" stroke-width="0.5" fill="#FFFFFF" cx="172.5" cy="172.5" r="172.25"></circle>
<circle id="椭圆形" stroke="#666666" stroke-width="0.5" cx="172.5" cy="172.5" r="155.25"></circle>
<circle id="椭圆形" fill="#5E5E5E" cx="172.5" cy="172.5" r="138"></circle>
<circle id="椭圆形" stroke="#FFFFFF" stroke-width="0.5" opacity="0.6" cx="172.5" cy="172.5" r="120.75"></circle>
<circle id="椭圆形" fill="#38BFF2" cx="172.5" cy="172.5" r="103.5"></circle>
<circle id="椭圆形" stroke="#333333" stroke-width="0.5" opacity="0.600000024" cx="172.5" cy="172.5" r="86.25"></circle>
<circle id="椭圆形" fill="#FF5665" cx="172.5" cy="172.5" r="69"></circle>
<circle id="椭圆形" stroke="#333333" stroke-width="0.5" opacity="0.600000024" cx="172.5" cy="172.5" r="51.75"></circle>
<circle id="椭圆形备份" fill="#FDDC61" cx="172.5" cy="172.5" r="34.5"></circle>
<circle id="椭圆形" stroke="#333333" stroke-width="0.5" opacity="0.600000024" cx="172.5" cy="172.5" r="17.25"></circle>
<circle id="椭圆形" stroke="#333333" stroke-width="0.5" opacity="0.600000024" cx="172.5" cy="172.5" r="8.625"></circle>
</g>
<g id="编组-5" transform="translate(161.000000, 164.500000)" font-family="PingFangSC-Regular, PingFang SC" font-weight="normal">
<text id="1" font-size="10" fill="#333333">
<tspan x="172.608636" y="11">1</tspan>
</text>
<text id="2" font-size="10" fill="#333333">
<tspan x="154.136364" y="11">2</tspan>
</text>
<text id="3" font-size="10" fill="#FFFFFF">
<tspan x="137.136364" y="11">3</tspan>
</text>
<text id="4" font-size="10" fill="#FFFFFF">
<tspan x="120" y="11">4</tspan>
</text>
<text id="5" font-size="10" fill="#333333">
<tspan x="103" y="11">5</tspan>
</text>
<text id="6" font-size="10" fill="#333333">
<tspan x="86" y="11">6</tspan>
</text>
<text id="7" font-size="10" fill="#333333">
<tspan x="69.265" y="11">7</tspan>
</text>
<text id="8" font-size="10" fill="#333333">
<tspan x="52" y="11">8</tspan>
</text>
<text id="9" font-size="10" fill="#333333">
<tspan x="35" y="11">9</tspan>
</text>
<text id="10" font-size="7" fill="#333333">
<tspan x="20.9965" y="10">10</tspan>
</text>
<text id="X" font-size="7" fill="#333333">
<tspan x="9.2705" y="10.5">X</tspan>
</text>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

+21
View File
@@ -0,0 +1,21 @@
## 接口与数据文件清单
进入 `point-book.vue` 页面调用的接口(已排除个人信息 `getHomeData`),均来自**测试环境** `apitest.shelingxingqiu.com`
| # | 接口函数 | URL | 调用时机 | 数据文件 |
| --- | ---------------------------- | ------------------------------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| 1 | `getPointBookConfigAPI` | `GET /user/score/sheet/option` | onMounted | [getPointBookConfigAPI.json](file:///Users/ZhuanZ/Documents/gdfw/shoot-miniprograms/datas/getPointBookConfigAPI.json) |
| 2 | `getPointBookStatisticsAPI` | `GET /v2/user/score/sheet/statistics` | onShow / user 变化 | [getPointBookStatisticsAPI.json](file:///Users/ZhuanZ/Documents/gdfw/shoot-miniprograms/datas/getPointBookStatisticsAPI.json) |
| 3 | `getPointBookRankListAPI(1)` | `GET /user/score/sheet/week/shoot/rank/list?pageNum=1&pageSize=100` | onShow | [getPointBookRankListAPI.json](file:///Users/ZhuanZ/Documents/gdfw/shoot-miniprograms/datas/getPointBookRankListAPI.json) |
## 关于环境的说明
之前失败是因为我默认请求了生产环境 `api.shelingxingqiu.com`,而你的 token 是测试环境签发的(小程序 envVersion 为 develop/trial 时走 `apitest.shelingxingqiu.com`,见 [apis.js:9-20](file:///Users/ZhuanZ/Documents/gdfw/shoot-miniprograms/src/apis.js#L9-L20))。切换到测试环境后三个接口均返回 `code:0` 成功。
## 数据结构说明
每个 JSON 文件保存的是接口响应中 `data` 字段的内容(与前端 `request` 函数 resolve 的结果一致,见 [apis.js:50](file:///Users/ZhuanZ/Documents/gdfw/shoot-miniprograms/src/apis.js#L50))。
- **Config**`bowOption`(5种弓) + `targetOption`(10种靶),两环境数据一致
- **Statistics**:签到/今日与累计箭数/训练天数/黄心率/平均环数/各环数分布/本周箭着点坐标(当前 `weekArrows` 为空)
- **Rank**`my`(当前用户) + `list`(榜单,本周共2人上榜) + `total`
+91
View File
@@ -0,0 +1,91 @@
{
"bowOption": [
{
"id": 1,
"name": "反曲弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02c0mwlgpcihn.png"
},
{
"id": 2,
"name": "复合弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02d17qt8548j4.png"
},
{
"id": 3,
"name": "美洲猎弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02cv1b8ucjp4y.png"
},
{
"id": 4,
"name": "传统弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n02cohc2omofsb.png"
},
{
"id": 5,
"name": "光弓",
"icon": "https://static.shelingxingqiu.com/attachment/2025-08-04/dbt8n01ru48k0bwwz8.png"
}
],
"targetOption": [
{
"id": 1,
"name": "40 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 2,
"name": "80 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 3,
"name": "122 全环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%85%A8%E7%8E%AF%E9%9D%B6@3x.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x.png"
},
{
"id": 4,
"name": "40 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 5,
"name": "60 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 6,
"name": "80 半环靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%8D%8A%E7%8E%AF%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(1).png"
},
{
"id": 7,
"name": "三连靶",
"icon": "https://static.shelingxingqiu.com/20260310target/%E4%B8%89%E8%BF%9E.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(2).png"
},
{
"id": 8,
"name": "品字靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%93%81%E5%AD%97%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(3).png"
},
{
"id": 9,
"name": "复合 三连靶",
"icon": "https://static.shelingxingqiu.com/20260310target/%E5%A4%8D%E5%90%88%E4%B8%89%E8%BF%9E.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(5).png"
},
{
"id": 10,
"name": "复合 品字靶",
"icon": "https://static.shelingxingqiu.com/target20251126/%E5%A4%8D%E5%90%88%E5%93%81%E5%AD%97%E9%9D%B6.svg",
"iconPng": "https://static.shelingxingqiu.com/shootTarget/shoot@2x(4).png"
}
]
}
+44
View File
@@ -0,0 +1,44 @@
{
"my": {
"id": 339,
"name": "高桥凉介(发量惊人)",
"avatar": "https://static.shelingxingqiu.com/attachment/2026-08-08/dkj77wp1cmk3ovqjimjpeg",
"totalDay": 1,
"averageRing": 7,
"weekArrow": 0,
"ifLike": false,
"rank": 0,
"likeTotal": 0,
"vip": true,
"sVip": true
},
"list": [
{
"id": 212,
"name": "Amer就是总部的喵美酱啦!𓆡",
"avatar": "https://static.shelingxingqiu.com/attachment/2026-08-07/dkijshwr9k3i0aiyqnjpeg",
"totalDay": 29,
"averageRing": 5.681518151815181,
"weekArrow": 60,
"ifLike": false,
"rank": 1,
"likeTotal": 0,
"vip": false,
"sVip": false
},
{
"id": 338,
"name": "Sylar",
"avatar": "https://static.shelingxingqiu.com/attachment/2026-08-07/dkibj7cfdx34jh04gtjpeg",
"totalDay": 1,
"averageRing": 4.583333333333333,
"weekArrow": 24,
"ifLike": false,
"rank": 2,
"likeTotal": 0,
"vip": true,
"sVip": false
}
],
"total": 2
}
+24
View File
@@ -0,0 +1,24 @@
{
"weeksCheckIn": [false, false, false, false, false, false, false],
"todayTotalArrow": 0,
"totalArrow": 3,
"totalDay": 1,
"averageRing": 7,
"yellowRate": 0.3333,
"checkInCount": -44,
"ringRate": {
"-1": 0,
"0": 0,
"1": 0,
"10": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0
},
"weekArrows": []
}
+165
View File
@@ -0,0 +1,165 @@
# 📝 记分本(Point BookFlutter 纯本地版 PRD
## 文档信息
- **文档状态**:已完成(重构版)
- **适用端**iOS / Android 客户端(Flutter 纯本地架构)
- **变现模式**:免费试用 + iOS 苹果内购(IAP 买断/解锁)
- **关联模块**:本地训练统计 / 个人资料管理 / 记分管理 / 苹果内购
---
## 1. 页面概述
### 1.1 页面定位与目标
- **定位**:记分本业务线的 **总入口与本地数据总览页**
- **目标**
1. **零门槛使用**:无任何登录流程,首次打开即可直接查看本地统计或发起记分。
2. **正向数据反馈**:直观展示本地累计射箭数据、日均消耗、环值命中分布与落点热力图。
3. **内购合规转化**:提供免费体验额度,在用户第 N 次点击【开始记分】时,平滑唤起苹果内购付费解锁弹框。
### 1.2 权限与架构变更
- **数据架构****纯本地架构(Local-First)**,无后端服务器、无网络 API,所有训练数据与配置均存储于手机本地数据库(Isar/Hive)。
- **用户体系**:**完全免登录**,移除所有手机号获取、微信登录及协议勾选框。
- **排行榜**:**彻底移除**周榜、点赞及任何他人对比功能。
---
## 2. 页面流转与初始化逻辑
```mermaid
graph TD
A[用户打开 App / 进入首页] --> B[加载本地数据库 Isar]
B --> C[读取/初始化本地 UserProfile]
B --> D[读取/初始化本地 AppConfig]
B --> E[读取本地历史 PointRecord 列表]
C --> F[渲染:顶部个人资料卡片]
D --> G[渲染:用户权益/免费剩余次数]
E --> H[渲染:本地统计指标、落点热力图、环值分布图]
```
---
## 3. 核心功能与交互说明
### 3.1 本地个人资料管理(头像与昵称修改)
- **默认生成**:App 首次启动时,本地自动创建默认 Profile:
- **默认昵称**`弓箭手_XXXX`(四位随机数字)。
- **默认头像**:预设本地 Avatar Asset。
- **编辑交互**
- **入口**:点击首页顶部的个人资料卡片或【编辑】图标。
- **修改昵称**:弹出本地输入框,限制 1~12 个字符。
- **修改头像**:支持从手机本地相册选择图片或调起相机拍摄;选中后将图片异步拷贝至 App 本地沙盒目录 `ApplicationDocumentsDirectory/avatar.png`,数据库中仅保存文件路径。
---
### 3.2 个人训练统计卡片(纯本地计算)
- **关键指标**:今日射箭数、今日消耗、运动强度、训练天数、累计射箭数、平均环数。
- **计算规则**
- **无数据时**:指标统一展示为 `-`
- **今日消耗**$\text{今日箭数} \times 1.6$。
- **运动强度**$\frac{\text{今日箭数} \times 5}{60}$(上限封顶为 10)。
- $> 6$:标记为 **重度**
- $4 \sim 6$:标记为 **中度**
- $< 4$:标记为 **轻度**
---
### 3.3 核心业务入口与苹果内购(IAP)拦截
#### 🔹 入口一:【计分记录】
- **交互**:点击直接进入 `本地计分记录列表页`(支持按弓型/距离/靶纸筛选及本地记录滑动删除)。
#### 🔹 入口二:【开始记分】(含免费试用与内购拦截)
- **参数配置**
- `free_trial_limit`: 可配置免费试用次数(默认 `2` 次)。
- `used_trial_count`: 已使用免费试用次数。
- `is_vip_unlocked`: 是否已购买内购解锁(`true` / `false`)。
- **拦截判定流程**
```mermaid
graph TD
Start[点击“开始记分”] --> VIPCheck{is_vip_unlocked == true ?}
VIPCheck -- 是 --> DraftCheck
VIPCheck -- 否 --> TrialCheck{used_trial_count < free_trial_limit ?}
TrialCheck -- 是 (试用额度内) --> DraftCheck
TrialCheck -- 否 (试用额度已满) --> Paywall[阻断进入,弹出收费解锁弹框]
DraftCheck{本地是否存在未完成草稿?} -- 无草稿 --> CreatePage[进入参数选择/新建记分页]
DraftCheck -- 有草稿 --> DraftConfirmDialog[弹出草稿二选一确认框]
DraftConfirmDialog -- 继续编辑 --> EditPage[进入记分编辑页加载草稿]
DraftConfirmDialog -- 重新计分 --> ClearDraft[清空本地草稿] --> CreatePage
```
> **计数更新时机**:当用户在试用期内完成一次完整记分并点击**【保存记分】**成功写入本地数据库后,系统自动执行 `used_trial_count + 1`。
#### 💳 内购解锁弹窗与结果流转
- **弹窗展示**:包含内购商品名称、价格、买断权益说明、`[立即解锁]` 按钮、`[恢复购买]` 按钮及 `[取消/暂不解锁]` 按钮。
- **支付流转规则**
| 用户操作 / 支付状态 | 系统响应 | 页面流转 |
| ------------------------ | ------------------------------------------ | --------------------------- |
| **点击 [立即解锁]** | 调起 Apple App Store 原生支付组件。 | 界面显示原生 Loading 遮罩。 |
| **支付成功 (Purchased)** | 1. 本地数据库更新 `is_vip_unlocked = true` | |
2. 弹出 Toast 提示:“解锁成功!已获得无限记分权益” | 1. 关闭内购弹窗;
3. **返回【记分本首页】**
4. 再次点击【开始记分】自动解锁放行。 |
| **取消支付 (Canceled)** | 1. 弹出 Toast 提示:“支付已取消” | 1. 关闭内购弹窗;
5. **停留在【记分本首页】**。 |
| **支付失败 (Error)** | 1. 弹出 Toast 提示:“支付失败:[错误信息]” | 1. 关闭 Loading
6. **停留在【记分本首页】**。 |
| **点击 [恢复购买]** | 调起 `InAppPurchase.instance.restorePurchases()` | 查到历史购买凭证后更新 `is_vip_unlocked = true` 并提示“权益已恢复”,关闭弹窗并**返回【记分本首页】**。 |
---
### 3.4 本地图像分析模块(热力图与环值分布)
#### 🎯 落点热力图
- **展示条件**:本地存在历史训练数据时展示。
- **生成方式**:读取本地 `PointRecord` 中的 `hitPoints` 坐标数据,使用 Flutter Canvas 在本地预设靶纸底图上直接绘制热力点覆盖层。
#### 📊 个人环值分布图
- **展示条件**:本地存在历史记录时展示。
- **展示形式**:按 `M / X / 1~10 环` 统计本地所有箭数的占比,以柱状图形式呈现。
---
## 4. 边界异常处理与业务细节(QA 关注)
| 场景 | 预期处理机制 | 备注 / 风险点 |
| --------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
| **首次安装 / 无数据** | 统计数据指标展示 `-`,热力图展示纯靶纸背景图,免费次数显示 `0/2`。 | 避免因为数据为空导致本地 Canvas 渲染报错。 |
| **本地草稿覆盖** | 点击“重新计分”会强制删除本地 SQLite/Isar 中的草稿记录,并覆盖写入。 | 需有二次弹窗明确确认,防止误删未保存数据。 |
| **重装 App / 换手机** | 纯本地 App 不支持跨设备数据同步;用户可通过内购弹窗的 **[恢复购买]** 恢复付费权益。 | 需在 App 内“关于我们”或设置页明确告知“数据存储于本地,卸载 App 会清空训练记录”。 |
| **网络离线内购** | 发起购买需要网络连接,若离线调起内购,提示:“无法连接到 App Store,请检查网络设置”。 | - |
---
---
## 5. 关联页面流转汇总
- 📄 **记分本首页** (`PointBookHomeScreen`):本地数据总览、免费次数提示、个人资料编辑入口、内购弹窗触发。
- 📄 **计分记录列表** (`PointBookListPage`):读取本地 Isar 历史列表、草稿展示与记录删除。
- 📄 **新建参数配置** (`PointBookCreatePage`):选择弓型、距离、靶纸类型及组数。
- 📄 **记分编辑/打靶页** (`PointBookEditPage`):本地实时记录落点与环数,保存时写入本地数据库并扣减试用次数。
@@ -1,390 +0,0 @@
# ARCX iOS 本地打包机落地计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在本机(或专用 Mac)建立可重复的 ARCX iOS 出包能力:前端资源导出 → 原生工程签名 → 产出可安装/可上架 ipa。
**Architecture:** 采用「两阶段」:Phase A 先用 Mac **安心打包**快速打通证书与出包;Phase B 再搭建完整 **离线 SDK + Xcode** 本地打包机,满足证书/代码不出本机、可脚本化/CI 的需求。`arcx-app` 是 vue-cli/vite 项目,本地打包资源**必须经 HBuilderX 导出**,不能仅靠 `npm run build:ios`
**Tech Stack:** uni-app (Vue3/Vite) · HBuilderX · DCloud iOS 离线 SDK · Xcode 26+ · CocoaPods · Apple Developer 证书/Profile · Transporter
**官方文档入口:**
- 总览:[uni-app 官网](https://uniapp.dcloud.net.cn/) → 发布 → 原生 App(离线)
- 离线 SDK 总入口:[nativesupport AppDocs](https://nativesupport.dcloud.net.cn/AppDocs/README)
- iOS 开发环境/工程配置:[usesdk/ios](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios)
- 导出前端资源:[importfeproject/export](https://nativesupport.dcloud.net.cn/AppDocs/importfeproject/export.html)
- 证书/Archive/上传:[package/ios](https://nativesupport.dcloud.net.cn/AppDocs/package/ios.html)
- iOS 原生资源(Info.plist 等):[app-nativeresource-ios](https://uniapp.dcloud.net.cn/tutorial/app-nativeresource-ios)
- 安心打包(Mac 本地签):[SafePack](https://uniapp.dcloud.net.cn/tutorial/build/SafePack.html)
- 模块/Pod 集成(5.13+):[iOSModuleConfig/common](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/common.html)
---
## 官网结论摘要(先读再落地)
### 两条「本地」路径不要混
| 路径 | 本质 | 证书/前端代码 | 限制 | 适合 |
|------|------|---------------|------|------|
| **安心打包** | 云端生成原生壳,**本机合并代码并签名** | 不上传代码与证书 | 非纯离线;改模块配置会重新拉壳;付费原生插件/原生混淆能力受限场景见文档 | 日常出包、Mac 打包机首选起步 |
| **离线打包** | 下载 iOS 离线 SDK,用 **Xcode** 本地编签 | 全程本机 | 无原生混淆;**付费 uni 原生插件不可用**;须申请 `dcloud_appkey`;编译器版本必须与 SDK 一致 | 强合规、深度原生定制、CI Archive |
### 离线打包标准流水线(官方)
1. **版本对齐**HBuilderX / `npm run info` 的编译器版本 ≡ 离线 SDK 版本(不一致会弹窗且功能异常)。
2. **申请 Appkey**SDK ≥ 3.1.10):在 Info.plist 配置 `dcloud_appkey`Bundle ID + `control.xml` 中 appid 必须与申请一致。
3. **导出资源**HBuilderX → 发行 → 原生 App-本地打包 → **生成本地打包 App 资源**
- **vue-cli 项目不能用纯 CLI 导出**,必须用 HBuilderX 打开项目再导出。
- `manifest.json``appid` 不能手填空值,须由 HBuilderX 获取(本仓库已有 `__UNI__8A880C6`)。
4. **配置 Xcode 工程**`HBuilder-Hello`):
- Bundle ID / Display Name / Version / Build
- 与导出资源中的 `manifest``control.xml` appid 对齐
- 图标、LaunchScreen、隐私描述、所需模块(参考 `Feature-iOS.xls`;新版推荐 CocoaPods `uniapp_subspecs`
- 合并项目内 `nativeResources/ios`(离线时需**手动**合并进 Xcode)
5. **Signing**:生产证书 + Distribution Profile(与 Bundle ID 绑定)。
6. **Product → Archive → 导出 ipa**;上架用 **Transporter** 上传。
### 与本仓库的映射
| 项 | 当前值 | 打包机要求 |
|----|--------|------------|
| 项目形态 | vite + `@dcloudio/uni-app` alpha `4080620251107001` | 离线 SDK 选与编译器对齐的版本;用 HBuilderX 打开本仓库根目录 |
| DCloud appid | `__UNI__8A880C6` | 写入 SDK 工程 `control.xml` / 资源目录名 |
| iOS Bundle ID | `com.shelingxingqiu.arcx` | Apple App ID + Provisioning 必须一致 |
| 版本 | `versionName` 0.1.1 / `versionCode` 101 | Xcode Version / Build 对齐 |
| 证书 | `manifest` 中 p12/profile **已注释** | 打包机钥匙串导入正式证书;勿把密码提交 Git |
| 原生资源 | `nativeResources/ios/info.plist`(含 ATT 文案) | 云包自动合并;离线需手动合并 |
| 本机工具 | macOS 26.1 · Xcode 26.1.1 · CocoaPods 已装 | 已满足官方「Xcode 26.0+」门槛 |
---
## 文件与目录约定(打包机)
建议在打包机固定目录(示例,可按团队规范改):
```text
~/Packaging/
credentials/ # 不进 Git.p12、.mobileprovision、密码备忘(加密磁盘)
sdk/
iOS-SDK-<ver>/ # 解压后的离线 SDK(与编译器同版本)
workspace/
arcx-app/ # git clone
HBuilder-Hello/ # 从 SDK 拷出的长期维护工程(或软链)
artifacts/
ipa/ # 产出
logs/
scripts/
export-note.md # HBuilderX 导出步骤备忘(GUI
sync-www.sh # 把导出的 www/资源拷进原生工程
archive.sh # xcodebuild archive + export
```
项目内相关文件:
- `src/manifest.json` — appid、ios.appid、隐私、图标路径
- `nativeResources/ios/info.plist` — 额外 Info.plist 合并项
- `package.json` — 编译器版本锚点
- `docs/superpowers/plans/2026-08-07-ios-local-pack-machine.md` — 本计划
---
## Phase A:Mac 安心打包机(1–2 天,先打通)
> 目标:Mac 上可重复产出已签名 ipa;证书与业务代码不上传云端(首次仍会提交模块配置拉取原生壳)。
### Task 1: 账号与证书就绪
**Files:**
- 不改仓库;材料落在 `~/Packaging/credentials/`
- [ ] **Step 1: Apple Developer**
准备:
- Apple Developer 账号
- App ID`com.shelingxingqiu.arcx`
- Distribution Certificate.p12 + 密码)
- App Store / Ad Hoc `mobileprovision`(按发布渠道选)
- [ ] **Step 2: 导入钥匙串**
```bash
# 在打包机执行(路径按实际修改)
security import ~/Packaging/credentials/ios_dist.p12 -k ~/Library/Keychains/login.keychain-db -P '<P12_PASSWORD>' -T /usr/bin/codesign
```
Expected: 钥匙串可见「Apple Distribution: …」证书,信任链完整。
- [ ] **Step 3: 在 HBuilderX 配置打包证书**
打开 `src/manifest.json` → App 模块配置 / iOS 打包配置,填入(**勿提交明文密码到 Git**):
- Bundle ID`com.shelingxingqiu.arcx`
- 证书路径、密码、profile 路径
本地可用环境变量或 HBuilderX 图形界面填写;保持仓库内注释状态。
- [ ] **Step 4: 验收清单**
- [ ] Bundle ID 与 Profile 一致
- [ ] 隐私文案与实际上架用途一致(当前含相机/相册/定位/麦克风/跟踪,无用项建议上架前删减)
- [ ] 图标资源 `unpackage/res/icons/` 齐全
### Task 2: HBuilderX 打开 CLI 项目并首次安心打包
**Files:**
- Modify locally only: HBuilderX 打开 `/Users/ZhuanZ/Documents/gdfw/arcx-app`
- Output: `unpackage/release/ipa/`(或 HBuilderX 提示目录)
- [ ] **Step 1: 安装与 HBuilderX 编译器对齐的版本**
对照 `package.json``@dcloudio/uni-app` 版本号 `3.0.0-alpha-4080620251107001`(对应 HX/编译器 4.08.06 一带),安装匹配的 [HBuilderX](https://www.dcloud.io/hbuilderx.html)。
- [ ] **Step 2: 用 HBuilderX 打开项目根目录**
确认能识别 `src/manifest.json`appid 为 `__UNI__8A880C6`
- [ ] **Step 3: 发行 → 原生 App-云端打包,勾选安心打包**
按 [SafePack](https://uniapp.dcloud.net.cn/tutorial/build/SafePack.html)
1. 首次:云端下发原生壳 → 本机合并代码 → 本机签名
2. 后续仅改前端且模块配置不变:本地复用壳,速度更快,且不占免费云打包次数
- [ ] **Step 4: 安装 ipa 到测试机或上传 TestFlight**
Expected: 应用可启动;若提示 appkey/证书问题,回到 Task 1。
- [ ] **Step 5: 记录打包机 SOP 一页纸**
写入 `~/Packaging/scripts/export-note.md`HBuilderX 版本、证书别名、Profile 名称、成功产物路径、耗时。
---
## Phase B:完整离线本地打包机(3–5 天)
> 目标:不依赖云端原生壳;用离线 SDK + Xcode Archive 出包;可脚本化。
### Task 3: 下载并对齐 iOS 离线 SDK
**Files:**
- Create: `~/Packaging/sdk/iOS-SDK-<ver>/`
- [ ] **Step 1: 查编译器版本**
在项目根目录:
```bash
cd /Users/ZhuanZ/Documents/gdfw/arcx-app
# 若已配置 uni info 脚本则:
npx uni -v
# 或在 HBuilderX 中查看关于/编译器版本
```
Expected: 记下与导出资源一致的版本号字符串。
- [ ] **Step 2: 下载同版本 iOS 离线 SDK**
从 [SDK 下载页](https://nativesupport.dcloud.net.cn/AppDocs/download/ios)(以官网当前入口为准)下载,解压到 `~/Packaging/sdk/`
目录应含:
- `HBuilder-Hello` — 打包工程
- `Feature-iOS.xls` — 模块依赖表
- `SDK` — 库与资源
- (新版)`uniapp.podspec` / 示例 `Podfile`
- [ ] **Step 3: 版本一致性门禁**
建立检查表:`编译器版本` = `SDK 发布版本` = `HBuilderX 导出资源所用版本`。三者任一不一致禁止出生产包。
### Task 4: 申请并写入 dcloud_appkey
**Files:**
- Modify (Xcode 工程): `HBuilder-Hello/.../Info.plist`
- 参考:[usesdk/ios 配置 Appkey](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios)
- [ ] **Step 1: 在 DCloud 开发者中心申请 Appkey**
绑定:
- DCloud appid`__UNI__8A880C6`
- Bundle ID`com.shelingxingqiu.arcx`
- [ ] **Step 2: Info.plist 增加**
```xml
<key>dcloud_appkey</key>
<string>YOUR_DCLOUD_APPKEY</string>
```
- [ ] **Step 3: 同步修改 control.xml 中的 appid 与 Bundle ID**
Expected: 真机运行不再提示 appkey 错误。
### Task 5: HBuilderX 导出本地打包资源并导入工程
**Files:**
- Output from HX: 通常在项目 `unpackage/resources/` 或发行提示路径下的 www/app 资源
- Modify: `HBuilder-Hello` 内 Pandora/apps 资源目录
- [ ] **Step 1: 导出**
HBuilderX → 发行 → **原生 App-本地打包****生成本地打包 App 资源**
CLI 项目必须这一步,见[官方说明](https://nativesupport.dcloud.net.cn/AppDocs/importfeproject/export.html)
- [ ] **Step 2: 拷贝资源进 HBuilder-Hello**
按官方「导入前端资源」文档:将导出的应用资源放到原生工程 `Pandora/apps/<appid>/www`(目录名 = appid)。
建议脚本骨架 `~/Packaging/scripts/sync-www.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
APPID="__UNI__8A880C6"
SRC="${1:?usage: sync-www.sh <exported_www_dir>}"
DST="$HOME/Packaging/workspace/HBuilder-Hello/HBuilder/Pandora/apps/${APPID}/www"
rm -rf "$DST"
mkdir -p "$DST"
cp -R "$SRC"/. "$DST"/
echo "synced -> $DST"
```
> 实际 `Pandora` 相对路径以当次 SDK 示例工程为准,首次手工核对后再固化脚本。
- [ ] **Step 3: 合并 `nativeResources/ios`**
将仓库 `nativeResources/ios/info.plist` 中的键(如 `NSUserTrackingUsageDescription`)合并进 Xcode Info.plist;有 `Resources` 时拷入 Bundle Resources。
### Task 6: 配置 Xcode Identity、模块与签名
**Files:**
- Modify: Xcode Target `HBuilder` General / Signing / Info.plist /(新版)Podfile
- [ ] **Step 1: Identity**
| 字段 | 值 |
|------|-----|
| Display Name | ARCX |
| Bundle Identifier | `com.shelingxingqiu.arcx` |
| Version | `0.1.1`(随 `manifest.versionName` |
| Build | `101`(随 `manifest.versionCode` |
同时打开工程内 `manifest`,使 name/version 与上表一致。
- [ ] **Step 2: 模块精简**
本项目 `manifest.app-plus.modules` 当前为空 → 离线工程只保留基础能力。
若后续加支付/推送/登录,按 `Feature-iOS.xls``Podfile``uniapp_subspecs` 开启,再 `pod install`
```bash
cd ~/Packaging/workspace/HBuilder-Hello
pod install
open HBuilder-Hello.xcworkspace # 使用 Pods 时必须开 workspace
```
- [ ] **Step 3: Signing & Capabilities**
- Team + Distribution 证书
- Release 使用正确 Provisioning Profile
- 需要 ATT 时已有隐私描述;按需加 Associated Domains 等
- [ ] **Step 4: 真机 Run 冒烟**
Expected: App 启动到首页 Tab,无「版本不一致 / appkey 错误」弹窗。
### Task 7: Archive 出包与上传
**Files:**
- Create: `~/Packaging/scripts/archive.sh`
- Output: `~/Packaging/artifacts/ipa/`
- [ ] **Step 1: GUI 首次 Archive**
Xcode → Product → Archive → Distribute App → 导出 ipaApp Store Connect 或 Ad Hoc)。
- [ ] **Step 2: 固化命令行(打包机自动化)**
```bash
#!/usr/bin/env bash
set -euo pipefail
WS="$HOME/Packaging/workspace/HBuilder-Hello/HBuilder-Hello.xcworkspace"
SCHEME="HBuilder"
OUT="$HOME/Packaging/artifacts/ipa"
ARCHIVE="$OUT/ARCX.xcarchive"
EXPORT_PLIST="$HOME/Packaging/scripts/ExportOptions.plist"
xcodebuild -workspace "$WS" -scheme "$SCHEME" \
-configuration Release -archivePath "$ARCHIVE" archive
xcodebuild -exportArchive -archivePath "$ARCHIVE" \
-exportOptionsPlist "$EXPORT_PLIST" -exportPath "$OUT"
```
`ExportOptions.plist` 首次用 Xcode 导出后从 Organizer 旁路生成,或按 Apple 文档手写 `method=app-store-connect`
- [ ] **Step 3: 上传**
使用 **Transporter** 上传 ipa 至 App Store Connect[官方](https://nativesupport.dcloud.net.cn/AppDocs/package/ios.html))。
- [ ] **Step 4: 打生产包前检查**
- [ ] `control.xml` **去掉** `debug="true"` / `syncDebug="true"`(自定义基座调试用,留着会导致热更新等问题)
- [ ] Version/Build 已递增
- [ ] 隐私清单(SDK 4.13+ 示例工程含基础 PrivacyInfo)已按模块补齐
---
## Phase C:打包机运维与门禁(持续)
### Task 8: 目录权限、密钥与备份
- [ ] **Step 1:** `credentials/` 放加密卷或 1Password**禁止进 Git**
- [ ] **Step 2:** `.gitignore` 确认忽略 `unpackage/release/`、本地 p12、profile
- [ ] **Step 3:** 每月检查:Apple 证书过期日、HBuilderX/SDK 升级窗口、Xcode 与 macOS 兼容性
### Task 9: 版本升级流程(强制)
每次升级编译器:
1. 升级 HBuilderX / 项目 `@dcloudio/*` 依赖
2. 下载**同版本** iOS 离线 SDK
3. 重新导出资源
4. Diff `HBuilder-Hello` 与新 SDK 示例工程(Pods、隐私清单、基础库)
5. 再 Archive
### Task 10: 验收标准(Definition of Done
- [ ] 安心打包:本机产出可安装 ipa(Phase A)
- [ ] 离线打包:Xcode Archive 产出 ipa,安装后无版本/appkey 弹窗(Phase B
- [ ] 同一 commit 资源可重复出包(脚本化 sync + archive
- [ ] 证书与密码不在仓库中
- [ ] 有一页 SOP:版本号对齐表 + 出包命令 + 回滚方式
---
## 推荐落地节奏
| 周次 | 交付 |
|------|------|
| Day 1 | 证书/Profile + HBuilderX 打开项目 + 安心打包首包 |
| Day 2 | TestFlight/真机验收;写 SOP;决定是否上离线 |
| Day 34 | 下载对齐 SDK、Appkey、导出资源、Xcode Identity/签名 |
| Day 5 | Archive 脚本化 + Transporter;自定义基座(可选) |
**默认建议:** ARCX 现阶段模块少、无付费原生插件 → **先 Phase A(安心打包)**;若合规要求「完全不碰云原生壳」或要 CI Archive,再上 Phase B。
---
## 风险与明确不做
| 风险 | 应对 |
|------|------|
| 编译器与 SDK 版本不一致 | 出包前硬门禁,禁止混用 |
| CLI 无法直接导出本地资源 | 打包机必须装 HBuilderX |
| 离线无法用付费 uni 原生插件 / 原生混淆 | 评估插件策略;必要时改安心/传统云包 |
| manifest 隐私项过多导致审核追问 | 上架前按真实能力删减 |
| p12 密码曾出现在历史注释 | 已注释路径勿回填到 Git;轮换证书 |
---
## Self-Review
1. **Spec coverage** 官网离线流程(版本对齐、Appkey、导出资源、Xcode 配置、证书、Archive、Transporter)与安心打包路径均有 Task;本仓库 Bundle ID/appid/nativeResources 已映射。
2. **Placeholder scan** 脚本中的路径以 SDK 实际目录为准,首次需人工核对后固化(已标明)。
3. **一致性:** Bundle ID 全程使用 `com.shelingxingqiu.arcx`DCloud appid 全程 `__UNI__8A880C6`
+34
View File
@@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
+24
View 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>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
</dict>
</plist>
+2
View File
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
+2
View File
@@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
+43
View File
@@ -0,0 +1,43 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
+35
View File
@@ -0,0 +1,35 @@
PODS:
- Flutter (1.0.0)
- image_picker_ios (0.0.1):
- Flutter
- in_app_purchase_storekit (0.0.1):
- Flutter
- FlutterMacOS
- isar_flutter_libs (1.0.0):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
- isar_flutter_libs (from `.symlinks/plugins/isar_flutter_libs/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
in_app_purchase_storekit:
:path: ".symlinks/plugins/in_app_purchase_storekit/darwin"
isar_flutter_libs:
:path: ".symlinks/plugins/isar_flutter_libs/ios"
SPEC CHECKSUMS:
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
image_picker_ios: e0ece4aa2a75771a7de3fa735d26d90817041326
in_app_purchase_storekit: 22cca7d08eebca9babdf4d07d0baccb73325d3c8
isar_flutter_libs: 9fc2cfb928c539e1b76c481ba5d143d556d94920
PODFILE CHECKSUM: 3c63482e143d1b91d2d2560aee9fb04ecc74ac7e
COCOAPODS: 1.16.2
+746
View File
@@ -0,0 +1,746 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
27A77D74E4505B5D2AA63D0F /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 561C8CEE01920EEC7A945F80 /* Pods_RunnerTests.framework */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
8F0B832FFA652893A2418D6F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E868FF8080DD0482F6C33647 /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
048D9C63DCC6330C4375E801 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
41517F8DE1244167EA1C3EF0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
54790F6136DFBB3350A35FAA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
561C8CEE01920EEC7A945F80 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8173FD6563D966BAFA3AA699 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9FE17248895AEA422B438BFD /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
DCD6C7F1914EC7BEB639DB0B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
E868FF8080DD0482F6C33647 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
927EAE761096EB2B5FA9B76C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
27A77D74E4505B5D2AA63D0F /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8F0B832FFA652893A2418D6F /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
156C087B45530EC102A0D4A8 /* Pods */ = {
isa = PBXGroup;
children = (
41517F8DE1244167EA1C3EF0 /* Pods-Runner.debug.xcconfig */,
54790F6136DFBB3350A35FAA /* Pods-Runner.release.xcconfig */,
8173FD6563D966BAFA3AA699 /* Pods-Runner.profile.xcconfig */,
DCD6C7F1914EC7BEB639DB0B /* Pods-RunnerTests.debug.xcconfig */,
048D9C63DCC6330C4375E801 /* Pods-RunnerTests.release.xcconfig */,
9FE17248895AEA422B438BFD /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
156C087B45530EC102A0D4A8 /* Pods */,
B36C47CC576BE63C4192FAAB /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
B36C47CC576BE63C4192FAAB /* Frameworks */ = {
isa = PBXGroup;
children = (
E868FF8080DD0482F6C33647 /* Pods_Runner.framework */,
561C8CEE01920EEC7A945F80 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
5ED369F7938D6E55445F98FE /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
927EAE761096EB2B5FA9B76C /* Frameworks */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
7AE3623C7230451709ED948F /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
6E44F253809A70D824E46E32 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
5ED369F7938D6E55445F98FE /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
6E44F253809A70D824E46E32 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
7AE3623C7230451709ED948F /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = MT26BPCKF6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "DevProfile-arc";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = DCD6C7F1914EC7BEB639DB0B /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 048D9C63DCC6330C4375E801 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9FE17248895AEA422B438BFD /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = MT26BPCKF6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "DevProfile-arc";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = MT26BPCKF6;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.shelingxingqiu.arcx;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "DevProfile-arc";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
@@ -2,7 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSUserTrackingUsageDescription</key> <key>IDEDidComputeMac32BitWarning</key>
<string>We use tracking to analyze in-app clicks and usage to continuously improve the product experience.</string> <true/>
</dict> </dict>
</plist> </plist>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
+16
View File
@@ -0,0 +1,16 @@
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}
@@ -0,0 +1 @@
{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

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