肇鑫的日常博客

肇鑫 / Owen Zhao

独立开发者,主要开发 iOS、watchOS、macOS 应用。

目前在维护 SleepTapRooster Time,以及 Markdown Writer 相关工具。

最新文章

M4 Mac mini连接Apple TV HD声音断断续续问题的一种解决方案

技术

将Mac mini从M1换成M4之后,Apple TV HD的画面没啥问题,但是声音断断续续,根本没法看。之前M1的时候没问题,但M4的时候就这样了。我认为它应该和M4的网络从Wi-Fi 6升级到Wi-Fi 6E有关。

如图是我调整之后的设置。

wifi

这个和M1的相比主要有两点变化:

  1. 频道,M1只支持80MHz
  2. 安全性,之前为了兼容性,我统一使用了WPA2个人级的加密。

解决方案

因为Apple TV HD不支持WPA3的加密,当我开启5G的WPA3之后,就需要在Apple TV中手动选择2.4G的Wi-Fi。采用了这个设置之后,目前Apple TV HD只在刚开始的时候会断断续续几秒,之后就一切正常了。

我的路由是小米的BE6500 Pro。不清楚这个问题和路由是否也有关。

扩展丐版Mac的磁盘空间

技术

今年Mac mini M4丐版火了。主要是两点:

  1. 苹果将祖传的8GB内存升级到了16GB。
  2. 国家补贴20%,将价格降到35xx。

东西买来了。但是只有256G容量的SSD,却有些捉襟见肘。尤其是做开发的。Xcode自身日常就能占据80-100G。如果是512G的容量就好了。但是从256G升级到512G,苹果要价1500,算上国补,也需要加价1300。实在不够划算。

这篇文章探讨几种不同的方式来扩展Mac的内存。因为这件事实际操作起来,才能发现比原本预期的要更复杂。

硬核办法,更换内置SSD

既然SSD空间小,那么大家首先想到的就是更换一个更大的SSD。想法很好,但是苹果的SSD是焊接在主板上的。普通用户没有这个手艺。因此,要么你找有这个手艺的第三方去更换。要么你直接买别人已经更换好的。

注意:更换SSD的行为会使你的Mac mini失去质保。有些卖已经更换好的Mac mini的商家,提供一年的店铺保修。也就是说,如果坏了,你可以邮寄给商家进行保修。

这种方式的好处是,SSD仍旧是内置的,不会有额外的空间和接口占用。缺点是价格相对较贵,同时会失去苹果质保。另外还有就是第三方的技术水平参差不齐,更换可能存在隐患。

外置硬盘法

顾名思义,外置硬盘法就是使用移动硬盘的方式。而按照硬盘盒的区分,又分为10Gbps的USB 3.1/3.2硬盘盒,以及40Gbps的雷电3/4硬盘盒。二者各有各子的优缺点。

  • 10Gbps的USB 3.1/3.2硬盘盒
    • 优点:价格便宜,温度低
    • 缺点:速度相对较慢,读取写入在900MB/s以下。
  • 40Gbps的雷电3/4硬盘盒
    • 优点:速度快,读取写入可以达到2000到3000MB/s。
    • 缺点:价格要贵一些。温度较高。

虽然雷电的盒子温度要高,因此有的盒子有主动散热的风扇。但是购买时不要买有风扇的版本,因为那个实在太吵了。Mac mini睡眠时风扇也不会停。要买就买无风扇,但是硬盘盒特别重的,因为盒子重的,散热才好。比如我购买的ITGZ的那款。放在手里沉甸甸的,就是一块儿铝锭。

上面提到的是按照硬件进行划分。下面再按照使用方式进行划分。

系统外置法

系统外置法,就是将系统安装到移动硬盘上。安装的方法有两种:

  1. 通过macOS的安装文件进行安装,安装时选择外置硬盘作为安装的位置。
  2. 通过类似CCC这类的备份软件进行备份,备份时选择备份为可以启动的磁盘。
  3. 通过启动磁盘进行选择,选择从移动磁盘启动。

优点:
安装方法简单。
缺点:
完全使用外置磁盘,内置磁盘浪费掉了。
据说苹果智能要求必须使用内置磁盘。外置磁盘无法开启苹果智能。

