我做了一款精力管理App「元気手账」,聊聊从 Swift 移植到鸿蒙 ArkTS 的真实经历

鸿蒙第16篇——数据持久化 本文介绍的数据持久化是指鸿蒙应用的数据持久化存储。它是将内存中的数据通过文件或数据库的形式保存到设备存储中。鸿蒙支持多种数据存储方式, 包括用户首选项Preferences、 键值型数据库KV-Store和关系型数据库。 阅读详情

起因:我想把自己的精力变化「看见」

去年有段时间状态特别差,每天下午三点准时犯困,开会完脑子一片浆糊,但又说不清到底是什么在消耗我。

市面上的情绪记录App我试了好几个,要么让我写一大段日记(我懒),要么就是打个心情emoji完事(太粗糙)。我想要的是一个特别轻量的东西——就像手机电量百分比一样,随手记一笔"+20 跑步回来精神了"或者"-30 项目评审被锤了",然后在时间轴上看到今天的能量流向。

于是我做了「元気手账」。iOS 版先上了,用 SwiftData 写的,核心就四个模型:EnergyRecord(精力变化记录)、DailyBaseline(每天的基准电量)、Project(方舟项目,追踪精力投在哪)、QuickAction(快捷动作条)。跑了一段时间自己用着挺顺手,就开始琢磨鸿蒙版。

为什么要做鸿蒙版

说实话,不是因为什么"看好鸿蒙生态"这种大话。

原因很朴素:我手边有一台 Mate 60,日常双持。iOS版我自己用着爽,但换到华为手机的时候就断了,记录习惯一中断基本就废了。加上 HarmonyOS NEXT 搞纯血鸿蒙,ArkTS 开发工具链也成熟了不少,我想趁这波把坑踩一遍。

另外 优快云 和华为开发者社区对 HarmonyOS 内容确实有流量倾斜,这个我不装,也是动力之一。

移植过程中最头疼的三件事

1. 数据层从 SwiftData 到关系型存储的思维切换

iOS 版用 SwiftData 特别舒服,@Model 一标注,关系用 @Relationship 一声明就完事了。比如 Project 和 EnergyRecord 的一对多关系:

@Model
final class Project {
    var id: UUID = UUID()
        var name: String = ""
            var exp: Double = 0
                var level: Int = 1
                    var isLegendary: Bool = false
                        var totalSeconds: Int = 0
    @Relationship(deleteRule: .nullify, inverse: \EnergyRecord.project)
        var records: [EnergyRecord] = []
        }
        ```
到了鸿蒙这边,我用的是 `@ohos.data.relationalStore`,得自己建表、自己写 SQL、自己维护外键。说白了就是从 ORM 退回到手写 SQL 的年代。

一开始我想偷懒直接把数据全塞 JSON 存 preferences,后来记录一多查询就卡,老老实实换成了关系型数据库。这个弯路大概浪费了两天。

### 2. ArkUI 的状态管理和 SwiftUI 的差异

SwiftUI 里 `@State`、`@Observable`、`@Environment` 这套我很熟。ArkTS 里对应的是 `@State`、`@Prop`、`@Link`、`@Provide/@Consume`,概念上类似但细节上坑不少。

比如我做时间轴视图的时候,父组件的电量列表更新了,子组件的曲线图没刷新。排查了半天发现是 `@Prop` 传的是值拷贝而不是引用,应该用 `@Link`。这种事在 SwiftUI 里也踩过类似的坑,但鸿蒙的文档当时写得比较模糊,Stack Overflow 上相关问答也少,基本靠自己试。

### 3. 快捷动作条的交互实现

iOS 版的 QuickAction 是一个横向滚动条,点一下就记录一笔,delta 值预设好的。这个交互在 ArkUI 里用 `List` 横向布局加 `onClick` 就能实现,但我想加一个长按编辑的手势,这时候发现 ArkUI 的手势系统和 SwiftUI 差别挺大。

最后用了 `GestureGroup` 配合 `LongPressGesture` 和 `TapGesture` 的组合,调了几版才让长按和点击不冲突。

```arkts
Row() {
  ForEach(this.quickActions, (action: QuickActionItem) => {
      Column() {
            Image($r(`app.media.${action.icon}`))
                    .width(28).height(28)
                          Text(action.title)
                                  .fontSize(12)
                                      }
                                          .gesture(
                                                GestureGroup(GestureMode.Exclusive,
                                                        LongPressGesture({ repeat: false, duration: 500 })
                                                                  .onAction(() => { this.editAction(action) }),
                                                                          TapGesture({ count: 1 })
                                                                                    .onAction(() => { this.recordDelta(action.delta, action.title) })
                                                                                          )
                                                                                              )
                                                                                                })
                                                                                                }
                                                                                                .width('100%')
                                                                                                ```
这段是简化过的,实际还有动画和 haptic feedback 的处理,但核心思路就是这样。

## 几个做对了的决策

**用"电量"隐喻而不是"情绪"。** 这个决定是在 iOS 版就定下来的。跟朋友聊的时候发现,很多人对"记录情绪"有心理负担——觉得太私密,或者觉得矫情。但"今天还剩多少电"这个说法大家秒懂,记录起来也没压力。一个 delta 值加一句话,三秒钟搞定。

**方舟项目维度。** 这个功能是后来加的。我自己记了两周发现光看总电量曲线还不够,我想知道"到底是哪个项目把我榨干的"。加了 Project 维度之后,我真的发现写代码其实不怎么费电,反而是写文档和开需求评审会最消耗精力。这个洞察直接影响了我排日程的方式。

**纯本地存储,不联网。** 精力数据算是挺私密的东西,我不想碰云端同步这个坑(也没精力搞服务器)。iOS 版用 App Group + SwiftData 本地存储,鸿蒙版用 relationalStore 存在应用沙箱里。这个在 HarmonyOS 的隐私审核上也省了很多事。

## 当前状态和一些数据

坦白说,鸿蒙版刚上架不久,下载量还很小。七天数据基本是零,付费也是零。

这个我有心理准备。独立开发者做工具类App,冷启动就是这样。iOS 版也是上架头两周没什么动静,第三周在某个效率社区被人分享了一次才开始有自然流量。

鸿蒙的应用市场分发逻辑和 App Store 不太一样,我还在摸索。目前版本号 1.2.0,基本功能都有了:电量记录、时间轴、方舟项目、快捷动作条、周/月统计图。接下来想加的是桌面卡片(HarmonyOS 的 FormAbility),让用户不打开App就能看到当前电量。

## 鸿蒙开发的体感

说几个真实感受:

**DevEco Studio 比两年前好用太多了。** 预览器虽然偶尔抽风,但日常开发够用。热重载的速度可以接受。

**ArkUI 的声明式写法学习曲线不高,** 特别是如果你写过 SwiftUI 或者 Flutter。但一些组件的行为细节文档写得不够清楚,经常得靠试。

**鸿蒙应用市场的审核比 App Store 快,** 基本一两天就过了。但应用市场内的搜索权重逻辑我到现在没完全搞明白。

**有点可惜的是**,鸿蒙的开发者社区讨论质量参差不齐,很多帖子还是"hello world"级别的入门教程,深度踩坑分享太少了。

## 我自己怎么用这个App

每天大概记 5-8 条。早上起来默认 50 点电量(如果昨晚睡得好会手动调到 55),然后一天下来就是加加减减。

上周有一天我发现下午两点电量已经掉到 15 了——上午连着开了三个会。看到这个数字我直接取消了下午的一个非必要会议,出去走了二十分钟。回来记了个"+15 散步",剩余电量够我把当天最重要的代码写完。

这种"量化→决策"的反馈循环,说实话是我做这个App之前没想到的。我以为记录就是记录,没想到看到数字会真的改变行为。

## 写在后面

如果你也在做 HarmonyOS 开发,或者对 ArkTS/ArkUI 有兴趣,欢迎交流。我踩过的坑不少,特别是 SwiftData 到 relationalStore 的数据层迁移、ArkUI 手势系统的组合用法这些,如果有人感兴趣我可以单独写一篇展开讲。

应用商店搜「元気手账」就能找到。
精力管理思维导图 立即下载

相关推荐

Brim与ZUI协同安装指南:从下载到流量分析实战

本文提供Brim与ZUI协同安装与实战指南,详细讲解从下载、环境变量配置到流量分析的全流程。通过将PCAP文件转换为ZNG格式,结合直观的Zed查询语言,这套组合能极大提升大型网络数据包的分析效率,是网络安全与运维人员进行高效流量分析的利器。

metal的博客 458

Python, C ++开发人体精力管理APP

该方案充分发挥了C++在实时数据处理和Python在机器学习领域的优势,建议采用微服务架构实现模块化部署,同时注意不同语言组件之间的版本兼容性管理。// 10ms采样间隔。├── 服务接口层 (Python) # REST API/GraphQL。FatigueAnalyzer() { /* 初始化C++分析模块 */ }├── 核心算法层 (C++/Python) # 混合计算模型。3. **混合计算框架 (C++/Python交互)**// 使用C++17的异步I/O处理传感器数据。

2501_90802096的博客 765

Allegro中调整差分对等长的步骤介绍

【代码】Allegro中调整差分对等长的步骤介绍。

qq_30882617的博客 3832

软件开发者的精力管理(一)

关注健康,从精力管理开始

大脑与思维的专栏 877

Windows11家庭版开启虚拟化与WSL安装操作手册

Windows 11 家庭版完全支持 WSL 2,无需升级到专业版即可享受 Linux 开发环境。通过本手册介绍的步骤,您可以顺利安装和配置 WSL,并掌握系统更新后的维护技巧。WSL 为开发者提供了在 Windows 环境下使用 Linux 工具链的便利,尤其适合需要跨平台开发的场景。随着使用深入,您会发现 WSL 生态系统的强大之处,它不仅能提高开发效率,还能让 Windows 用户体验到 Linux 的强大功能。建议定期查看微软官方文档,了解 WSL 的最新功能和最佳实践。

m0_54846764的博客 3018

R语言caret拟合模型:train函数构建xgBoost Dart模型、模型调优、自定义设置trainControl函数和tuneLength参数

R语言caret拟合模型:train函数构建xgBoost Dart模型、模型调优、自定义设置trainControl函数和tuneLength参数

statistics+insight+vista+power 528

05 · OpenStack的对象存储 Swift——海量静态数据的“无限仓库“

本文系统解析 OpenStack Swift 对象存储,厘清其与块、文件存储的本质区别:面向永久静态数据(如镜像、图片、备份)的长期存储,采用最终一致性模型。核心为 Account→Container→Object 三级结构,容器不支持嵌套,通过对象名前缀模拟目录。依托三类 Ring(Account/Container/Object)实现分布式定位,基于一致性哈希与副本机制保障高可用与无限扩展。实验环节可完成加盘、分区、挂载及 Ring 构建,验证多副本落点。对比华为 OBS、Ceph 等,凸显其在海量非结

路漫漫其修远兮,吾将上下而求索 568

UG NX二次开发(C#)--详细讲述编程模板NXOpen_CS_Wizard的代码意义,帮你轻松进入NXOpen(C#)二次开发

有几个读者私信问我,在看了“NX1957在VS2019上二次开发的环境配置”后,能完成了UG NX二次开发(C#)模板的配置,也能根据模板创建工程,但是对工程文件.cs不甚理解;并且,在UG Styler新建完成后,其也有一个dlx文件和.cs文件,也不清楚怎么使用。本文先对UG NX二次开发(C#)模板文件进行讲解,在下一个博客中,讲解Styler新建后的模板文件。以上就是对编程模板NXOpen_CS_Wizard(c#)的讲解,其实只要明白了逻辑关系,编程实现只是时间问题,祝你好运。

GimiGimmy 1785

编译期常量不是 Dart 专有的概念

Dart 中的“编译期常量”指在编译阶段即可确定值的常量,如 const secondsPerHour = 60 * 60。此类常量无需运行时计算,而 final 变量可在运行时初始化,如 final startTime = DateTime.now()。const 要求初始值为编译期常量,不可变;final 不限于编译期,但初始化后不可修改。类似概念见于 C++ constexpr、C# const,Swift let 则更接近 Dart final。

侯仕奇的博客 200

uniapp - 详解APP端免费人脸识别+人脸核身+人脸对比+活体检测插件功能完整源码,uniAPP纯前端实现不依赖后端API接口或第三方付费人脸识别功能示例(仅兼容安卓app与苹果ios App)

uniapp免费人脸认证功能,uniapp APP开发活体人脸识别,UniApp人脸识别与活体检测,人脸核身uni-app插件 活体检测 人脸对比 人脸识别 人脸认证 身份证件,uni-app人脸核身,如何在app端实现免费人脸识别教程,人脸核身uni-app插件活体检测,uniapp安卓ios百度人脸识别、活体检测、人脸采集APP原生插件,详细实现人脸识别和活体检测功能,实时监测人脸是否进入区域及动作是否正确播报,提供提供实名认证、身份证识别、有没有免费的,api,活体检测,人脸信息采集、刷脸扫脸认证示例

🏆 前端领域优质创作者 4382

YOLO26改进 - 注意力机制 | ParNet并行子网络:多分支协同优化特征表达,增强模型判别能

本文介绍了ParNet注意力机制及其在YOLO26中的应用。ParNet注意力通过并行子网络结构,将网络层组织成多个子网络并行处理输入特征,降低了传统注意力机制在处理长序列时的计算复杂度。该机制采用VGG风格的块和特征融合策略,具有低深度高性能、参数效率高、可扩展性强和并行化能力好等创新点。我们将ParNet注意力引入YOLO26,在检测头部分应用该机制。通过实验训练改进后的模型,有望提升YOLO26在目标检测任务中的性能。

魔改工程师的博客 443

Flutter 可以更直接地调用原生 API 了,Dart Direct Native Interop

以前 Dart 层的没有用包装函数可以被 Tree Shaking 删除,但 Native Library 需要整体打包,现在配合 Link Hook 和支持裁剪的原生工具链,就可以进一步剔除没有用到的 Native Symbol,从而优化产物大小。这对依赖 SQLite、加密库、音视频库的插件也有意义,不过它需要相应的构建和链接配置,不是说升级 Dart 后任何原生库都会自动完成裁剪。2024 年:Dart 3.5 开始在完善 C、Java、Kotlin、Objective-C 的直接互操作能力。

恋猫de小郭的博客 263

UG\NX二次开发 获取对象的引用集

获取对象的引用集,一个对象可能有多个引用集,下面这个封装函数可以获取对象的所有引用集。

王牌飞行员_里海的博客 489

腾讯云国际充值未到账:从汇款附言到入账匹配的排查顺序

腾讯云国际站电汇充值没到账,原因大多不在"钱丢了",而在附言没写账号 ID、金额或币种与订单不符、中转行扣费造成短款、款项挂在待认领状态、重复提交触发风控。本文按从提交到入账的实际链路给出一张排查顺序表,每步附上现象、判断依据和对应动作,并说明工单该怎么写才不用来回三轮。

aolicloud的博客 379

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Ceph 对象存储(RGW)与文件系统(CephFS)管理

本文系统介绍Ceph对象存储(RGW)与文件系统(CephFS)的管理机制。重点阐述RGW的realm、zonegroup、zone多站点架构,涵盖S3/Swift接口部署、用户管理、配额控制及跨区域复制;CephFS部分则详解MDS元数据服务、池创建、Kernel/FUSE挂载、目录授权、快照与镜像功能。结合实际命令演示配置验证流程,全面展示两大存储接口在云环境中的应用能力。

xianyuCcCcCCCcc的博客 210

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Swift 对象存储建环实验 + Ceilometer 计量:两个收尾服务

来源:《OpenStack 管理手册》对象存储章节 + PPT《09 OpenStack 计量管理》。Swift 之前只讲过概念(三兄弟、三大关键技术),这篇补上真正的重头——:给 Swift 加盘、建 Ring、验证多副本。Ceilometer 只有理论,一节讲透。

xbzb的博客 222

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

快速消失的硬盘容量 -- 肘子的 Swift 周报 #160

Swift Optional 技巧、Instruments 排查 SwiftUI 重绘、iOS 27 Now Playing 框架、iPhone Duo 折叠屏适配、Agent 并行环境隔离

weixin_45801973的博客 228

HarmonyOS 7 端侧 AI 图像超分的工程化落地

用户抱怨网络差的时候图片传不上去,更严重的是,大量的私密照片上传到云端,引发了严重的隐私合规审查危机。痛定思痛后,我们决定把 AI 模型直接塞进手机里,用端侧的 NPU 来做推理,但这绝非易事。我们首先在服务端对模型进行了知识蒸馏,把参数砍掉了一大半,然后利用 MindSpore Lite 的转换工具,将模型转成了鸿蒙底层支持的。即便如此,模型依然有 20 多兆,我们最终选择了 FP16 量化,牺牲了极其微小的画质,换取了内存占用减半。推理过程极其消耗 CPU 和内存,稍微大一点的图,处理时间长达几秒。

2602_97267507的博客 156

〖物流终端实战 05〗纯血鸿蒙 ArkTS 高阶性能优化:长列表渲染、组件复用与内存泄漏排查

本文深度剖析鸿蒙ArkTS高阶性能优化,直击长列表卡顿与内存泄漏痛点。针对渲染,指出ForEach全量构建的缺陷,强调采用LazyForEach(V2推荐Repeat)配合增量通知及稳定业务Key;针对组件复用,明确@Reusable仅复用实例不重置状态,必须在aboutToReuse中手动清理UI状态;针对内存泄漏,总结全局监听未注销、定时器未清理及长生命周期对象持有页面引用三大元凶,并指导通过DevEco Profiler的Heap快照排查引用链。文章强调优化需遵循“先定位后改代码”原则,助力开发者打造

Eyf • 半字节的博客 634

AppGallery 上架自检 SOP:签名、隐私对齐与包体校验实战【鸿蒙心迹】

上架被驳回多因签名、隐私声明与包体不一致。本文提炼“签名→隐私对齐→包体校验”自检SOP,配套一键脚本与权限三角校验代码,实现90%驳回前置拦截。通过CI强制release签名、代码/声明/功能三者权限对齐、包体完整性校验,确保提审一次过。实战清单可直接抄,让过审从运气变为流程。

wdracky的专栏 311

【鸿蒙专题与实战】测试体系:单元测试、组件测试与 UI 测试

本文系统讲解鸿蒙开发中的三层测试实践:底层单元测试(用Hypium框架,优先覆盖纯函数、边界与异常)、中层ViewModel逻辑、顶层仅测3-5条关键UI路径。强调测试应“越往下写得越多”,因单元测试快且成本低,而UI测试慢易出错。通过实例说明断言拆分提升定位效率,结合覆盖率报告(hvigorwtest --coverage)发现盲区,核心是“用覆盖率找漏测,而非追求数字”。附五步落地清单:建测试文件、按优先级补用例、精简UI测试、生成报告、定位未覆盖行。下一篇将开启实战项目:从需求到上架全流程。

信息安全领域优质创作者|操作系统领域专家 162

窗口销毁了监听还在,HarmonyOS 7 生命周期释放的归属分界

综上所述,onWindowStageWillDestroy 是窗口监听的最后安全出口,onWindowStageDestroy 只负责断开窗口引用,onDestroy 管 Ability 级资源——三者不是“程度不同的退出回调”,而是各自有明确的归属范围。窗口监听的所有者是 WindowStage,定时器的所有者是 UIAbility,播放器的所有者是页面或 Ability(取决于你在哪一层创建的),ApplicationContext 监听的所有者是 Ability 的 context。

qq_61905492的博客 197

鸿蒙平板能当电脑第二块屏幕吗?ToDesk、向日葵镜像/副屏实测

本文对比测试了ToDesk鸿蒙版4.8.3.0与向日葵鸿蒙版16.8.0在连接鸿蒙平板作为电脑副屏的表现。结果显示,ToDesk可直接实现镜像屏与扩展屏功能,支持参数调节,操作流畅;而向日葵副屏需开通会员才能使用。对于已有鸿蒙平板的用户,ToDesk能有效拓展工作空间,提升多任务效率,尤其适合临时办公、出差等场景,具备较高实用价值。

2501_91062530的博客 2313

React Native for OpenHarmony 实战:react-native-file-logger 日志库鸿蒙化适配

本文记录了将 react-native-file-logger 适配至 OpenHarmony 的实战过程。基于鸿蒙 7.0 模拟器,通过 5 个 TurboModule 方法实现日志落盘、轮转、列举与删除,采用 fileIo 实现核心功能,支持按大小和跨天轮转,归档文件命名精确至毫秒。邮件发送功能因平台限制按能力边界处理,明确拒绝并提示用户手动导出。验证通过,日志文件结构清晰,内容完整,产出 HAP 示例与独立 HAR 库,中英双语文档齐全,为鸿蒙应用日志管理提供可靠方案。

m0_62930060的博客 233

【鸿蒙心迹】深色模式适配全链路——从配置到自定义(HarmonyOS 7.x)

系统切深色模式,应用没跟着变;图片在深色模式下刺眼;自定义绘制颜色没适配——深色模式不是"换个背景色",是颜色/图片/材质/状态栏的全链路适配。本文用涟漪睡眠 App 适配深色模式为案例,给完整方案与 5 个踩坑。

腾讯云创作之星、华为云云享专家,深耕电商全栈高并发系统实战,分享可商用商城项目源码。 361

【共创稿事节】HarmonyOS 7.0 Marquee跑马灯:从接入到生产验证

HarmonyOS 7.0 Marquee跑马灯:从接入到生产验证:真实工程复盘,附代码与验证方法。

2401_84996024的博客 160
上一篇: 我做了一款鸿蒙原生加密App,加密后的密文看起来就是一段正常中文
下一篇: 独立开发一款呼吸训练App:自适应帧率降级、hilog性能分析与课程状态机设计
SameX-4869
博客等级 码龄17年 3354粉丝 657原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值