應對「不」:當 Apple 拒絕你以無障礙功能為核心的 App 時

對於許多開發者來說,寫程式是一種熱愛的投入,但對 Rene Zelaya 而言,這卻成了一場身體上的掙扎。在多年大量使用鍵盤後,Zelaya 患上了漸進性的手部傷害,導致持續打字變得幾乎不可能。這種身體上的限制促使他開發了 WhisperPad,這是一款以本地優先(local-first)為設計理念的聽寫 App,旨在透過語音轉文字並將文字直接注入活動游標欄位,來最大限度地減少手部動作。

雖然這款 App 解決了關鍵的個人需求,但它最終撞上了牆:Apple App Store 的審核流程。WhisperPad 被拒絕的故事凸顯了嚴格的平台指南、安全性疑慮與身障用戶真實需求之間的緊張關係。

衝突點:指南 2.4.5 與無障礙 API

WhisperPad 的核心價值主張在於效率。透過使用 accessibility API 來將文字直接注入其他應用程式,它免除了用戶手動貼上轉錄文字的需求。然而,Apple 拒絕了該 App 的一次更新,理由是根據 Guideline 2.4.5,聲稱該 App 使用 accessibility API 的方式並不構成合法的無障礙用途。

這次拒絕對開發者來說尤其令人震驚,因為該 App 較早期的版本(執行完全相同的的功能)先前都已獲得批准。儘管在申訴中解釋了該 App 是專門為患有重複性勞損(RSI)的用戶設計的,Apple 仍堅持其立場。

策略性拆分:App Store 與直接發行

面對二選一的困境——是遵守指南並失去 App 的主要功能,還是完全退出 App Store——Zelaya 選擇了第三條路:拆分發行模式。

1. App Store 版本(妥協後的體驗)

為了維持與 Mac App Store 相關聯的可發現性與信任感,Zelaya 發布了一個符合規範的版本。這個版本移除了自動貼上功能,要求用戶必須手動按下 Command-V 來從剪貼簿貼上文字。雖然這將工作流程從四個步驟增加到了六個,但它符合了 Apple 的指南,並確保了 App 仍能提供給廣大受眾。

2. 直接發行版本(完整的體驗)

為了實現最初的願景,Zelaya 將功能完整的版本轉向透過他自己的網站進行直接發行。這需要從頭開始建立整套基礎設施,包括:

  • Payments: 使用 Paddle 進行信用卡處理。
  • Updates: 使用 Sparkle framework 進行軟體更新。
  • Licensing: 建立授權金鑰伺服器。

技術觀點與社群討論

WhisperPad 被拒絕一事,引發了開發者之間關於 accessibility API 的性質以及 Apple 對其規則執行力度的更廣泛討論。

安全性議題

一些社群成員認為 Apple 的謹慎是有道理的。accessibility API 的權限範圍非常廣泛,賦予了 App 對系統的重大控制權,包括移動游標和擷取螢幕截圖的能力。正如一位開發者所言:

"The accessibility API unfortunately is way too broadly scoped... the proper engineering solution would actually be to phase out the accessibility API and replace it with something that is narrowly scoped."

此外,也存在著「中間人攻擊」(MITM)類型的固有風險,即 App 可能會將惡意文字注入到敏感欄位中,例如銀行 IBAN 帳號。

一致性問題

相反地,許多開發者對 Apple 審核流程的不透明與不一致性表示沮喪。普遍的觀點是,所謂的「界限」往往是看不見且被任意執行,讓開發者處於不確定狀態。

"The frustrating part is less that Apple has a boundary here, and more that the boundary seems opaque and inconsistently enforced."

給獨立開發者的教訓

WhisperPad 的故事為那些開發工具並試圖挑戰平台 API 的界限時,提供了幾個關鍵的啟示:

  • 限制即催化劑: 最初看似是障礙的限制,迫使開發者必須精通自己的構建配置、支付流程與更新管道,最終建立起更穩健的業務結構。
  • 多元化發行渠道: App Store 是獲取新用戶的強大工具,但對於需要深度系統整合的 App,將其作為唯一的失效點(single point of failure)是有風險的的。
  • 'Comply and Expand' 策略: 當平台說「不」時,選項通常不只是遵守或退出。開發一個分層版本的 App——一個用於商店,一個用於直接發行——可以讓開發者在維持觸及率的同時,保留產品核心功能的完整性。

Sources