软连接法

软连接法,就是通过命令行的ln命令创建软连接。将文件夹连接到移动硬盘上的对应文件夹。

优点:
简单,灵活。不需要新建系统,可以针对任何大的文件夹。
缺点:
有些应用会有兼容问题。比如Xcode的模拟器在使用软连接之后,就消失了,也无法新建新的模拟器。只能从软连接恢复到原来的文件夹方式。因此,这个需要不断的试错。

移动默认用户法(推荐)

苹果其实支持了用户文件的重定向功能。即在设置->用户和组->用户上点鼠标右键,然后选高级,就可以设置新的用户文件夹。

这个文件夹是磁盘占用的大头,这个转移走了,剩下的空间就超级大了。

优点:
这个方式是官方支持的。也无需安装新系统。
缺点:
操作复杂。用户文件下是包含资源库文件夹的。而这个文件夹具有系统属性,因此复制时可能存在问题。因此,你在复制粘贴到新位置时,一般不会成功,而只会提示复制失败。

解决办法:
不要直接从系统当前用户的文件夹复制。而是要利用备份软件,比如从时光机中提取这个文件夹,然后保存到新位置。又或者从CCC的备份中直接复制粘贴。

缺点:
这个方式还有一个缺点。就是对于一基于磁盘的备份工具,因为系统和用户文件夹已经不再一个磁盘,那么CCC备份的内容就不在完美。
不过系统自带的时光机还是会正常备份系统和用户文件夹到一个备份的。

华为手环9使用体验(第三晚、第四晚)

随笔

昨天没时间写这个。今天把第三晚、第四晚合并在一起写吧。

第二晚的问题

华为手环9使用体验(第二晚)中我提到了华为睡眠应用的几个问题。很难想象华为做的这么一个不算复杂的应用居然会有这么严重的问题。但是,昨天我在查看数据的时候发现,这些问题的根源其实更加复杂。

Screenshot_2025-01-03-09-45-19-521_com.huawei.health

如图,其实睡眠的数据有两项,一个是41分钟,由手环提供。另一个是2小时6分钟,是由手机提供的。但是我们从第二晚的应用的截图可以看到,它只显示了41分钟的,却没有显示2小时6分的。然后底下的打鼾录音却用的是手机录音。因此才会产生冲突。

那么问题来了,华为自己知不知道这个问题呢?华为是知道的。因为它在睡眠的41分钟后面,加了一个提示按钮i,点开你能发现,它提示你可以查看全部数据来查看完整数据。但这个按钮太过隐蔽。并且这个睡眠的整体设计也太过自相矛盾了。

Screenshot_2025-01-03-09-52-36-393_com.huawei.health

第三晚

第三晚开始,我摘下了苹果表,单独佩戴华为手环,看看它的记录是否有改善。今晚我睡得很晚,起来很早(2点多就起来了),因此没有记录上。苹果表没有佩戴,所以今天算二者打平。

第四晚

今天手环记录了两段睡眠。手环胜出。

Screenshot_2025-01-03-09-58-03-648_com.huawei.health

华为手环9使用体验(第二晚)

随笔

今晚在睡觉时,我尝试使用了手机版华为运动健康应用的记录睡眠功能,它使用麦克风记录睡眠,还能将鼾声自动分段并录音。不过使用它可能对于手环的睡眠记录产生了影响。今晚只有手机记录了。华为手环9和苹果表S9都没有任何睡眠记录。

因此,今天算是打平了。

手机记录睡眠的问题

Screenshot_2025-01-01-01-23-49-202_com.huawei.health

逻辑错误

这里有个逻辑错误。根据图片,睡眠时间时11:43-12:24,时长41分钟。但是根据下面的鼾声,第一次精选的鼾声时间是11:26分。因为是精选,所以睡眠的时间应该是不晚于11:26分,那么上面的11:43分的睡眠开始时间就是不准确的。

同理,那个12:24分的睡眠截止时间和01:04的打鼾时间也是冲突。我虽然不知道我具体何时睡着的,但是什么时候清醒还是知道的。我大概是01:10时醒的。所以这次睡眠时间应该是11:26-01:10,时长104分钟。

格式错误

