iCloud 同步 Obsidian Git Vault 导致 iOS App 无限重启问题
5 min read

iCloud 同步 Obsidian Git Vault 导致 iOS App 无限重启问题

折腾记:最近碰到了一个 Obsidian iOS App 无限重启的问题,社区搜索了一下好像没有人报类似的问题,为了能够定位和解决问题学习了一些基本技术原理包括 iCloud 同步原理、Obsidian App 启动原理、obsidian-git 插件移动端实现、File Over App 理念等,接着介绍一下我定位分析问题的思路以及最终的解决办法。
iCloud 同步 Obsidian Git Vault 导致 iOS App 无限重启问题
Photo by Reuben on Unsplash

我一直在使用 Obsidian Git 自动备份的方法来管理我的 Vault,出于稳妥考虑还额外使用了 iCloud 备份作为保险手段。iCloud 会同步一个 Git 仓库、同时 Obsidian 还用了一个 Javascript 实现的 git 功能、Obsidian 还是一个 local first 的软件,这一切想想都觉得复杂度爆炸。

后来再回顾这次折腾的时候,我的感受是用 iCloud 同步 Git 仓库引发的问题本来简单的花钱就可以迎刃而解,其实大可不必这么复杂,不得不说穷是一切「罪恶」的源头🤪。

一些技术原理说明

iCloud 同步原理

先了解一下 iCloud 文件同步的原理,以下内容均源自:iCloud详解——文档存储|Java North

1.新文件上传

2.旧文件变更上传

3.新文件下载

4.旧文件变更下载

Obsidian 启动原理

相信使用 iCloud 存储 Obsidian Vault 的人都看到过如下图所示的启动画面。

这个明显拖慢 App 启动速度的举动到底是什么原因呢?根据 Obsidian 团队成员 joethei 的解释,Obsidian 会确保将所有配置文件都下载到本地之后才进行启动,不会进行类似 Lazy Load。

这背后的逻辑还是 Obsidian 团队一直遵循的他们 CEO Steph Ango(kepano) 的产品理念 「File Over App: accept that all software is ephemeral, and give people ownership over their data」,这就不难理解他们坚持的 Local First 的原因了,所以 App 在践行这一原则时就一定要确保文件在本地。

obsidian-git 插件移动端原理

iOS 和 iPadOS 不支持原生的 git,为了能够在移动端也使用该 obsidian-git 插件,他们采用了 isomorphic-git(一个用 javascript 实现的 git),目前非常不稳定,可以参考文档说明:

Obsidian iOS App 无限重启问题

问题现象

iOS 启动 Obsidian App 之后就会出现如下面视频所示的现象:

0:00
/0:07

问题定位

碰到这种问题需要先确认是不是 App 本身的问题,社区里面搜索了一圈没有类似的 Bug 讨论,那么产生问题的地方基本就可以断定是插件了,通过修改 .obsidian 目录中的插件配置排除是那个插件造成的问题。

按照上面的思路我发现关掉 obsidian-git 插件之后,Obsidian App 不断重启的问题就消失。这个 Bug 不需要进行代码走读分析,因为疑似问题点非常确定,这里我没有细致去分析 obsidian-git 的代码。

定性分析的话就是 obsidian-git 插件在 iOS 端引入了 isomorphic-git,它会一直执行文件 index 等操作导致了 iCloud 不停的检测和重新下载配置文件,这就触发了“waiting for iCloud synchronize”,你会观察到 Obsidian App 一直在重新启动进入等待下载配置的界面。

解决思路

比较幸运的是 obsidian-git 插件提供了一个不需要同步配置就能关闭插件的功能,这样就能在不改动配置文件的情况下在 iOS 端关闭这个插件(在 macOS 端和 iPadOS 端不会触发这个问题)。

查了一下 obsidian-git 源码实现:

这样一来问题就简单,利用 electron 的 local storage 配置环境变量就可以在 iOS 不改变配置文件的情况下关闭该插件。

解决方法

目前采用的方法依赖 dataview 插件来执行 js 代码,所以需要打开 dataviewjs 的开关:

然后在任意文件添加如下代码:

具体代码如下:

// auto-disable obsidian-git plugin without syncing the setting
if(this.app.isMobile) {
	this.app.saveLocalStorage('obsidian-git:pluginDisabled', 'false');
} else {
	console.log("no need to disable obsidian-git");
}

注意:配合 Homepage 插件效果更好,Homepage 指定在每次 App 启动的时候打开包括上述代码的笔记文件,确保每次都能够及时触发。

References

  1. About me — Steph Ango
  2. Backup your Obsidian.md vault with git
  3. 一种 Obsidian vault 自动备份方法
  4. iCloud详解——文档存储|Java North

Public discussion

足迹