DevLog:2026年1月22日

1、截至目前,四款应用问题如下,加粗内容暂未修复:

1.DoitWith

-首次启动应用时无需生成示例数据

-设置-已完成 Todo,数据统计不正确

-已完成Todo页面同样以分组形式显示,需要能看到Todo原本所属的分组

-已过期的Todo需要在显示上有所差异,比如标题用红字

-设置-关于卡片最下方增加版本号信息,先用v0.1.0,居中显示

-按住拖动调整排序的功能无法正常使用

-不包含任何Todo的分组下会显示“该分组暂无待办”,但底下还有半截分隔线,需要和正常的Todo条目下的分隔线格式一致

2.ChatWith(目标是对齐ChatWith for Mac)

-清除后台后,再打开应用秒闪退,无法使用

-在与支持深度思考的模型对话时,看不到思考内容,我需要增加一个展示思考内容的区域,默认折叠,可以点击展开,并且显示样式要和回答内容有所区别(两轮修改后已有思考内容区域,但看不到具体的思考内容)

-发送消息后立刻显示在对话界面内,现在好像是在AI有响应后才会显示

-虽然可以看到Tavily已经联网获取了一些链接,但AI回答内容好像没有结合Tavily搜索结果

-不要给所有填写了Tavily Key的模型自动开启联网搜索功能,改为由用户自行开启/关闭联网搜索功能

-发送按钮上方设置联网搜索开关,并调整布局,拉高消息框,右侧放竖向排列的联网搜索开关和发送按钮

-对话列表中显示的标题是用户的第一个问题,需要改为用户的最后一个问题

-参考链接区域版式优化,目前的链接间距太近,想点开某条时容易点错

-点击对话界面右上角弹出选择模型界面,每个模型的信息分成四行,备注、模型名称、是否支持联网,是否支持深度思考

-长按消息(包括用户消息和AI消息)可弹出菜单,菜单中包含复制、收藏、删除 三个按钮,其中在AI消息上长按点删除时要同步删除思考过程、回答内容和参考链接

-消息(包括用户消息和AI消息)的时间显示有问题,现在只显示时:分,看不到是哪天,当天的消息可以只显示时:分,最近的消息显示昨天、前天、几天前,较早的消息显示完整日期+时:分

3.ChatWith for Mac

-关于页面的“初始版本发布”放到最上边

-优化上传附件和图片后的显示效果,比如取消附件和图标的红叉需要改小一些

4.DoitWith for Mac

-询问并调整数据持久化方式

-界面优化,以卡片形式呈现每条Todo

-增加“下一步”功能,和DoitWith移动版采用相同的完成Todo逻辑

2、继续优化ChatWith,之前遗留的几个问题暂时搁置,本轮修改主要针对以下几点:

1.不要给所有填写了Tavily Key的模型自动开启联网搜索功能,改为由用户自行开启/关闭联网搜索功能

2.发送按钮上方设置联网搜索开关,并调整布局,拉高消息框,右侧放竖向排列的联网搜索开关和发送按钮

3.对话列表中显示的标题是用户的第一个问题,需要改为用户的最后一个问题

4.参考链接区域版式优化,目前的链接间距太近,想点开某条时容易点错

5.点击对话界面右上角弹出选择模型界面,每个模型的信息分成四行,备注、模型名称、是否支持联网,是否支持深度思考

3、Composer 1模型的修改速度一流,涉及了五个文件,连接真机测试,1已实现,2消息框的高度没有变,可输入区域还是只有一行,右侧已有联网搜索开关,3对话列表里的标题已可显示用户的最后一个问题,但点开对话之后顶部的标题还是第一个问题,需要统一成最后一个问题,4参考链接之间的间距可以适当缩小一些,5已实现,另外在设置-模型管理界面,每个模型的信息也和刚刚修改的选择模型界面一样分为四行:备注、模型名称、是否支持联网、是否支持深度思考,继续让Cursor修改

4、本次修改Cursor针对消息框设置了最多5行的显示高度,设置了最大高度为120,对话列表和对话页面标题保持一致,将参考链接间距由上次修改的12改为8,并且调整了模型管理页面,与模型选择界面保持一致,真机测试,其他问题都已解决,但输入框仍然只显示为一行,另外再调整下添加模型和编辑模型页面,现有的五个字段都必填,并且把“备注”挪到最前边,提示“起个简单好记的名字吧”

5、针对添加模型和编辑模型页面,Cursor在调整字段顺序的同时,给备注、API Key、Tavily Key字段添加了必填验证,不过Tavily Key字段其实不用必填,再次改了下,针对输入框的高度,截了一张ChatWith for Mac的输入框的图,并让Cursor参考调整了输入框的高度,但测试发现依然未能实现想要的效果,决定将联网搜索按钮从目前的位置挪出来,浮在输入框的上方,居左显示,带有提示文字,另外,在添加模型和编辑模型界面,备注字段的输入框高度和其他几个字段高度保持一致

6、再次真机测试,需求已实现,继续优化,除上述未解决的问题之外,在对话界面还要增加如下功能:

1.长按消息(包括用户消息和AI消息)可弹出菜单,菜单中包含复制、收藏、删除 三个按钮,其中在AI消息上长按点删除时要同步删除思考过程、回答内容和参考链接

2.消息(包括用户消息和AI消息)的时间显示有问题,现在只显示时:分,看不到是哪天,当天的消息可以只显示时:分,最近的消息显示昨天、前天、几天前,较早的消息显示完整日期+时:分

7、测试发现上述需求已实现,发现回收站还有一个问题,目前设置-回收站-收藏内容里会显示我删除的每一条对话内容,这里应该只显示我删除的收藏内容,经过一次修改后我才注意到,每条收藏只有复制、取消收藏两个选项,点取消收藏后,这条内容就会从收藏列表消失,不会进入回收站,需要将“取消收藏”改成“删除”,点击即进入回收站-收藏内容里,并且可恢复到收藏列表、可永久删除,这样才合理,在修改过程中,Cursor出现了反复使用同样的命令行的循环,打断之后虽然出现了构建错误,但再次反馈问题并重新生成代码、运行pod install之后,应用可正常构建,并且删除收藏/恢复收藏的需求也已达成