这里,我们还注意到时间的格式的随意性。如果它遵从用户系统的设定,那应该是12小时上下午的时间。如果它决定用自己的时间,24小时制,也可以。但是它使用了混合的格式,而且出现自己和自己不统一。

比如零星小睡:下午11:43-上午12:24,这里如果想用12时制,应该是下午11:43-上午00:24。
下面的打鼾时间也应该使用12时制。

又或者全部使用24时制。

华为手环9使用体验(第一晚)

随笔

最近我的睡眠不太好,经常睡个1-2个小时就会醒一次。由于每次睡眠的时间都不长,苹果表s9在记录睡眠方面出现了问题,表现为有时能正常记录睡眠,有时整晚都没有记录。

我于是想再买个手环作为补充。由于我是双机用户——iPhone SE 3 + 红米K60。我首先想到的是不是要购买小米的手环。但是经过我查阅资料之后发现。似乎华为的手环在健康方面更加专业。另外,最新一代的手环,华为的价格也比小米的要便宜一些。

选择了华为手环9之后,我需要考虑的就是将手环配对到哪个手机的问题。因为我不希望重复记录睡眠时间。因此,我选择将华为手环9和红米K60进行配对。这样,我就有了两个独立睡眠记录。分别在不同的手机上面。

华为的软件设计真是让人一言难尽

早就听人说,国外软件和国内软件的最大区别,就是国外软件喜欢每个软件专注于一个方向,小巧精悍;而国内软件喜欢包罗万象,什么功能都整合在一起。华为的手环应用就是这样。

华为手环9配套应用叫华为运动健康。小米商店里就能下载到。但是它的功能实在太多了。也太过混乱。“得益于”安卓严格权限管理,打开这个应用之后,我不得不同意了太多的权限。而且它几乎每项功能都要单独申请好多的权限。比如心跳、睡眠和压力测试,虽然都在这个应用里面,但是它们都是单独申请自己是否允许写入到健康应用的权限。而且是你点击了该功能才会问。如果不点击,好多功能默认都没有开启。再点击了数不清的权限申请之后,终于可以使用了。

但是它还会时不时的跳出来让你买会员之类的。虽然手环只要200多。但是会员可不便宜,一年的年费就相当于一个手环。如果单独订阅,每个月也需要15元。什么,你说为啥年费比单独每个月乘以12还要贵?那是因为年费会员还会送你一个体脂秤。

但是其实,你就算不订阅任何会员,睡眠记录也是可以使用的。年费会员只是多了一个根据睡眠记录等信息,给你睡眠建议这项功能。但是,它的会员订阅里,却没有提示你不订阅也能用。所以,打开有人就稀里糊涂地订阅了会员。

更加混乱的是,买手环本身送一个月的免费会员。但是如果你单独点购买界面,头一个月是1元,之后是15元每个月。所以,很多人可能会因为免费或者是1月而上当。

第一晚

折腾完设置,终于可以睡觉了。还有一些吐槽留到下次再聊吧。第一晚的结果。苹果表未记录任何睡眠,华为手环记录了两段睡眠,合计2小时25分。

第一晚结果:华为手环胜出🏆。

我也会用AI写程序了

我使用AI写程序的方式

目前使用的是Xcode + GitHub Copilot(gpt-4o) + AlexSideBar(Claude Sonnet 3.5)的方式进行开发。

AI_coding

这些居然都是免费的。Copilot免费是因为我在GitHub上有开源程序,被GitHub认定是符合免费使用Copilot。而AlexSideBar是因为目前它处在Beta阶段,所以免费。

AI开发带来的收益

初级代码编写

免去了很多脚手架代码的自我编写。可以实现将功能用注释表明,然后让AI编写代码并处理错误等。

快速试错

AI可以快速生成代码和修改代码,并且可以自动合并到源代码中。比自己改要快很多。这样有想法可以快速试错。更快看到编程时的瓶颈。

很多时候,编程开发的最大难点就是这些瓶颈。也许是官方文档不全,也许是没有相应的功能,甚至可能是SDK的bug等。

自动修改

通过指导,AI可以按照用户要求的方向对于代码快速进行修改。也可以根据IDE提示的错误来修改代码。

快速进入陌生的领域

