遠端偵錯 macOS 文件應用程式時,開發者常會遇到這種情況:在終端機指定應用程式後,範例檔案可以開啟;但把同一個檔案放到桌面雙擊,卻由其他應用程式開啟,或是系統詢問要使用哪個應用程式。前一次成功,只代表應用程式有機會接收檔案,並未驗證檔案類型關聯。要釐清問題,必須把類型宣告、應用程式接收、預設開啟分成三項獨立結果來檢查。
本文以自訂的 .notejson 檔案為例。檔案內容是 JSON,但副檔名用來標示這是應用程式自己的文件。操作應在已建置且可執行的 macOS 應用程式上進行;測試檔案只放虛構資料,不使用正式環境的文件。
先宣告檔案類型,而不只是判斷副檔名
自有格式應有穩定的類型識別碼。本例約定識別碼為 dev.sample.notejson,副檔名為 notejson,內容符合 JSON 格式。應用程式的類型宣告須同時涵蓋兩件事:匯出這個類型,以及宣告應用程式能開啟它。只在程式碼中判斷檔名副檔名,不會讓 Finder 自動建立關聯。
在 Xcode 的應用程式目標中設定匯出類型與 Document Types 後,檢查最終應用程式套件內的 Info.plist。匯出類型應包含類型識別碼、副檔名,以及它所符合的上層類型;文件類型則應參照同一個識別碼。如果範例應用程式只能檢視文件,就把文件角色設為 Viewer,不要宣稱具備尚未實作的編輯能力。
檢查對象是建置後的應用程式套件,不是專案介面中尚未納入產出檔的設定。
如果實際格式並非 JSON,就不要為了讓範例通過而宣告它符合 JSON;類型關係必須反映真實內容。修改宣告後要重新建置應用程式,既有的應用程式套件不會因專案設定變更而自行更新。
檢查交付套件中的宣告
先把這次要驗收的應用程式放在固定路徑。以下命令以 /Applications/NoteReader.app 為例,執行前請將 APP 改成自己的應用程式路徑:
APP="/Applications/NoteReader.app"
test -d "$APP/Contents" || exit 1
plutil -extract UTExportedTypeDeclarations json -o - "$APP/Contents/Info.plist"
plutil -extract CFBundleDocumentTypes json -o - "$APP/Contents/Info.plist"
在第一項輸出中核對 dev.sample.notejson 與 notejson;在第二項輸出中核對相同的類型識別碼與文件角色。如果 plutil 回報找不到鍵,應先檢查目標設定和建置產出檔,不要直接跳到雙擊測試。有些專案會透過建置設定產生最終的屬性清單,這時更應以套件內的檔案為準。
在遠端 Mac 上,還要確認驗收的是剛建置完成的那一份。如果下載目錄和「應用程式」目錄都留有同名應用程式,終端機指定路徑的測試與 Finder 預設開啟的測試,可能指向不同的副本。記下套件路徑,並移走不參與本次測試的舊副本,會比反覆修改類型宣告更有效。
用兩種開啟方式區分故障
建立一個暫存範例,先明確指定應用程式開啟,再測試系統的預設選擇:
APP="/Applications/NoteReader.app"
CASE="$(mktemp -d)"
printf '{"title":"association-check"}\n' > "$CASE/demo.notejson"
open -a "$APP" "$CASE/demo.notejson"
open "$CASE/demo.notejson"
open -a 成功,表示系統已要求指定的應用程式處理該檔案。接著仍須觀察應用程式是否真的顯示範例內容;只看到視窗出現,不代表檔案已讀取完成。第二條命令未指定應用程式,才會經過預設開啟的選擇流程。也可以在 Finder 中雙擊同一個範例,對照實際由哪個應用程式開啟。
預設關聯會受到該台 Mac 上既有應用程式及使用者選擇的影響。因此,驗收紀錄應分別寫下「指定應用程式開啟的結果」與「目前使用者預設開啟的結果」,不能把後者當成所有電腦必然相同的結論。如果系統顯示選擇應用程式的畫面,也要如實記錄,不能算作自動關聯成功。
依症狀定位,避免誤改讀取程式碼
| 觀察到的現象 | 優先檢查 |
|---|---|
| 應用程式套件缺少類型或文件宣告 | 目標設定、實際建置產出檔 |
| 指定應用程式後仍無法讀取 | 檔案內容、應用程式接收與解析檔案的邏輯 |
| 指定應用程式可讀取,預設開啟卻進入其他應用程式 | 目前使用者的預設關聯、其他應用程式副本 |
| 應用程式啟動但顯示空白文件 | 接收檔案後的錯誤處理與介面狀態 |
表中的後兩種情況尤其容易混淆。系統把檔案交給應用程式後,應用程式仍可能因範例格式錯誤而拒絕解析;反過來說,即使應用程式完全能解析檔案,系統也未必會預設選擇它。先確認問題發生在開啟流程的哪一步,再修改對應的程式碼。
驗收完成後,刪除暫存範例,並在建置紀錄中保留應用程式套件路徑、類型識別碼、範例副檔名及兩種開啟結果。下次修改 Info.plist 或文件讀取程式碼時,沿用同一套檢查方式,就能判斷變化發生在類型關聯還是應用程式內部,而不必靠「我雙擊過一次」下結論。
常見問題
open -a 可以開啟檔案,為什麼雙擊仍會進入其他應用程式?
open -a 已明確指定應用程式,不會測試預設關聯。先檢查套件中的類型宣告,再以不帶 -a 的指令或 Finder 雙擊測試預設開啟行為。
檔案已交給應用程式,內容卻讀取失敗,該查什麼?
檔案路由與內容解析是兩個步驟。先確認檔案實際格式符合宣告,再檢查應用程式的讀取邏輯及其錯誤訊息。
讓雲端 Mac 融入你的工作流程
VPSPush 提供可遠端連線的專屬實體 Mac。選擇節點與租用期間後,請在訂單中確認連線資訊與總金額。