8、发现真机测试的效率真的比模拟器测试要高很多,而且更符合真实的使用场景,毕竟在Mac上用鼠标操作iOS应用还是不太符合使用手机的习惯,而且模拟器和手机的性能表现也很不一样,在模拟器上有些卡顿的功能,在真机上使用却会很流畅

9、然后将ChatWith for Mac的模型服务商列表截图给Cursor,让它给添加模型和编辑模型界面增加常用的提供商,实现自动填充Base URL的功能,同时保留自定义选项,可以手动输入Base URL,修改之后替换了下百度云千帆的链接,此需求已达成

10、然后是设置-数据统计页只需要保留AI对话和收藏内容两个卡片就行,不要再套一层卡片(外层Card包装),另外设置页底部增加一个“关于ChatWith”卡片,大字显示应用名“ChatWith”,第二行小字“Any AI LLM you like.”,第三行是版本号“v0.1.0”,这三行信息都居中显示

11、至此ChatWith的修改暂告一段落,继续修改DoitWith,需求包括:

1.首次启动应用时无需生成示例数据

2.设置-已完成 Todo,数据统计不正确

3.已完成Todo页面同样以分组形式显示,需要能看到Todo原本所属的分组

4.已过期的Todo需要在显示上有所差异,比如标题用红字

5.设置-关于卡片最下方增加版本号信息,先用v0.1.0,居中显示

12、也用Composer1模型进行修改,修改点包括修改TodoData.swift以移除自动创建示例数据的逻辑,修改SettingView.swift中的统计逻辑,修改CompletedTodosView.swift以按分组显示已完成的Todo,修改TodoRowView.swift和GroupTodoRowView.swift以添加过期检查逻辑,修改SettingView的关于部分,之后开始真机测试,上述需求的2、3、4、5均已实现,1可能需要在另一台手机上测试

13、然后检查一下目前应用都在哪些地方规定了版本号,可否只在一处填写版本号,在其他地方调用该处的版本号信息?针对这一需求,Cursor创建了AppConfig.swift文件来集中管理应用配置信息,规定了版本号优先从Bundle读取(Xcode项目中的MARKETING_VERSION),如果无法读取则使用默认值“v0.1.0”,同时提供了构建版本号的读取方法,然后将刚刚增加的设置-关于板块的硬编码版本号改为从项目配置中读取,这样就实现了版本号只在一个地方定义,并自动同步到使用版本号的地方

14、不止一个地方提到了“版本号”和“构建版本号”两个概念,询问了下ChatGPT,简单说就是版本号Version是给用户看的,构建版本号Build是给系统/开发者/审核看的;版本号表示产品层面的版本,如果用三位数(比如1.0.1)的话,三位数分别代表主版本号、次版本号、修订号,分别对应大版本、功能更新、Bug修复,构建版本号表示技术层面的“第几次打包”,每打一次包,就应该不一样,同一个版本号,对应的构建号必须递增,且不能重复;举例说,日常开发版本号可能是1.0.0+1,有功能更新时版本号可能是1.1.0+10,大版本发布时版本号可能是2.0.0+1,后续可以按照这种方式来管理版本,更加规范一些

15、针对DoitWith for Mac的数据持久化方式,首先让Cursor检查了下,受到以前有AI对话和笔记板块的影响,目前实际使用的是UserDefaults+JSON编码(TodoItem和TodoGroup通过JSON序列化存储在UserDefaults,每次修改都会序列化整个数组并保存),CoreDataManager已经初始化但实际未使用,而且数据模型中还保留着已经删除功能的实体(AIMessage、AISession、AIModel、Note);目前存在的问题有些多,比如Core Data已经初始化但未使用,造成资源浪费,数据模型包含已删除功能的实体,需要清理,UserDefaults不适合存储大量结构化数据,性能较差,每次保存都要序列化整个数组,数据量大时会有性能问题

16、针对上述问题,Cursor建议了三个方案,一是完全移除Core Data以简化架构,减少资源占用,降低维护成本;二是迁移到Core Data,性能好,支持大量数据,支持复杂查询/排序/过滤;三是使用SwiftData,具备更现代的API,与SwiftUI集成更好,代码更简洁,可自动处理数据同步,ChatGPT强烈推荐使用SwiftData(苹果在WWDC23推出的Core Data现代化封装,语法极简,学习成本低),认为它能最大化开发效率,同时不牺牲未来扩展性,让待办类工具使用Core Data有些“杀鸡用牛刀”,决定采纳ChatGPT的建议,使用SwiftData

17、Cursor认为TodoItem、TodoGroup这种业务数据可以使用SwiftData,界面设置和外观设置等配置数据可以继续使用UserDefaults,明天按照Cursor的建议修改下DoitWith的数据持久化方式,后续DoitWith移动版也考虑将Core Data换成SwiftData,ChatWith和ChatWith for Mac已经使用Flutter重制,不涉及Core Data或SwiftData

DevLog:2026年1月20日

1、继续测试昨天对DoitWith的完成Todo逻辑的修改效果,目前已经实现如果一个Todo中有多个下一步,点击完成按钮会先完成下一步,如果一个Todo中没有下一步,点击完成按钮会完成整个Todo的功能,但仍有两个问题,在编辑有“下一步”的Todo后,这条Todo会被分类到General中,而不是保持在原本的分组,另外已完成的Todo就不要再显示在首页的Todo列表里了,只显示在“已完成”页面就行

2、Cursor在修改过程中调整了编辑时的分组逻辑,如果在编辑时选择了分组,且与当前分组不同,才更新分组,如果在编辑时没有选择分组,且原来有分组,那就移动到General,如果原来就是General,那就保持在General,针对第二个问题,添加了过滤条件,已完成的Todo只会显示在“已完成”页面,即CompletedTodosView

3、再次构建测试,发现点击完成一条Todo后,已完成页面仍然是空的,看不到我刚刚完成的Todo,继续修复,Cursor表示修复后会直接从CoreData查询所有已完成的Todo(包括Genral和分组中的),并且按创建日期降序排列,在已完成视图出现时自动刷新,显示最新的已完成Todo

4、再次构建测试,发现在添加Todo——点击完成Todo或完成下一步时,会有一条之前已经完成的Todo变回未完成状态,出现在Todo列表里,即已完成的Todo被重置了,反馈给Cursor修改,Cursor认为这是因为重新排序时没有排除已完成的Todo,导致已完成的Todo的order被错误地重新赋值,可能会影响已完成的Todo的状态