本次新应用需要使用IOKit的通知功能。这部分是我陌生的,但是AI自动生成了相关的代码。可以让我更专注应用的功能和逻辑,而不是具体细节如何编写。

AI的不足

当遇到框架的bug时,AI不能识别。需要有经验的程序员指导AI绕过坑

比如AI在List中使用DisclosureGroup,结果DisclosureGroup的展开箭头显示不出来。我问AI为什么点击之后不能展开,AI只是尝试添加点击的手势,但是那没什么用。

后来我提示AI可能是List中使用DisclosureGroup会有问题。于是AI修改方案为ScrollView+VStack来代替List,问题得到解决。

AI不懂相对复杂的Xcode配置问题

比如我虽然知道如何创建开机启动项(Login Items)。但是我将这个描述给AI之后,AI一步一步让我实现出来的配置+代码却无法显示开机启动这个功能。由于这个功能的实现需要在Xcode调整多项配置,AI却提都没提,而是让在Info.plist里添加了无关的权限申请。

最后,我还是决定按照自己的思路来做。不再使用AI实现这个功能。

AI有时不能从项目的角度来考虑问题,而是着眼于当前文件

虽然AI可以读取项目的所有代码。但是它在修改时,仅仅是基于当前页面的代码。当前页面修改之后,如果其他页面不出现bug。AI不会主动考虑到其他页面也需要做相应的修改。因此,对于项目的整体把握,还需要开发者自行掌握。

这一点我不确定是AlexSidebar独有的缺点,还是说所有这类应用都有这个问题。因为我只用过这一个。
后续我又发现,有时AI还是能够考虑多文件的修改的。但是那个大多是修改View的时候,涉及到Model的修改。如果是View和View之间的,就还是不会考虑到。

AI的思考存在局限性

比如我在macOS发送用户通知时,发现通知有时能发送,有时不能。我告诉AI之后,AI并没有修改代码到我满意的程度。

原因是后来我发现,SwiftUI的onReceive是依赖视图的。当视图不存在时,通知就没法弹出。AI没有考虑过这一点。所以它修改代码是不能成功的。我将这个问题告知Ai之后,经过指导的AI创建了一个额外的类来单独处理通知,这样就没问题了。

AI有时会钻牛角尖

比如有一个函数,可以通过A获得A中所有的B。一开始,AI没有考虑到B存在嵌套B的情况。我指出之后,AI视图通过递归来获取所有的B。但是它递归的函数是错的,它一直想要递归func getAllBs(from a: A) -> [B],这是不可能成功的。因为虽然是A包含所有的B,但是B是嵌套的,需要递归的是B的嵌套,而不是从A到B。最后没办法,我手写了这部分代码。

AI并不知晓过于小众的知识

对于AI来说,重复率越高的知识,它越知晓。但是如果一旦某个知识过于小众,这会导致AI并不知晓哪种说法是正确的。

比如我想获得雷电设备插拔的检测。Claude Sonnet 3.5和gpt-4o给出的代码都是错误的。gpt-4o给出的匹配字符串是"IOThunderboltInterface",Claude Sonnet 3.5使用的是"AppleThunderboltHALType",但最后我发现唯一正确的应该是"IOPCIDevice"。

结论

善用AI的确可以大大提高开发者的效率。不过现阶段的AI,还存在诸多的局限性。需要开发者站在更高的角度,对于AI指导,才能获得最佳的结果。

最后,附上我合作AI共同开发的第一个应用:

USB-C Speed。这个应用的功能是显示当前USB口和雷电口连接设备的接口速率。开发这个的原因是,我发现,如果使用USB 4或者雷电3/4接口连接相应接口的移动硬盘盒。有时连接后的速率实际上并不是理论上的最高速率。这在Mac mini M1上,可能会从40 Gbps降低到10Gbps。这是因为Mac mini的USB-C接口在40Gbps之下,就只支持10Gbps或更低。

这个应用会显示当前连接所有设备的连接速率。并且在USB设备插拔时,弹出插入或者拔出的设备名和接口速率。这样就可以立刻看到当前的速率是否是理论上的最佳速率了。

谈谈目前阶段我认为的大模型使用策略

技术

先说一个公理:同一个大模型中,参数越高的版本越智能。

