create-dwy 0.14.3 → 0.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# create-dwy
|
|
2
2
|
|
|
3
|
+
## 0.14.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 将 iOS 规则 `dwy-swift-style.md` 重命名为 `dwy-swift-core.md`,并重构为精简版规范。
|
|
8
|
+
- 新增规则级配置收口约束,要求可配置项统一在 `AppConfig` 管理。
|
|
9
|
+
- 加强国际化规则:默认要求中文/英文支持,统一 `localizationBundle + loc() + LocalizationManager + AppLanguage` 实施要点。
|
|
10
|
+
|
|
3
11
|
## 0.14.3
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: iOS 17+ SwiftUI 开发基线规则(全局适配、动画、国际化、注释)
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*.swift"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## iOS 目标与写法
|
|
8
|
+
|
|
9
|
+
- iOS 最低版本 17.0+,不为 16 及以下做兼容分支。
|
|
10
|
+
- 统一 Observation + `@MainActor`,状态对象默认 `final class`。
|
|
11
|
+
|
|
12
|
+
```swift
|
|
13
|
+
@MainActor
|
|
14
|
+
@Observable
|
|
15
|
+
final class TaskListViewModel {}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 风格
|
|
19
|
+
|
|
20
|
+
- 4 空格缩进,不用 Tab。
|
|
21
|
+
- `UpperCamelCase` / `lowerCamelCase`。
|
|
22
|
+
- 参数过长换行,类型签名参数与返回值各占一行。
|
|
23
|
+
- 一行只做一件事,避免压缩表达式。
|
|
24
|
+
|
|
25
|
+
## 配置管理
|
|
26
|
+
|
|
27
|
+
- 可修改的运行时配置统一放在 `AppConfig`,避免业务层散落魔法值和可调参数。
|
|
28
|
+
- 默认实现必须只有一个 `AppConfig` 入口,所有配置项、开关、阈值和默认值从这里读取。
|
|
29
|
+
- 配置读取禁止越界分散;新参数先加到 `AppConfig`,再注入到业务逻辑。
|
|
30
|
+
- `AppConfig` 负责默认值、持久化键名、配置来源边界,业务层只读使用。
|
|
31
|
+
|
|
32
|
+
## 注释与控制流
|
|
33
|
+
|
|
34
|
+
- 关键类型、方法、属性必有中文 `///` 注释,写明意图和边界。
|
|
35
|
+
- 系统外边界校验,内部调用信任类型,不加冗余兜底。
|
|
36
|
+
- 统一 `guard` + early return,不要多层 `else`。
|
|
37
|
+
- 禁止 `try?` 吞异常;不写无意义 `value ?? default`。
|
|
38
|
+
|
|
39
|
+
## 全面屏与布局
|
|
40
|
+
|
|
41
|
+
- 默认尊重安全区;固定内容区用 `safeAreaInset` / `safeAreaPadding`。
|
|
42
|
+
- 全屏背景、遮罩、弹层可用 `ignoresSafeArea()`。
|
|
43
|
+
- 禁止使用固定状态栏高度常量。
|
|
44
|
+
|
|
45
|
+
## 动效
|
|
46
|
+
|
|
47
|
+
- 默认优先 `spring`,用同一组参数避免风格撕裂。
|
|
48
|
+
|
|
49
|
+
```swift
|
|
50
|
+
private let motionSpring = Animation.spring(response: 0.5, dampingFraction: 0.75)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 图标与文案
|
|
54
|
+
|
|
55
|
+
- 图标优先 `Image(systemName:)`,无符号则用成熟 SVG。
|
|
56
|
+
- 文案禁止 emoji,禁止硬编码,统一 `loc("key")`。
|
|
57
|
+
- 禁止使用 emoji 作为功能说明、状态、提示。
|
|
58
|
+
|
|
59
|
+
```swift
|
|
60
|
+
Image(systemName: "chevron.right")
|
|
61
|
+
Text(loc("home_title"))
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## 国际化
|
|
65
|
+
|
|
66
|
+
- 项目必须实现国际化。
|
|
67
|
+
- 默认实现必须包含中文和英文。
|
|
68
|
+
- 使用 `localizationBundle + loc()` + `LocalizationManager` + `AppLanguage` 组合。
|
|
69
|
+
- `loc` 必须走 bundle,不依赖默认 locale 自动解析 key。
|
|
70
|
+
- 语言变更持久化并刷新 `localizationBundle`,`system` 走系统首选。
|
|
71
|
+
|
|
72
|
+
## 资源与时序
|
|
73
|
+
|
|
74
|
+
- 颜色、字号走 token,不用裸值。
|
|
75
|
+
- 时间来源通过注入参数或测试可控入口,不直接散落 `Date()`。
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/*.swift"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Swift 代码规范
|
|
7
|
-
|
|
8
|
-
编辑任何 `.swift` 时遵守。本规则仅覆盖代码写法层(缩进、命名、注释、控制流、UI token 化),是与具体业务无关的通用约定。
|
|
9
|
-
|
|
10
|
-
## 1. 缩进与格式
|
|
11
|
-
|
|
12
|
-
- **4 空格缩进**,不用 Tab。
|
|
13
|
-
- 类型 / 函数声明参数过长时换行,每参数一行,右括号与返回类型 `) -> X` 单起一行。
|
|
14
|
-
- 一行只做一件事,避免把多个 `if` 挤进一行。
|
|
15
|
-
|
|
16
|
-
## 2. 命名
|
|
17
|
-
|
|
18
|
-
- 类型 `UpperCamelCase`,属性 / 方法 / 局部变量 `lowerCamelCase`。
|
|
19
|
-
- **局部短生命周期变量可用短名**(`i` = index、`f` = formatter、`cal` = calendar),同一文件内保持一致。
|
|
20
|
-
- 名字表达意图,避免无信息量的 `data` / `info` / `tmp` 当主力变量名。
|
|
21
|
-
|
|
22
|
-
## 3. 类型声明(iOS 17)
|
|
23
|
-
|
|
24
|
-
状态对象统一 iOS 17 写法,不要 `ObservableObject / @Published / @StateObject`:
|
|
25
|
-
|
|
26
|
-
```swift
|
|
27
|
-
@MainActor // 所有触碰 UI / 主线程隔离状态的类型都标
|
|
28
|
-
@Observable // 替代 ObservableObject
|
|
29
|
-
final class ListViewModel { // 非继承类一律 final
|
|
30
|
-
private let store: DataStore // 依赖私有 + 构造注入
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 4. 注释(中文,强制全量)
|
|
35
|
-
|
|
36
|
-
**所有代码都要加注释,包括每个类型和每个方法**。注释说明**意图**(为什么这么做、约束是什么),而非复述代码字面。
|
|
37
|
-
|
|
38
|
-
- **类型顶部必加** `///` 文档注释:说明该类型的职责、它在数据流里的位置或关键约束。`class` / `struct` / `enum` / `protocol` / 有逻辑的 `extension` 都算。
|
|
39
|
-
- **每个方法 / 函数必加** `///` 文档注释(公开和私有都要),说明它做什么、入参出参的语义、可能抛出的错误。
|
|
40
|
-
- 关键属性、反直觉分支、易踩坑处用行内 `//` 标注触发条件。
|
|
41
|
-
- 注释里**禁止 emoji**。
|
|
42
|
-
- 不写废话注释(`// 设置 name` 这种复述赋值的删掉),注释要补充代码没说出口的信息。
|
|
43
|
-
|
|
44
|
-
```swift
|
|
45
|
-
/// 列表数据源。负责从持久层读取并按时间分组,供视图直接渲染。
|
|
46
|
-
@MainActor
|
|
47
|
-
@Observable
|
|
48
|
-
final class ListViewModel {
|
|
49
|
-
|
|
50
|
-
/// 重新加载全部数据并写回 `grouped`。
|
|
51
|
-
/// 失败时透传持久层错误,由调用方决定提示策略。
|
|
52
|
-
func reload() throws {
|
|
53
|
-
let items = try store.all() // 持久层已保证非 nil,无需兜底
|
|
54
|
-
grouped = group(items)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## 5. 控制流:信任上游,不过度防御
|
|
60
|
-
|
|
61
|
-
只在系统外边界(用户输入、文件 / 网络读入、外部 API)校验;内部调用信任类型签名。
|
|
62
|
-
|
|
63
|
-
```swift
|
|
64
|
-
// 好:early return,无多余 else
|
|
65
|
-
guard !isBusy else { return }
|
|
66
|
-
withAnimation(.spring(response: 0.5, dampingFraction: 0.75)) { isBusy = true }
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
- 不写 `value ?? default` 兜已有明确来源的值。
|
|
70
|
-
- 不写 `try? { ... }` 吞异常掩盖 bug;只 catch 预期的具体错误,其余让它抛。
|
|
71
|
-
- 持久 / IO 层方法用 `throws` 透传错误,由调用方决定处理,不在底层吞。
|
|
72
|
-
|
|
73
|
-
## 6. 图标:矢量图,禁止 emoji
|
|
74
|
-
|
|
75
|
-
UI 图标优先使用 **SF Symbols 矢量图**(`Image(systemName:)`)。系统无对应符号时,改用**成熟第三方 SVG 图标**(如已集成并维护良好的 icon 套件),禁止自行手绘或临时 PNG/emoji。
|
|
76
|
-
|
|
77
|
-
```swift
|
|
78
|
-
// 优先:系统 SF Symbols
|
|
79
|
-
Image(systemName: "checkmark")
|
|
80
|
-
.font(.system(size: 11, weight: .bold))
|
|
81
|
-
.foregroundStyle(.white)
|
|
82
|
-
|
|
83
|
-
// 次选:成熟第三方矢量图标组件或资源
|
|
84
|
-
Image("icon_checkmark")
|
|
85
|
-
.resizable()
|
|
86
|
-
.frame(width: 12, height: 12)
|
|
87
|
-
|
|
88
|
-
// 禁止:emoji 当图标
|
|
89
|
-
Text("✅") // 不允许
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
任何视图、文案、注释都**禁止 emoji**。
|
|
93
|
-
|
|
94
|
-
## 7. 颜色 / 字体 / 动效 token 化
|
|
95
|
-
|
|
96
|
-
- 颜色集中到设计 token(如 `ColorTokens.*` / `theme.*`),**禁止在视图里散落硬编码颜色字面量**。
|
|
97
|
-
- 字体用 `.font(.system(size:weight:))` 或集中的字体 token。
|
|
98
|
-
- 动效统一用一组 `.spring(response:dampingFraction:)` 参数,不用 `.easeInOut`,保持全局手感一致。
|
|
99
|
-
|
|
100
|
-
## 8. 文案与时间
|
|
101
|
-
|
|
102
|
-
- 所有 UI 文案走 `String(localized: "some_key")`,**禁止硬编码字面量**;key 命名风格全项目统一。
|
|
103
|
-
- 业务逻辑里「现在」作为依赖注入(`now: @escaping () -> Date = { Date() }`),方便单测固定时间,禁止在逻辑里直接散用 `Date()`。
|