5、再次测试,以上问题已解决,接下来对界面布局进行一些调整:

1.搜索栏挪到顶部,“添加”按钮放在搜索栏右侧

2.待办、已完成、设置 三个按钮放在底部,点击可切换至对应界面

3.设置界面底部增加“关于DoitWith”板块,展示应用名DoitWith和副标题(Manage things with next steps)

6、修改过程中,Cursor创建了MainView(底部导航栏),使用TabView管理三个页面,并修改了TodoView(搜索栏和添加按钮)、CompletedTodosView(改为Tab页面)、SettingsView(添加关于板块),更新了ContentView(将TodoView替换为MainView,使用新的底部导航结构),由于项目使用了PBXFileSystemSynchronizedRootGroup,Xcode会自动检测并包含DoitWith文件夹中的新文件,所以刚刚创建的MainView就不需要手动更新到项目中了

7、构建测试,已实现上述界面调整需求,但在待办界面,搜索栏和顶部的“待办”、下方的快速导航栏之间的间距有些大,需要稍微改小一些,Cursor同步调整了搜索栏与导航栏之间、搜索栏与快速导航栏、快速导航栏与第一个分组之间的间距,再次构建测试,界面比之前稍微紧凑了一些,基本达成需求

8、接下来给DoitWith添加图标,使用ChatGPT创建图标包,指令是“我有一个待办类iOS应用,叫DoitWith,我需要给它加上图标,你先帮我创建一张1024*1024的底图,格式要符合iOS应用对图标文件的要求,颜色和DoitWith的启动页面颜色保持一致(red: 27/255, green: 94/255, blue: 32/255),需要稍微有一点创意,同时保持简洁”

9、ChatGPT给了我两张图,但都不是很满意,元素和色彩都稍微有点多,并且还出现了“图标套图标”的问题,虽然主体基本可用,但还有一个明显的“内层圆角块/底座”的感觉,在裁切成图标文件后就会像是套了一层,为了让图标更简洁,多次跟ChatGPT对话,去掉了内层圆角容器的感觉,并且微调了色彩,生成了图标包,放到Assets.xcassets文件夹里之后,应用图标搞定

10、ChatGPT还提示我可以在真机上测试时注意看桌面、Spotlight搜索结果、设置App列表这三个位置里的图标是否干净、清晰、锐利,如果都OK,那就可以长期使用

11、我发现目前应用在一些界面上还存在英文提示,比如搜索页未搜索到结果时的提示、Todo的日期信息(月份)、点击完成Todo时的弹窗提示等,需要改成对应的汉字,让Cursor排查下还有没有其它地方要改,但启动页、设置-关于页中的英文不要改,Cursor修改了TodoView中的提示文本、弹窗按钮文本、日期格式化、导航标题(我又让改回去了),以及General分组的名称,另外添加Todo和编辑Todo界面里的日期选择器还是英文的,反馈后Cursor给这两处增加了locale环境变量,这样DatePicker就会使用中文界面,构建测试,需求达成

12、接下来暂时不增加新功能,昨天询问了如何在真机上测试iOS App,Cursor指出这种方式只要有Xcode+Apple ID就可以,不需要通过TestFlight,也不需要上架,步骤包括用数据线把iPhone连到Mac、在Xcode中打开项目、设置签名、选择真机为运行设备、点击RUN等,并且我有已付费的开发者账号,通过这种形式进行测试时不会有7天过期的限制

13、按照ChatGPT的提示连接自己的手机进行测试,发现ChatGPT少写了一步,在选择真机为运行设备前,需要在手机的设置中打开开发者模式

14、想用同样的方法把之前使用Flutter重构的ChatWith移动版安装到手机上,但我发现目前的ChatWith移动版在模拟器中安装后,面上显示的是Flutter的图标,名字叫Chatwith Flutter,于是让Cursor修改了应用的名字(将Info.plist中的CFBundleDisplayName由Chatwith Flutter改为ChatWith),并且用ChatGPT制作了图标包(18张,包含Contents.json),替换了原来的Flutter图标

15、然后连接手机并且在手机上运行ChatWith,首次启动时竟然出现了“允许ChatWith查找本地网络中的设备?”的提示,为啥功能这么简单的应用居然会有这种权限要求呢?

16、到目前为止,已经把ChatWith for Mac(使用Flutter重构)安装到了电脑上,并且把ChatWith(使用Flutter重构)和DoitWith(使用SwiftUI原生开发)移动端安装到了电脑上,接下来在日常使用中测试一段时间,并修复使用中发现的问题

17、同步开发DoitWith for Mac,在之前的NoteWith for Mac基础上修改,之前已经有了对话、笔记、Todo三个板块,功能比较杂乱,也不太符合实际的使用需求,让Cursor简化当前应用的功能,去掉对话和笔记功能,并且将应用名称和所有的NoteWith都改成DoitWith,这个应用今后也尽量只用SwiftUI原生开发

18、Cursor陆续进行了这些操作:删除AI对话和笔记相关的文件,更新ContentView、SearchWindowView、RecycleBinView、DataManager等文件以移除AI和笔记功能,将所有文件中的NoteWith重命名为DoitWith,重命名项目文件夹和配置文件,更新项目配置文件等等,几分钟时间完成

19、构建测试,需要重新在Xcode中打开项目文件,并且让Cursor修正了CoreDataManager.swift路径配置错误、应用已删除的文件等多个问题,主要是清除已经删掉的AI对话、笔记相关功能代码,终于可以顺利构建

20、首先调整了最左侧栏、待办分组栏的宽度设置,最左侧栏固定为200,待办分组栏固定为300,并且禁止用户拖动调整宽度,然后我发现在Xcode中,当前项目好像仍在引用MarkdownUI,但涉及这个依赖的AI对话、笔记功能已经都删掉了,让Cursor从项目文件中移除对MarkdownUI的引用,重新构建、功能正常

21、明天开始,在使用并记录ChatWith for Mac、ChatWith、DoitWith的问题的同时,持续优化DoitWith for Mac,包括修改数据存储方式、增加下一步功能、调整界面、增加图标等等,之前使用SwiftUI开发的NoteWith移动版暂时搁置

DevLog:2026年1月19日

1、上周参考ChatGPT的建议,给DoitWith增加了“下一步”功能,用于记录工作流程,同时调整了部分操作方式和界面细节,构建测试,发现问题如下:

