Carpe Diem

備忘録

ObsidianのデータをMac, iPad, Androidで同期する

概要

Obsidianというメモアプリを使っていますが、

  • 基本はMacBook Proでメモする
  • たまにiPadで見たりメモすることもある

という使い方に加え、

といった使い方もしたくなりました。
しかし

といった課題があり、今回はそれを解決する方法を紹介します。

連携

概念図

概念図は以下のようになります。

簡単に説明すると

とい方針です。

同期-A

iPadiCloudディレクトリ以外Macとデータ連携させることができません。

iCloudディレクトリはFinderだと次のディレクトリにありますが、

ターミナル上のパスは次のようになっています。

/Users/jun06t/Library/Mobile Documents/iCloud~md~obsidian/Documents/

このパスは次の同期-BによってiCloudディレクトリにObsidianのデータを同期させる際に必要です。

ちなみにアプリ関連ではなく自前で用意したディレクトリは

/Users/jun06t/Library/Mobile Documents/com~apple~CloudDocs

に置かれます。

同期-B

事前準備

同期設定をする前に、あらかじめDropboxディレクトリとiCloudディレクトリのシンボリックリンクを用意します。

Dropboxディレクトリはターミナル上では

/Users/jun06t/Library/CloudStorage/Dropbox

なので

$ ln -s /Users/jun06t/Library/CloudStorage/Dropbox .

iCloudの方は先程のパスを元に

$ ln -s /Users/jun06t/Library/Mobile Documents/iCloud~md~obsidian/Documents/jun06t Obsidian

としておきます。

フォルダの双方向同期

フォルダを双方向かつリアルタイムにデータ同期させるツールとしてunisonがあります。
そこでfswatchを使ってデータ変更を検知しつつ、検知したらunisonを発火させます。

.unison/sync.prfに以下のconfigファイルを用意し、

$ cat .unison/sync.prf
# タイムスタンプをコピーする
times = true

# 新しいファイルを優先
prefer = newer

auto = true

# 同期する対象のルートパスの定義
root=/Users/a13156/Dropbox/Obsidian/
root=/Users/a13156/Obsidian/

# 同期するパスの定義
path=./

次のようなコマンドを実行すれば同期が開始されます。

$ fswatch -o /Users/jun06t/Dropbox/Obsidian/ /Users/jun06t/Obsidian/ | xargs -I{} unison -batch sync

再起動しても動くように

再起動しても動くようにするにはMacのLaunchdを使う必要があります。

先程のコマンドをシェルスクリプトとして用意し、

#!/bin/bash

/opt/homebrew/bin/fswatch -o /Users/jun06t/Dropbox/Obsidian/ /Users/jun06t/Obsidian/ | xargs -I{} /opt/homebrew/bin/unison -batch sync

次のような.plistファイルを用意します。
今回はcom.example.syncfolders.plistというファイル名にします。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.example.syncfolders</string>
  <key>ProgramArguments</key>
  <array>
      <string>/Users/jun06r/scripts/syncfolders.sh</string>
  </array>
  <key>RunAtLoad</key>
  <true/>
  <key>KeepAlive</key>
  <true/>
  <key>StandardErrorPath</key>
  <string>/tmp/syncfolders.err</string>
  <key>StandardOutPath</key>
  <string>/tmp/syncfolders.out</string> 
</dict>
</plist>

用意ができたら~/Library/LaunchAgents/に移動し、

$ mv com.example.syncfolders.plist ~/Library/LaunchAgents/

launchdに読み込ませます。

$ launchctl load ~/Library/LaunchAgents/com.example.syncfolders.plist

止めたい時はunloadします。

$ launchctl unload ~/Library/LaunchAgents/com.example.syncfolders.plist

同期-C

AndroidではDropsyncというアプリがDropboxと双方向に同期してくれておすすめです。

play.google.com

※追記 2024/03/19
Dropsyncの自動同期頻度が最短15分→最短1時間に変更されました。
これにより誤差が出やすくなってしまったためスマホで操作した際は手動で同期ボタンを押すのが良さそうです。

その他

途中でハマった問題についてです。

Launchdでcommand not foundが出る

Launchdからシェルスクリプトを使う際に相対パスだとcommand not foundが出たので絶対パスに変更します。

NG: fswatch
↓
OK: /opt/homebrew/bin/fswatch

ref: bash - launchd - how to keep script running in the background - Stack Overflow

まとめ

Mac内でDropboxiCloudディレクトリを双方向同期することで、Mac, iPad, Android間でもデータ同期できる環境が整えられました。

参考