从表面上看,既然参数越高的版本越智能,那么在硬件允许的情况下,是否应该本地运行参数更高的版本呢?答案是:是,也不是。这是因为,虽然参数更高的模型更智能,但它们消耗的资源也更高。而且,参数越高的模型,输出所需的时间通常也越长。尤其是如果使用独立显卡进行推理,当模型所需的内存超过显卡的显存时,就会转而使用CPU进行推理,那速度可能会令人无法接受。

相较于本地运行大模型的高参数版本,我更推荐本地运行低参数版本的模型,比如2B、3B这种,同时订阅在线的大模型。尽管这些低参数版本的模型在能力上不及高参数版本强大,但用于一些简单的任务,比如翻译、总结等,效果还是很不错的。而且,它们占用的资源较少,运行速度也相当快。即便是在16GB内存的Mac mini M1上,它们运行时的内存占用也仅在2GB左右。

对于复杂的任务,我们可以将其交给在线的大模型处理。因为相比于在线模型的订阅费,本地运行这些大模型所需的硬件费用远远更高。而在线大模型的好处在于,我们可以根据当前任务选择最合适的模型进行使用。

有人可能会说,若想灵活切换,就需要订阅多个在线大模型,那么费用不就高了吗?其实并非如此。我们可以考虑订阅第三方服务,比如OpenCat。在其订阅期间,我们可以有限制地使用所有它支持的大模型。这样,我们就不必为每个大模型单独订阅。而且,通过这种方式,我们还可以避免一些大模型随意封号的风险。

忙碌的一天(后续)

忙碌的一天

今早起床,看到EPIC回复了。没想到事情还会有新的变化。EPIC回复说,通过发给它的收据,它发现我购买了游戏EPIC账号,不是我现在使用的这个Gmail的。而是另外一个邮箱。它说,虽然它不能直接告诉我那个邮箱的信息,但是已经发了一个确认邮件给那个邮箱,让我自己找。

我也很困惑。我还有两个EPIC的账户?真是没想到啊。我尝试登录了我的QQ邮箱和微软邮箱,发现都不是。有尝试登录Apple ID,结果发现我的iCloud Mail账户没有开通。这我就奇怪了,我并没有别的邮箱了啊。

苹果的安全邮件

于是我又回到了Gmail,然后搜索之前的EPIC邮件。我发现,早期EPIC发给我的Gmail的邮件,居然不是直接发到Gmail邮箱的,而是通过一个@privaterelay.appleid.com中转过来了。这个功能,其实是Apple ID登录的一部分。可以避免暴露用户本来的邮箱地址。

不过我这次却的的确确被这个功能给坑了。因为这个功能貌似需要整个系统的支持。只有你一直使用同一个Apple ID的时候,你在某网站登录过之后,下次才会使用的同样的ID登录。如果你有多个Apple ID,那么就可能会重新创建一个ID,这样你之前创建的ID就找不回来了。

没有办法。既然我没法通过苹果登录重新登录。我只能通过@privaterelay.appleid.com的邮箱,选择重置密码登录。登录之后,的确购买过的游戏都还在。进度也是对的。

后续处理

我和EPIC说明了上面的情况。并请求它将我的两个账户合并,今后我将只使用Gmail的邮箱进行登录。可是EPIC回复说,它没有合并账户的功能。但是在设置里,我可以修改注册邮箱。我只需要将@privaterelay.appleid.com的邮箱,修改为我另外一个邮箱就可以了。当然,不能还是Gmail的这个邮箱。

我回复,那我就现在删掉Gmail的账户,然后将@privaterelay.appleid.com改成Gmail的就可以了。我问EPIC我的这个方案是否可行?EPIC回复,可行。不过删除账户要15天才能生效,因此第二步需要15天后才能进行。建议我还是直接修改邮箱。

于是我最终选择了将Gmail的账户的邮箱,改为了Foxmail的邮箱,然后将@privaterelay.appleid.com邮箱改成了Gmail的。此时终于完美解决。

结论

如果你有多个Apple ID,并且经常切换使用。那么最好不要轻易使用Apple账户登录的功能。它这个功能最好的使用场景,是某些强制登录,但是你永远不会再用的情况。