1.应用内的示例Todo无法修改内容,标题、下一步、日期、重复在修改之后保存,均未生效

2.修改新建的Todo时也无法生效

3.删除示例Todo后,第一次删除会被归类到General,第二次删除后仍然在General里,同时回收站中也有同样的条目,应该是在删除之后直接进入回收站,不应继续存在于Todo列表中

2、Cursor在修改过程中指出问题1和2是由于EditTodoView只更新内存数组,未更新CoreData导致的,问题3是因为分组信息未能正确获取,并且删除后要调用loadFromCoreData()重新加载,确保列表更新,再次测试,已经可以正常保存修改,但删除后仍然会被归类到General分组,继续反馈给Cursor修改

3、Cursor认为这是因为删除时创建的todoCopy被当做正常Todo出现在列表中,在删除Todo时,需要从CoreData中删除原始TodoEntity,并创建DeletedTodoEntity,保存到回收站,修改后再次测试删除功能也已正常

4、然后和Cursor明确“完成Todo”的逻辑,如果一条Todo未添加下一步,点击完成按钮时就直接完成整条Todo,如果添加了下一步,点击完成按钮时就完成下一步,所有下一步均完成后,才会完成整条Todo,另外,在添加和修改Todo时,下一步的输入框里不要提示下一步1、下一步2,只显示“下一步”就好

5、突然想起来上周发起的4个Archive任务,打开看了下4条都已经通过了Notary,目前的状态都是Ready to distribute,第4条没有任何的问题,全部绿色,前3条都有黄色的提示信息“Unable to find API request response with task ID for GET submissions”,询问ChatGPT得知,这是Xcode(Organizer/Notary UI)在向Apple Notary服务拉取公证日志(log)时失败了,常见的原因包括Apple服务端短暂异常/延迟、网络或代理导致请求被拦截、或Xcode UI的偶发BUG(任务其实已经在处理/已完成,但UI拉日志失败),怀疑可能是因为公司网络质量差导致的

6、接下来尝试用命令行形式将.app制作成.dmg,包括安装create-dmg——进入.app所在目录——生成DMG——公证DMG——Staple等步骤:

1.安装create-dmg:

brew install create-dmg

2.进入.app所在目录(在Archieve中导出时选择导出到桌面,不要cd进.app里面):

cd ~/Desktop

3.生成DMG:

create-dmg \

  –volname “chatwith” \

  –window-size 800 400 \

  –icon-size 120 \

  –icon “chatwith.app” 200 190 \

  –app-drop-link 600 185 \

  “chatwith.dmg” \

  “chatwith.app”

4.公证DMG:

xcrun notarytool submit chatwith.dmg \

  –apple-id wujinlei51@gmail.com \

  –team-id 6UY94UFR36 \

  –password xzfg-rgmk-niks-ehtt \

  –wait

5.Staple:

xcrun stapler staple chatwith.dmg

最后一步收到The staple and validate action worked!的提示之后,就说明公证票据已经成功“钉”进chatwith.dmg,即使离线,Gatekeeper也能验证,到此完成,今晚换另一台电脑安装测试

7、继续前边对DoitWith的修改,主要是明确完成Todo的逻辑,并调整下一步输入框的提示文字,针对完成Todo的逻辑,需要修改CoreData模型、修改Todo结构体、修改完成Todo的逻辑,并修改TodoRowView和GroupTodoRowView显示下一步完成状态,Cursor在进行这些修改的同时,增加了一个针对编辑Todo的功能:在EditTodoView中,当修改nextSteps时,会自动过滤掉超出范围的已完成索引,明天测试一下这个功能具体是指什么

DevLog:2026年1月16日

1、参考昨天ChatGPT的建议,结合我的日常使用需求,将DoitWith调整成一款用于记录工作流程的工具,并且还有一些界面上的调整需求,包括:

1.每一条待办都可以添加多个“下一步”,创建和修改待办时都可以添加,默认显示两个“下一步”,也可以点击按钮添加更多“下一步”,去掉现有的“描述”字段

2.在首页列表里,待办的标题下方显示“下一步:下一步的具体内容”

3.主界面右上角,在目前已有的“设置”、“新建”两个按钮的右边,增加“已完成”按钮,点击可以在弹出的页面中查看已完成的待办

4.两条待办之间的间距缩小一点,紧凑一些,现在一屏只能容纳4条待办

5.目前当需要编辑或删除待办时,需要长按条目触发菜单,修改一下操作方式,改成向左滑动,在待办条目右侧显示编辑、删除按钮

2、另外结合过往的经历,iOS应用应该都会遇到数据永久化方式的问题,ChatGPT建议,如果只做轻量待办,UserDefaults够用,若想做出更多功能,比如搜索、统计、节奏、多端同步(iCloud)、复杂重复,CoreData会更合适,而且能成为“可持续迭代”的底座

3、长痛不如短痛,先让Cursor评估一下当前版本哪些数据适合用CoreData,哪些数据适合继续用UserDefaults,Cursor创建了详尽的存储方案评估.md文件,建议将Todo数据(数量会增长,需要复查查询,与分组有关联关系)、TodoGroup数据(与Todo存在一对多关系,CoreData管理关系更稳妥)、DeletedTodo数据(回收站数据可能累计,可通过CoreData做定时清理)迁移到CoreData,至于appColorScheme可以继续使用UserDefaults(配置简单、集成方便)

4、先按照Cursor的建议将Todo数据、TodoGroup数据、DeletedTodo数据迁移到CoreData,具体步骤包括创建CoreData模型文件(.xcdatamodeld)定义实体和关系、创建CoreData Stack、重写TodoData类,实现数据迁移逻辑、更新项目文件(添加CoreData模型文件引用)、更新DoitWithApp.swift,初始化CoreData等

5、完成一轮修改后,发现又忘了要求Cursor不要给应用添加“首次启动时自动从UserDefaults迁移到CoreData”的功能,因为当前版本还没有对外发布,另外在创建多个新文件后,项目文件好像还没有更新,再次反馈检查并去掉迁移逻辑(移除了migrateFromUserDefaultsIfNeeded()方法),至于项目文件,Cursor认为理论上不需要手动更新project.pbxproj,因为项目使用了PBXFileSystemSynchronizedRootGroup,Xcode会自动同步DoitWith文件夹中的文件

