
Modaal 用一份共享的功能逻辑同时长出 SwiftUI 与 Jetpack Compose 两套原生界面,再用逐字节比对的重放检查,把两个平台的行为分叉变成一次构建失败。
shares the logic, not the screens。2 这套机制叫 Duet,框架本身开源,当前是 0.7.0 的预发布版本。3ModalBottomSheet 和 iOS 的 .sheet 在应用逻辑里是同一个界面,在用户眼里是两件完全不同的事,而这正是对的,因为 Android 用户期待的就是一块从底部升起的面板。4path、每个节点唯一的模态槽 slot、tabs、整屏阶段 stage。这个集合是封闭的,想加第五个要走一次版本化的契约变更,默认答案是不加;四个原语够不够用,官方在里程碑上做一次普查来回答——把所有 reducer 的状态扫一遍,看导航类字段有没有落在四个原语之外。no silent transitions。detent 字段,那就是违约。.confirmationDialog、.sheet、.fullScreenCover 三种 SwiftUI 呈现通道,加上系统的 Photo Picker 和 AVFoundation;Android 一边用 Material 的 AlertDialog 与 ModalBottomSheet,一边把拍摄整件事交给系统应用。两端的呈现方式几乎没有交集,而 reducer、状态形状和录制下来的 fixture 逐字节相同。5
parity/manifest.yaml 账本,两个入口:manner waiver 用于同一个界面在两个平台上用不同类别的呈现方式,比如一边是全屏对话框、一边是半高面板,只是圆角或动画曲线不同不需要登记;island 用于内部状态活在状态树之外的区域。账本由 lockstep-lint 检查,而它只核对形状和交叉引用——每个条目要对应真实存在的功能、合法的平台、ISO 格式的日期。这条差异值不值得,lint 刻意不判断,留给人来审。5duet verify 停在 134/134,fixture 语料一次都没有重录;账本上留下 0 条 waiver、6 条 island 条目,也就是 3 个区域乘 2 个平台。官方把六处刻意做出来的平台差异也列了出来:Android 不做 Lottie 开场动画,不做 Apple 登录按钮,不做反应飞行动画,不做视频转码,用 Compose 的分页 Dialog 代替 UIKit 轮播,标签先只出文字。这六处每一处最多花掉一行日志。5PRD.md,再把第一个功能规划成一份规格,固定包含概述、用户场景、技术方案、实现步骤、要新建或修改的文件、风险与未决问题、测试策略七节。你读完、改完、批准,才动第一行代码。规格文件留在项目里,所以第五十个功能是跟第一个功能对着同一份文档规划的。67
commonMain 放共享逻辑,Mac 上还需要 Android SDK 和 JDK。免费版只能建一个平台,两个平台同时建属于 Pro,按年付每月 9 欧元。16modaal.dev
producthunt.com
github.com
docs.modaal.dev
producthunt.com
docs.modaal.dev
This story was produced automatically by a channel. One sentence is all it takes for Neodrop to keep producing for you.