一种备份苹果备忘录的方法

概述

如题。对于使用Mac、iPad或iPhone的同学来说,备忘录是一个方便好用的笔记本。与同类应用相比,它具有如下优势:

  • 原生
  • 支持同步
  • 支持多目录
  • 能够添加密码锁
  • 界面还看得过去
  • ......

然而,它的一大问题(特点)在于,无法批量导出笔记。对于轻度用户来说,其实还好,手动对每一个笔记进行PDF导出即可;不过重度用户就麻烦了,成百上千的笔记总不能一个一个点导出吧。

好吧,有人会问为什么要导出......一方面我们可能不太确信云服务是万无一失的;另一方面可能我们需要导出作他用。总之,需求在这了——批量导出备忘录中的笔记。

两种思路

在对备忘录应用进行一番研究之后,很自然地,我们能够提出两种解决问题的思路:

  1. 逆向并解析备忘录数据库,编程读出数据,然后就自由了,想干嘛干嘛;
  2. 利用备忘录自带的导出功能,想办法将单文件导出功能升级为批量导出功能(自动化导出)。

第一种思路很不错,很彻底,把数据拿出来之后,对于稍微懂一点编程的人来说,真的是想怎么改怎么改、想改成什么格式改成什么格式了。这方面的工作有KrauseFx开发的notes-exporterNote2Txt等。然而,由于Apple在不断地更新改变备忘录的数据存储格式,这些工具如果没及时更新,就很容易失效。在我的测试过程中,还没有哪一个能够有效地帮我把几千个备忘录一次导出来。

既然没有好用的工具,就打算自己开发一个。于是我跟着前人的脚步逆向了一段时间的备忘录数据格式,还是太麻烦。在新版本中Apple把数据都加密了。

重新考虑一下需求,其实我的备份是出于防止文件文件丢失目的。于我而言,保存成什么格式、好不好看都不重要,重要的是我需要把备忘录以某种形式在别的地方保存起来,未来一旦Apple这边出现问题,我的备份只要提供理论上的恢复可能性就好。

因此,我们不妨考虑一下第二个思路。当然,可以预见的是,即使第二个思路可行,导出的也是一个个单PDF文件。

首先,导出需要在Mac上进行,iOS上感觉比较受限(未调研,只是感觉)。那么Mac上常用的自动化工具就是Automator和AppleScript了。经过查找资料,发现AppleScript可以实现上述需求。

具体的步骤是:

  1. 手动打开备忘录,将光标停留在需要导出的备忘录的列表其实位置(如有加锁需先解锁);
  2. AppleScript模拟按键Command+P,即“导出功能”的快捷键;
  3. 此时会弹出询问保存位置的对话框,有一个默认位置,例如我这里是桌面。AppleScript模拟按下回车键确认;
  4. 导出完成,桌面上多了一个PDF文件;
  5. AppleScript模拟按下“方向键下”选择下一个备忘录;
  6. 返回步骤2。

在实践过程中,导出时间会根据备忘录内容的复杂度有所差异。因此,我们在导出前后加一些缓冲时间,使得整个过程能够完全无人监控进行。另外,桌面上放太多文件会导致系统变慢甚至卡死,因此我决定每导出N个文件后将这些文件统一移入指定文件夹,这一功能可以借助AppleScript的Shell脚本执行功能实现。

如果有多个目录待导出需要手动切换到不同的目录下,将光标停留在该目录列表中的第一个笔记,然后执行上述算法。

这个方案比较耗时,不过胜在简单,也不需要你监督,打开脚本运行起来让计算机自己导出即可。导出的结果是无数单个PDF,这其实不算难事,无论是后续把这些PDF合并成一个也好,亦或是编程将这些PDF的内容解析出来再作他用,都具备理论的可能性和实践的可行性。

解决方案代码

下面是我用来备份备忘录的代码,放入Mac自带的ScriptEditor中执行即可。代码比较简陋,但是满足了需求,够用。

set cnt to 365
set i to 0
tell application "System Events"
	repeat cnt times
		tell application "Notes" to activate
		key code 35 using {command down}
		delay 2
		key code 76
		delay 5
		key code 125
		if i = 30 then
			do shell script "mv ~/Desktop/*.pdf ~/Desktop/Diaries/D2019/"
			set i to 0
		else
			set i to i + 1
		end if
	end repeat
	do shell script "mv ~/Desktop/*.pdf ~/Desktop/Diaries/D2019/"
end tell
Per Aspera Ad Astra