6、在Xcode中构建测试,TodoData.swift出现了三处警告一处错误,修正后可以正常构建,功能也基本正常

7、回到今天最初的需求,让Cursor调整应用的功能,调整部分界面和交互方式,本次修改涉及更新CoreData模型、更新Todo结构体、修改AddTodoView和EditTodoView、修改TodoRowView、修改部分界面等,修改小问题后可正常构建,但会卡在启动页面,提供调试信息后Cursor指出这是因为代码还在尝试访问已从CoreData模型中移除的descriptionText属性,导致运行时异常,在移除对descriptionText的访问的同时,添加了“如果nextSteps无法解码或为空,直接初始化为空数组”的规则,下周再测试

8、ChatGPT提出的另一个建议“为macOS/iOS原生体验而生(利用Spotlight、菜单栏快速完成、Live Activity/Widget驱动行动、支持快捷指令等macOS/iOS原生能力)”也可以考虑,既然目前应用使用的是Swift语言,那就把iOS原生的功能,以及界面设计语言充分利用起来,这是下一步的开发重点

9、再记录一个ChatWith for Mac需要优化的细节:

1.关于页面的 初始版本发布 放到最上边

DevLog:2026年1月5日

1、年前对目前的项目进行了盘点,暂定先主要推进ChatWith移动端(已使用Flutter重写)和ChatWith for Mac的开发工作

2、针对ChatWith for Mac,节前要求Cursor进行了微调,以实现“所有网络请求必须在后台线程执行,所有UI更新操作必须在主线程执行”的需求,今天起对应用进行测试,主要看是否还会在切换对话时遇到卡死问题,已经去掉了在对话中切换模型的功能,如果测试没有什么明显的问题就修改设置-关于页面、刷新README文档,并打包,版本号用v0.3

3、对比Chatbox,有几个功能后面还是要加上,比如上传图片、上传文件并由AI进行解读,这两个功能留到后面v0.5时再添加

4、接下来调整一下UI,特别是输入框,目前应用的输入框看不到边框线,且右侧的联网搜索和发送/停止按钮大小不一样,要求Cursor给对话界面的输入框增加灰色边框线,并修改联网搜索按钮,去掉已关闭、已开启的文字,只留图标

5、输入框和按钮的修改基本完成,但总感觉发送/停止按钮和联网搜索按钮大小不一样,且在测试时再次遇到了应用卡死问题,从调试信息来看,对话的输入和输出是正常的,但没有看到UI更新,继续反馈问题给Cursor,修改一次之后卡死问题更加严重,只要打开应用-打开历史对话就会卡死,再次反馈、修改

6、目前打开应用-打开历史对话暂时不会卡死了,但在翻看更早的历史对话消息时又会卡死,要求Cursor添加调试信息来定位问题,同时还询问了豆包,豆包认为所有的耗时操作都不应该放在主线程执行,比如网络请求(之前已经挪到了后台线程)和本地数据读写(涉及DataManager和MessageView等文件),修改之后Cursor指出,虽然Core Data的保存操作必须在主线程执行,但由于使用了异步执行,不会阻塞调用线程

7、再次测试,仍然会出现卡死问题,逐渐失去耐心了,询问豆包,换用 Flutter 完全可以从根源上解决这类卡死问题,且Flutter对「消息列表加载/渲染」的适配性远优于原生Swift,99%的原生卡死场景在Flutter中都能彻底规避;更关键的是,Flutter无需像原生那样做大量「线程切换、异步处理」的繁琐适配,基础写法就自带防卡死能力,开发效率更高

8、开启了一个新对话,决定在新对话中先梳理目前应用的功能,并且用Flutter来重写当前应用,步骤包括创建Flutter项目结构和基础配置、创建数据模型、实现数据层、实现AI服务层、实现视图模型、创建主界面、实现AI对话视图、实现收藏视图、实现设置视图、实现搜索视图、检查并完善所有模型类等等,耗时大概50分钟,中间还中断了一次,点击继续之后Cursor首先查可能了已有文件,了解进度,并逐步完成剩余部分

9、使用Flutter的项目结构包含models-数据模型、services-服务层、viewmodels-视图模型、views-UI视图,之后让Cursor生成了该应用的的macOS平台代码,并且在生成ephemeral文件,并修复编译错误、图标问题后,项目成功构建

10、使用Flutter构建的应用界面稍显简陋,主要的功能板块已经有了,包括对话、收藏、设置三个页面,设置中包含了AI模型管理、外观设置和数据统计,但每个界面右上角都带了一个DEBUG的标志,不知道是干啥用的,先让Cursor去掉它(debugShowCheckedModBanner),同时也问问能否把之前已有的图标文件复制过来一份,继续使用(将Swift版本的图标复制到Flutter版本,并重命名为Flutter所需的文件名格式)

11、修改过程中再次出现了频繁创建.md说明文件的情况,其实我用不到,要求Cusor清理掉

12、目前ChatWith for Mac已经实现了基于Flutter的改写,并且可以成功构建,接下来需要对各个功能进行详细测试和修改,目前已发现的问题包括:

1.在添加和修改模型时,我需要让添加和修改窗口在最前,只有点了取消或确定后才能回到主界面,现在只要一点主界面,添加和修改窗口就会被关闭

2.对话时,点击发送按钮后问题发不出去,没有任何反应

3.设置-外观设置-主题模式中,我需要跟随系统、浅色模式、深色模式三个选项,并且点击选项后可实现对应的主题模式

4.需要增加回收站功能(删除和恢复对话和收藏)和搜索功能(搜索对话和收藏)

5.设置-AI模型管理界面,需要增加删除模型按钮

13、初步修改了一轮之后,发现上面的五个问题里,

1.已解决

2.未解决,发送按钮有时可用有时不可用

3.已解决

4.需要把回收站挪到设置页的数据统计下边,即设置界面共有AI模型管理、外观设置、数据统计、回收站四个功能

5.未解决,AI模型管理界面还是没有删除模型按钮

14、继续修正问题2和问题4,问题2通过添加输入框监听器和_cansend状态变量,已完成修改,问题4主要是在entitlements文件中添加了com.apple.security.network.client权限,允许应用进行网络请求,已完成修改,并且在测试过程中发现之前使用Swift实现的深度思考、流式输出等功能均可正常使用

15、继续修正问题5,通过移除if(config.isCustom)条件判断,改为每个模型后边都会显示删除按钮,解决了问题

16、明天继续修改其他问题,包括:

1.把右上角的搜索按钮挪到最左侧,放在“对话”上面

2.明确对话列表的显示规则,标题直接用用户提出的最后一个问题,下面小字显示最后一次回答的内容,只显示一行

3.对话列表和收藏列表的宽度都固定为300,且不需要拖动调整

4.其他问题视测试情况而定

DevLog:2025年11月4日

补充一条,时间线有点乱了,但还是要记录一下。

1、继续试用ChatWith,发现目前的应用在使用支持深度思考的模型时,思考内容好像限制了显示高度,一旦达到高度限制,就不会随着思考的内容继续自动滚动,Cursor表示思考内容的显示高度的确固定在了400点,且超出之后会出现滚动条,但超过400点后就不会再自动滚动,在修改过程中发现了另一个问题,好像在对话中切换了另一个模型,再提出新问题时应用就会卡死

2、Cursor分析了可能导致应用卡死的几个问题:Core Data并发冲突、通知监听器生命周期、状态读取时序、缺少状态同步,特别是Core Data并发冲突,由于直接在主线程修改Core Data managedobject,如果此时用户立即发送消息,可能造成并发访问冲突,updateAISession可能触发Core Data save操作,与其他操作冲突,明天继续修改这个问题

3、添加其他模型来测试Base URL的填写方法,之前已经要求Cursor将其改为用户手动填写AI服务的跟地址,应用会自动补全路径,比如api.openai.com、openrouter.ai/api,然后针对火山引擎的“应用”(bots)做了特别优化,需要填写完整地址https://ark.cn-beijing.volces.com/api/v3/bots/,测试发现百度云千帆的Base URL填写仍然有问题,比如我填写官网提供的https://qianfan.baidubce.com/v2/chat/completions就会连接失败,删掉v2往后的内容也不行,只填写https://qianfan.baidubce.com也不行,与其设定各种复杂的自动补全规则,倒不如直接要求用户填写完整的Base URL,或者应用内置一些常用的Base URL来的简单

附上常用的几个AI的Base URL:

OpenAI

https://api.openai.com/v1/chat/completions

DeepSeek

https://api.deepseek.com/v1/chat/completions

OpenRouter

https://openrouter.ai/api/v1/chat/completions

硅基流动

https://api.siliconflow.cn/v1/chat/completions

火山方舟

https://ark.cn-beijing.volces.com/api/v3/chat/completions

或

https://ark.cn-beijing.volces.com/api/v3/bots/chat/completions

百度云千帆

https://qianfan.baidubce.com/v2/chat/completions

阿里云百炼

https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions

4、询问Cursor目前应用在Base URL补全方面的规则是怎样的,根据回答内容,规则包括:

1.如果没有http://或https://,就自动添加https://

2.如果URL末尾有斜杠,就自动移除

3.如果已经包含完整路径,就不做任何修改

4.如果包含部分路径,就自动补全,比如补全v1,补全/chat/completions

5.如果只有基础URL,就自动补全/v1/chat/completions

按照这套规则,我填写了完整的百度云千帆的Base URL,应该能正常使用才对,但填写完整地址之后测试仍然提示404

5、问题可能出现在自动补全v1上,也就是在“包含/chat/completions但不包含v1时,会自动添加v1前缀,包含/api/、/bots/、/v3/、/v2/,且不含/chat/时,则添加chat/completions”这里,根据Cursor给出的示例,可能会出现/v1出现在/chat/completions之后的情况

6、目前的规则的确有些复杂,可能用户在填写过程中也会不知道该填写完整的地址还是部分地址,倒不如直接在应用里内置几个常用的、完整的Base URL,由用户自行选择,要求:目前的规则有些复杂,我希望能在添加和编辑AI模型界面,预置几个常用的API平台的完整Base URL,用户只需要填写备注、模型名称、选择模型提供商、填写API Key、填写Tavily API Key即可使用模型

7、Cursor在修改过程中创建了APIProvider枚举,包含10个常用平台(OpenAI、DeepSeek、Anthropic Claude、OpenRouter、Google Gemini、智谱GLM、月之暗面Kimi、百度文心一言、阿里通义千问、腾讯混元、自定义),这样就不再需要配置路径补全规则,用起来也更方便了,先添加几个模型试试,再决定要不要增加或删减APIProvider

8、在修正因为使用中文引号导致构建失败的错误之后,百度云千帆和火山方舟的API都可成功连接,当API提供商选择自定义时,需在“高级设置”的Base URL中填写完整地址,即带有/chat/completions的地址

9、APIProvider需要增加硅基流动、火山方舟、百度云千帆、阿里云百炼,这四个都放在“自定义”前面,另外我发现在选择某个APIProvider之后,模型名称部分也会出现预置的模型名称,但我不需要,改成由用户手动填写模型名称,修改之后测试了几个不同的模型,都可以成功连接了

DevLog:2025年12月19日

1、测试当前版本的ChatWith for Mac,目前已经支持在打开应用后自动开启新对话,并且新对话位于置顶对话下方,之前已经要求应用在开启新对话时默认使用模型列表里的第一个模型,并且在对话过程中也可以点击右上角切换模型,但由于多次遇到切换模型后对话界面卡死的情况(也有可能是在加载历史对话时出现卡死?),决定调整模型切换的逻辑试试

2、首先,在AI模型管理界面,增加“默认模型”设置,按钮放在每个模型的“测试”按钮前面,可以将任何一个模型设置为默认模型,并且在创建新对话时直接使用默认模型,若用户需要使用其他模型,就在AI模型管理界面手动切换默认模型,再去开启新对话,这样也能防止某个对话中积累太多内容

3、另外我还发现现在每次在应用的不同界面间切换时都可能触发“创建新对话”的操作,比如首次启动应用时会创建新对话,看看收藏界面,再回到对话界面,也会创建一个新对话,这样就导致会出现多个空白的新对话,我只需要在首次启动应用时创建新对话,并且如果已经有空的新对话,就不要再自动创建新对话了

4、或者去掉自动创建新对话的机制,但在对话界面增加一个提示,比如请点击开启新对话,与默认模型对话,需要看下这种方式是否和目前的空状态提示有冲突

5、综上,本次修改内容包括:

1.在AI模型管理界面,增加“默认模型”设置,按钮放在每个模型的“测试”按钮前面,可以将任何一个模型设置为默认模型,并且在创建新对话时直接使用默认模型

2.去掉每次打开应用自动创建新对话的机制,在对话界面最右侧栏增加一个提示“请点击右上角开启新对话,若需切换模型,请前往设置中修改默认模型”

6、Cursor的修改内容包括:在DataManager中添加默认模型ID的保存和读取方法(使用UserDefaults);在AIModelManagementView中添加“默认模型”按钮(放在“测试”按钮前面);修改AIViewModel的createNewSession方法,使用模型模型而不是第一个模型;修改AIChatView的sendMessage方法,使用默认模型;去掉AIChatSessionListView中的自动创建新对话逻辑;在AIChatView的emptyChatView中添加提示信息,除此之外还增加了一条“更新removeAIConfig方法:删除的模型时默认模型时,清除默认模型设置”

7、测试发现默认模型设置功能已经具备,创建新对话时会直接使用新模型,但对话界面右侧的提示目前有两行,并且内容有重复,于是让Cursor去掉了第一行,只留新添加的一行,并且稍微加大了提示内容的字号

8、本次的修改需求基本达成,发现AI模型管理界面的“数据统计”功能好像没啥用,于是也让Cursor去掉了,至于在使用应用的过程中频繁出现的FSFindFolder failed with error=-43错误提示,Cursor认为这种提示通常出现在CoreData初始化时,系统内部可能使用旧的Carbon API(FSFindFolder)查找Application Support目录,导致出现了-43即“文件未找到”错误,Cursor改成了显式指定Core Data存储位置,使用FileManager的现代API,避免系统使用旧的FSFindFolder API,初步测试暂时未遇到这一错误

9、今天的修改就到这里,接下来测试两天,如果没有什么明显的问题就修改设置-关于页面、刷新README文档,并打包,版本号用v0.3

DevLog:2025年11月17日

1、继续修正之前的问题,并且增加一些细节,首先是数据统计功能,对Cursor说:我需要在设置中增加针对每个模型的数据统计功能,显示自从该模型被添加以来的对话数据量,包含输出Tokens和输入Tokens,这一修改涉及Core Data模型、AIService、DataManager和AIModelManagementView

2、修改后测试发现AIModelManagementView里显示的内容有些多,比如Base URL这一行其实没有必要在这里显示,数据统计功能现在像是一个表格,改成单行就可以了,继续让Cursor修改

3、测试过程中发现对话时偶尔会遇到点击发送按钮后应用卡死的情况,继续让Cursor排查问题,Cursor进行了添加防止重复发送机制、优化Core Data操作、改进错误处理、减少不必要的操作等改进,但仍然没有解决问题,我在打开应用后,打开一个有历史对话记录的对话,输入问题并提交后应用就会卡死,可能是加载历史对话记录导致的卡顿?Cursor优化了处理大量历史消息时的性能问题,并且优化消息的payload构建,包括预取数据、减少faulting、优化排序等等操作

4、再次测试,首次打开一个有对话记录的对话并且提交问题后不会卡死了,但切换到另一个对话并且提交问题时又卡死了,Cursor继续优化流式响应处理,但依然存在应用卡死的问题,甚至打开应用后,打开一个已有历史消息的对话,应用就会被卡死

5、再次修改时,Cursor采用了分批处理消息(每批处理50条消息,避免一次性处理过多)、异步执行、预取优化等操作,并指出卡死时因为打开有大量历史消息的对话时,应用会一次性处理所有消息,长时间占用主线程,Core Data faulting导致同步IO操作,且排序操作在处理大量数据时耗时,现在我看见Cursor这种煞有介事的解读都已经麻木了,AI对自己的思考和操作都非常自信,但实际结果可能并没有多么好,实测果然还是会卡死

6、决定先绕开这个问题,将应用的对话界面修改成每次打开应用时,默认用模型列表里的第一个模型开启新对话,这样应该能避免一打开应用就加载历史对话导致的卡死问题,修改后的工作流程变成了:应用启动时,AIChatSessionListView出现——检查是否有模型配置——如果有模型,使用第一个模型创建新对话——自动选中新对话,用户可以直接开始聊天

7、修改之后实现了我的需求,但我发现目前应用的流式输出好像又出现了问题,像是每次跳出来一两句甚至一两段,Cursor分析后表示这是因为之前使用定时器延迟更新(0.12秒),导致内容在buffer中累积,每0.12秒才更新一次UI,于是将content和thinking内容改成了立即更新,不再使用定时器延迟,tavilyResults也改成了立即更新,这样可以实现接近逐字显示的平滑输出效果,明天再测试下看看

DevLog:2025年11月7日

1、今天再次遇到了用ChatWith for Mac对话时应用卡住的问题,但强制退出、重新对话时又能正常对话了,猜测可能是因为单个对话中内容比较多时,应用还未加载完成就提问,就会导致应用卡死?而且我还发现在不同对话间切换时,有时不会直接跳到最新的对话底部,有时还需要滚动一下才能看到对话内容,体验上也不够统一,继续优化,并且需要把停止生成按钮、快捷键支持、代码块复制、消息时间显示、数据导出功能、使用统计这些功能加进来,测试基本完善后,更新版本号为v0.3,移动端NoteWith的开发暂停

2、向Cursor反馈了这些问题,询问是否是因为内容加载机制导致的,Cursor分析后表示的确和对话内容加载机制有关,主要包括“流式更新时频繁遍历Core Data关系”和“每次保存都整表刷新会话列表”,建议拆分保存和刷新逻辑,减少loadAISessions()调用频率,或换成增量更新,同时在切换会话和流式结束后再合适地触发滚动,避免“滚动到底部”信号在数据还没稳定时被打断

3、具体操作上,需要先重构流式消息的更新方式,再优化Core Data刷新的节奏,修改一次之后依然存在打开对话窗口时不自动滚动到最新对话底部的情况,再次让Cursor修改之后可以自动滚到到最新对话底部了

4、接下来开始增加一些小功能,包括停止生成按钮、快捷键支持、代码块复制、消息时间显示、数据导出功能、使用统计,先增加停止生成按钮(发送消息后、正在回答时发送按钮变成停止生成按钮,点击可以停止生成)、消息时间显示(显示绝对时间),这两个功能都在AI对话界面里,其他功能稍等

5、修改过程中发现,今天Cursor的对话的语言风格突然变了,可能是Auto模式换成了另一个模型?而且也不会根据我之前的要求自动进行构建测试了,甚至在我要求进行构建测试时,也会出现因为权限问题导致的构建失败,挺奇怪的

6、修改之后测试发现已经有了停止生成按钮(但未测试)和消息时间显示功能,连续询问了三个问题,前两个问题都可以正常回答,但第三个问题在点击发送后应用就卡死了,我提交了调试信息,Cursor再次进行了节流流式更新、结束时一次性收尾、降低Core Data压力等优化,这次依然没有自动进行构建测试,那我只有自己继续测试了,连续多轮对话看是不是还会被卡死

7、连续问到第三个问题时应用依然会卡死,再次让Cursor修改,流式输出过程中只往缓冲区追加字符串,不直接操作Core Data,用定时器把写库和UI刷新节流到120ms等操作,这样每条回复只会做少量大块复制,避免了第三次对话时的主线程卡顿(当然这都是Cursor说的,具体体验如何还得看测试结果),再次测试,打开上次因卡死未收到回复的对话时也被卡死了,这次Cursor进行了清理空白AI消息、修改滚动逻辑、思考内容默认折叠(我还是更希望默认展开)等操作,再次测试,切换对话、切换模型后提问时依然有问题

8、这两天对ChatWith应用卡死问题的修改不是很顺畅,开始反思到底有没有必要在同一个对话里切换模型,对这种操作的支持,可能增加了应用的复杂性,如果增加一个默认模型机制(其实一开始是有的,但我给去掉了),每次创建新对话时就直接用默认模型,或者在新建对话时即要求用户选择模型,在一个对话中只允许使用一个模型,可能会更简单一些,但我最初借鉴的Chatbox和Cherry Studio,的确都支持在对话过程中切换模型

DevLog:2025年11月6日

1、让Cursor将当前版本(v0.2)打包,Cursor这次还同步创建了发布说明文档,其中包括版本信息、安装说明、更新内容、系统要求、支持的AI平台、反馈与支持、注意事项等内容,看起来还是挺规范的

2、已经用上了v0.2版本,以后对话时多多使用,修正问题并进一步优化,同时我还询问了Cursor下一个版本的建议,以细节补充和优化为主,Cursor给出了高、中、低三个不同优先级的建议,但我个人还是觉得有些并不着急

3、高优先级建议包括停止生成按钮(发送消息后按钮变成停止生成按钮,可以随时点击停止)、会话重命名/自动命名(其实现在可以重命名,也会自动获取用户的最后一个问题作为会话的名字)、消息复制按钮(已有)、快捷键支持(比如给创建新对话、切换模型、搜索等功能指定快捷键,这个可以有)、错误处理优化(更友好的错误提示、API限流处理、离线模式、崩溃日志等,我暂时不需要)

4、中优先级建议包括重新生成功能、代码块复制(这个可以有)、消息时间显示(我忽略了这一点,现在还真没有)、空状态设计(无对话、无收藏时的引导界面,这个好像也已经有了)、数据导出功能(收藏内容导出成.md还是比较实用的)

5、低优先级建议包括主题色自定义(花里胡哨,不需要)、使用统计(显示使用次数、Token消耗等,后面可以加上)、标签分类(暂不需要)、字体调节(暂不需要)、帮助文档(暂不需要)

6、总结一下,v0.3要增加的功能包括:停止生成按钮、快捷键支持、代码块复制、消息时间显示、数据导出功能、使用统计,也都是一些细节上的补全

7、目前在进行中的开发项目,移动端有ChatWith、NoteWith和DoitWith,Mac端有ChatWith for Mac和NoteWith for Mac,NoteWith for Mac是由移动端NoteWith修改而来,功能上相当于在ChatWith基础上增加了备忘录和待办事项功能,整合的功能比较多,后续可能会考虑删掉待办事项功能,留给DoitWith,且AI对话功能需要重复开发,暂时先搁置,接下来继续开发移动端NoteWith

8、将近三个月没有修改过NoteWith了,甚至都忘了它的功能都有啥,先让Cursor梳理一下目前的项目,都有哪些功能,有哪些优化建议,在梳理过程中,先整理了应用功能与优化建议文档,然后检查发现了重复文件,Cursor建议先清理重复文件(我还发现目前应用文件夹里有多个Trae创建的项目文件备份和.sh文件,也都不需要了,一并清理掉)、清理调试打印和未使用的代码,后面可以考虑更换数据持久化方案为Core Data,然后优化性能、扩展功能等等

9、Cursor直接删掉了15个无用文件(应用能否正常运行还有待验证),然后我删掉了多余的空文件夹,和之前不知道啥时候、由哪个AI工具编写的重构指南文件,以及一个项目初始化脚本setup.sh

10、时隔三个月再次启动了iOS模拟器,iOS 26已经发布,模拟器也换成了iPhone 17 Pro、iOS 26.0,并且部分界面也自动变成了iOS 26的效果,比如底部的AI对话、备忘录、我的三个按钮及其切换效果,决定趁现在应用功能还很简单,结合近期修改ChatWith for Mac的经历,先开启一个新对话,把NoteWith的AI对话和备忘录的数据永久化方式改为Core Data,AI模型、设置等仍然采用UserDefaults

11、Cursor的建议是使用Core Data存储Note、AIChatSession、AIMessage、SearchLink、deletedNotes,仍然使用UserDefaults来保存AIConfig和应用设置,因为Core Data适合结构化数据,支持关系、查询和迁移,UserDefaults适合小量配置,访问频繁但更新不频繁

12、接下来创建Core Data模型文件和相关组件,创建了备忘录、AI对话、AI消息、搜索链接四个实体及对应的扩展类,重构了DataManager,并更新了项目文件,和以往修改数据永久化方式一样,这次Cursor也增加了迁移机制,首次运行时会自动将现有的UserDefaults数据迁移到Core Data,但因为当前应用还没有发布,不需要迁移机制,让Cursor去掉了迁移机制,并且修复了构建错误,具体使用体验怎么样,哪些功能受到了影响,明天再测试,然后引入三方库MarkdownUI和RichTextKit,完善AI问答和备忘录的渲染效果和编辑体验