search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

我是如何把 Klib 帶到這個世界的

友情提醒:

這裡不但有 Klib 的誕生過程
還有 獨立開發者的真實寫照

萬字長文,謹慎繼續…

歷時 50 天、橫跨 2 年、經過 258 小時的純手工打造,Klib 終於來到了這個世界。

這兩天 Klib 剛剛發布,收到很多用戶的好評。趕著手熱,記錄下 Klib 的誕生歷程吧。

Klib 是全新的 Kindle 標註、筆記/書摘管理工具,macOS 平台。

2016 年底的時候,我在思考接下來做什麼項目,並沒有定下來,只是有個大概的方向:做個稍微大些的,以及技術上的需求,就是做一個有界面交互的。因為之前做的 i 系列工具(iPiciTimeriPasteiHosts)都是非常垂直的,並且都是菜單欄工具,我想讓自己有所突破

正巧,當時也給自己定了讀書計劃,就是要經常讀書,並且讀完后要在博客上寫文章。主要自己是獨立開發,獲取信息的渠道本來就不多,就要用這種方式強迫自己不斷更新。而要寫文章,很重要的內容就是讀書時的書摘。我習慣於用 Kindle 讀電子書,於是,很直接的需求就是,把 Kindle 中的標註、筆記複製出來,用於寫文章。

而我大致搜索了下當時 macOS 平台下的標註管理工具,發現並沒有趁手的。於是,就開始了程序員最喜歡做的事:造輪子

時間,正好是 2017 年元旦,詳見 當天日記。順便說一句,我有每天寫日記的習慣,已經堅持幾年了,也是為了逼迫單打獨鬥的自己,能夠保持思考、反省

設計

這裡借用設計這個名字,只是用以涵蓋產品前期的各種思考。確實是有各種思考,如市場環境、商業模式、競品分析、名字、Logo、做成什麼樣子、交互、如何發布、怎麼運營、時間節點、等等。時間有些早了,這裡簡單回憶下幾個比較重要的點。

定位

我一向傾向於做簡潔的產品,這個工具也是如此。我最核心的需求就是導出 Kindle 中的筆記,最直觀的衍伸就是能持久保存、定期回顧這些筆記。好了,就是這些吧,再多就難做的精簡、好用了。重複+小結一下:

定位:精簡的、macOS 平台、Kindle 筆記管理工具

功能集:

  • 導出 Kindle 中的筆記
  • 持久保存筆記
  • 方便回顧

名字、Logo

名字好定,因為我開發的工具都是 i 開頭的(iPiciTimeriPasteiHosts),這個自然也是。再加上是 Kindle 相關的,於是就叫:iKindle. 當然,你知道最後不是這個名字;這個坑,以後再填。

Logo 也很容易呀,你看我之前產品的 Logo 就知道了:

iKindle 的 Logo 一定是類似下面這個樣子的:

當然,你知道,後來也改了。這是后話。

交互

有了前面的鋪墊,就可以考慮具體的交互。

交互一定要直觀、符合直覺。開始時,大致的想法是這樣的(幸虧我還保留了當時的截圖):

左側是書列表、右上角是書中筆記列表、右下角是選中筆記的內容、方便編輯。後來當然是不斷演變了。

先是書

我一開始就沒打開按作者來區分,因為我本人並沒有追作者的習慣;並且,即使追,也沒必要非得按作者分類,搜索不就可以了。

但是,太多書放在一起,就有了排序的問題。按書名、最後閱讀時間、還是別的?其實你會發現,如果書多,再怎麼排序都沒用。那幹嘛不讓書少點呢?有了,如果只看最近的幾本書,比如 3 本,還需要考慮排序嗎?那些更早的書,歸檔起來不就好了,之後能搜索到就行。

於是,這就誕生了 iKindle 獨有的創意:區分當下正在閱讀的書、和之前已經閱讀的書。形式上就是把已讀的書放在一起,可以摺疊隱藏。恩,挺棒的!

然後是筆記列表

程序員的思考,很直觀的就是把所有屬性都列出來,比如筆記內容、類型(是標註、還是筆記)、位置、添加日期。這用列表很容易實現。

可問題是,除了筆記內容,後面這些屬性會佔用大量屏幕內容,卻又不重要,只要在我需要的時候能看到就可以了。

於是,那就把它們都隱藏起來好了,隱藏到簡介里,這樣筆記列表就只顯示純粹的筆記內容。恩,挺棒的!

再然後就是閱讀、編輯當前筆記

你會發現,在最原始的設計中,這部分也佔據了大量屏幕、卻不得已有大量空白。並且,對於我實際的筆記來看,很多都是一句話的,在列表中就幾乎可以展示了,不再需要額外的這個區域。再並且,真正編輯的需求並不大(最多的就是在標註時,前後有不需要的內容、符號),大部分時間只要看就行了。

於是,這部分也被我幹掉了。那如果筆記確實很長怎麼辦呢?我自然想到了 Finder 的快速預覽。OK,那就搬過來吧。恩,挺棒的!

下一個就是搜索

這個並不需要特別設計,跟系統的保持一致好了,不一致反而不好。恩,挺棒的!

最後,就是整體的交互

我一看,經過上面的改進,這不就是個系統「提醒事項」的樣子嗎?好吧,那就做成「提醒事項」的樣子。恩,挺棒的!

開發

設計差不多了,就可以碼了。我開發的順序一般是三步走:數據結構、堆 UI、完成業務邏輯。

數據結構

數據結構又主要為三塊:Kindle 本身數據結構、內存中數據結構、持久化數據結構。

Kindle 本身數據結構

好吧,先吐槽一句:Kindle 的數據結構真垃圾!至少是開放出來的數據結構真垃圾,就是一個純文本,類似於以下的內容:

史蒂夫•喬布斯傳(Steve Jobs:A Biography) (沃爾特•艾薩克森 (Walter Isaacson)) - 您在位置 #5676-5677的標註 | 添加於 2015年8月22日星期六 下午1:33:54 一家妥善經營的公司能夠大量催生創新,遠勝於任何一個有創造性的個人。 ==========

看起來還行是嗎?那再來一些多語言版本的:

-YourHighlightonLocation1-6 | AddedonThursday, January5, 20174:20:05PM-IhreMarkierungbeiPosition6-7 | HinzugefügtamMittwoch, 1. Februar201712:21:36-Votresurlignement à lʼemplacement9-12 | Ajouté lemercredi1février201712:51:12-Tusubrayadoenlaposición33-35 | Añadidoelmiércoles, 1defebrerode201712:42:10- 位置No. 39-42のハイライト |作成日: 201721日水曜日 13:00:33 – Ваш выделенный отрывок в месте 4549 | Добавлено: среда, 1 февраля 2017 г. в 13:12:38- 您在位置 #38-39的標註 | 添加於 201715日星期四 下午4:07:22

單單是識別其中的日期,就有種想 shi 的衝動:要獲取日期文本、識別格式、確定 Locale;另外,還不知道日期所在時區。

這裡我做一個小機巧:數據結構的解析能力可以動態更新。也即,在二進位程序不變的情況下,可以從雲端獲取數據的最新解析方式。這樣,當用戶反饋給我不支持的格式時,我只要更新雲端的解析能力,客戶端就都可以無痛、後台式更新了。為自己這個設計點贊!

內存中數據結構

這個沒太多好說的,定義書、筆記的各個屬性即可。

一個主要的機巧在於:如何識別筆記的唯一性?前面的文本中可以看到,筆記並沒有所謂唯一 ID 之類的東西。既然沒有,那就把筆記整體、或整體的 Hash 值作為唯一 ID 好了,反正筆記的數據量並不大,一個人一生的筆記,可能也沒有 iPhone 拍的一張圖片體積大。

持久化數據結構

這一步,主要在結構化存儲、和非結構化存儲中糾結。前者數據規整,適合筆記存儲,但擴展性差。後者優缺點大致和前者相反。

最後,我還是選擇了結構化存儲。具體的,就是 SQLite. 一方面筆記類數據實在是太規整了;另一方面,抱著學習的態度,反正我哪種都不熟悉,隨便拉一種出來練手吧。

還有一個考量就是:數據結構的公開性。數據是用戶的、寶貴的,如果使用私有的二進位數據結構,萬一哪天要停止維護了,用戶就沒有任何辦法可以解析這些數據。而使用公開的 SQLite 則不怕,任意一款 SQLite 工具都可以查看用戶自己生成的數據。這樣做,對用戶是負責任的。

堆 UI一方面就是一些核心控制項的用法,如

NSOutlineView

,

NSTextView

,

NSPopover

,

NSSearchField

. 其中,

Source List

模式的

NSOutlineView

是有些坑的,會出現諸如 UI 刷新不及時、圖標丟失等現象。有遇到類似問題的朋友,可以找我聊聊。

另一方面就是界面的細節,如字體、字型大小、顏色、留白、間距、等等。這方面我倒是偷懶了,因為基本就是「復刻」系統「提醒事項」

實現業務邏輯

打通數據流

比如,選擇右側書時,右側筆記列表能相應變化;編輯筆記時,數據能持久化;查看筆記時,能讀取正常的數據;等等。是不是聽起來都像是廢話?恩,就是這麼回事,做對就行了。關鍵是 代碼結構要好,不要有複製代碼、嚴重耦合之類的問題。

用戶引導層面

比如,開始時引導用戶手動導入、進行過程中引導用戶如何操作。這部分我基本沒做太多,因為希望程序可以做到無需引導。不過,引導用戶導入這一步,做的確實不好,還要再改進。

外圍的一些功能

比如,賬戶系統、日誌及反饋系統、等等。這裡就不再鋪開了。

測試

單元測試

其實,單元測試是在開發一開始就進行的。尤其是對數據結構部分,要充分測試。如果這部分沒問題,只要程序能跑起來,基本就沒有大問題。如果這部分有問題,改 Bug 夠喝一壺的。

並且,要在定義數據結構、完成新功能那一刻,立即完善單元測試。因為這時候是對代碼最熟悉、最清楚、也最願意寫單元測試的時候。錯過這一刻,實在是太可惜了。

完善測試用例

和單元測試一樣,測試用例不是在產品開發結果後補齊,而是在每開發完一個功能邏輯后,立即完善測試用例。道理一樣,因為這個時候是對邏輯理解最透徹、清晰的時候,千萬不能錯過。

版本測試

單元測試跑一遍,心裡就有底了。再加上前面完善的測試用例,版本測試無非就是照著用例跑一遍。

我並沒有做自動化測試、持續集成,主要是涉及 UI 的自動化測試並不好做,而且投入很大。對於我這種小項目、獨立開發者而言,手動跑跑測試用例,可能是性價比最高的。

值得介紹的一點是,推薦使用虛擬機進行版本測試。事先建立好乾凈的系統、生成鏡像。每次測試時,只要將虛擬機恢復到指定的鏡像即可。再者,就是可以在當前系統(如 macOS 10.12)中,測試其它版本的系統(如 macOS 10.11)

上架

自己辛苦做出來的東西,當然是希望越多人用戶越好。要觸到更多的用戶,最直接有效的辦法就是 上架 Mac App Store (MAS) 了。

內測、公測

在上架前,要保證自己的產品的可用、好用的,最好的辦法就是,先讓一部分用戶用起來,也就是內測、公測(以下統一稱公測)。

特別要強調的是,公測的目的並不是發現 Bug,這是你自己要做好的事。公測主要有以下目的:

  • 檢驗市場:也就是說,這個產品是不是有人需要、有多迫切需要,之前假想的市場是否存在、有多大,等等
  • 檢驗設計:如果有人要,那自己做出來的東西是不是他想要的?哪些地方設計的比較好,有沒有致命的缺陷?
  • 檢驗質量:因為自己能覆蓋的情況是有限的,還是要靠真實用戶的實際使用來最終檢驗質量。

我的內測主要是在之前的用戶群中、V2EX 中,在此特別感謝參與公測的朋友!

Mac App Store

好吧,終於來到 Mac App Store (MAS) 這個大坑。說 MAS 是大坑,主要是以下方面:

沙盒限制

沙盒會限制很多介面、系統許可權的使用,對程序設計、產品交互有明顯的影響。

比如,除非用戶手動操作(及用操作本身來授權)沙盒不允許產品訪問用戶的文件系統。這就使用 iKindle 無法在一開始時直接自動導入當前連接的 Kindle 設備,而必需由用戶手動操作。這就需要很恰當的引導。而一旦使用過一次,後續就不再需要用戶手動操作。這也是為什麼 iKindle 後續可以自動導入。

還有一個很關鍵的:即使在開發過程中打開了沙盒限制,蘋果在審核時還是可能以沙盒為理由拒絕。雖說蘋果準備了齊全的文檔來說明這些限制,但一般開發者明顯不能完全領會。就像你不可能讀完所有法律以後再邁出家門第一步,一定碰到問題再解決問題更實際。好在,這次我沒碰到這個問題。

名字

好吧,來說前文的坑。也許你會奇怪,為什麼直到「沙盒限制」用的還是「iKindle」這個名字?是不是打錯了?沒錯,確實是叫 iKindle.

但是,蘋果不允許在 App 名字中出現 Kindle 這個字樣。於是,只能改名了。這真是個痛苦的過程。一方面,想出一個好名字並不容易,我糾結了 N 久(具體可見我的博客),最終寫了 Klib (Kindle library) 這個名字。

另一方面,所有的東西都是跟名字相關的,比如代碼、App 名稱、文案、截圖、等等。一旦名字改了,所有這些都要改。這是極其繁瑣的事,我再也不想做第 2 次。

比如 Logo,變成了下面的樣子:

發布、推廣

終於,在被拒了 2 次后,Klib 終於頑強上架 Mac App Store.

接下來的問題就是,怎麼讓更多人知道 Klib? 也即,如何發布、推廣?

Product Hunt

在這一環節,我最沒有辦法的,就是 如何在海外推廣。畢竟咱們是人,很難打入敵人內部,更別說在外國產生影響力。

怎麼辦呢?我目前找到最直接有效的方法,就是在 Product Hunt 中有個成功的發布。這樣國外的媒體也會在 Product Hunt 中找較好的產品進行報道。所以,Product Hunt 成了 Klib 走出國門、走向世界的關鍵。

Product Hunt 的發布有很多可說的,這裡挑幾點重要的來說:

發布時間

  • 從星期幾的角度,每周二是最合適的。因為周二 Product Hunt 的用戶量最多,也有充足的時間進入 Product Hunt 的 Weekly Report. 不過,考慮到 Klib 是小眾產品,不太可能進入當天的 Top 1. 根據「雞頭與鳳尾」的邏輯,我選擇美國的周一來發布。
  • 從幾點的角度,一種做法是在凌晨 00:00 發布,這樣可以充分利用 24 小時進行傳播;另一種做法是在早上的時間發布,因為這裡媒體人、評測者剛剛起床,可以給他們更多爆光。考慮到我並沒認識國外的媒體人,還是 00:00 發布吧。因為時區的原因,Product Hunt 會在北京時間下午 4 點切換昨天、與今天的產品列表。

名字、標語

  • 名字就是 Klib 了,重要的是標語。要簡潔、要突出產品特色、要抓住用戶眼球。

截圖

  • 如果有必要,可以製作動圖,雖然我挺討厭一旦有多個產品都使用動圖,會讓界面閃啊閃,顯得很 Low;但沒辦法,這確實是能抓用戶眼球。並且,Product Hunt 的 Twitter 賬戶也有專門轉發動力的。
  • 基本上,我把把 Mac App Store 的截圖重用了。
發布后,立即在首條評論中添加更多信息。如產品的進一步介紹、未來的規劃、聯繫方式、等等。

轉發、擴散。也就是讓更多的人點進來看,投票、討論。尤其是大咖的轉發會很有效。

我最大的成績是 Ben Tossell (Community Lead of Product Hunt) 參與了討論。

可惜,他並沒有轉發。

  • 不過,不要一味的拉票,Product Hunt 有自己的排名演算法。
及時回復留言。用戶的留言,要立即回復(恩,晚上基本可以不睡了,盯著)。並且,可以將用戶的回復轉發到 Twitter 上,並表示感謝。

最終,Klib 在 Product Hunt 上獲取 200+ 點贊,10 幾位國際用戶參與討論,並 入選當日 Top 10,基本滿意。

用戶群

Mac App Store 上的好評、留言,自然是非常重要的。而 最有可能給你好評的,就是你之前產品的用戶。我一開始沒有經營自己的用戶群,現在回想起來深覺可惜。好在,現在慢慢有了 微信群Telegram 群,也有了一些非常友善的用戶,感謝你們!

媒體

媒體的爆光自然必不可少,他們的影響力是個人無法比擬的。最好是:

  • 平時就與媒體朋友保持聯繫,不要臨時抱佛腳;
  • 上線前發體驗版本,給他們預留時間準備文案;
  • 上線時及時通知,方便他們安排發布時間;也可以提供兌換碼,方便對方做活動。
  • 發布會,也要幫忙轉發,並表示感謝。

其他影響力

動用所有可以動用的影響力,讓 Klib 觸達更多的人。比如讓朋友幫忙轉發及好評,微博轉發抽獎,朋友圈,等等。

其他

定價

定價是門玄學,太高沒人買、太低自己不划算。目前 Klib 採用的是免費 + 內購(一次性買斷)的方式。免費是為了方便更多的人使用 Klib、降低門檻。雖然我很想繼續嘗試訂閱模式,無奈用戶對訂閱始終接受程度不高,且 Klib 本身的屬性也不太適合訂閱模式,於是採取買斷式。

趁這個機會,表達下個人觀點:買斷對開發者並不友好,訂閱才符合實際。畢竟通常開發者需要對產品進行持續改進(這並不是說當初發布的產品有問題,而是產品本身有改進),卻不能從改進中獲得收益,這並不健康。傷害的最終可能還是用戶自己的利益,因為開發者一旦堅持不下去而不更新,用戶只能使用有待改進的版本。

定價目前是 ¥50,首發限時半價優惠,即¥25,入手即賺。

首發的意義

目前,Klib 是 macOS 平台、首款上架 Mac App Store 的 Kindle 筆記管理工具。這種唯一性是很有意義的。因為沒有直接競品,甚至有一定的定價權。

對用戶而言,首發更容易使產品在這一品類中形成定位,後來者要想搶走在用戶心智中的定位,就不容易了。

單日銷量的意義

如果單日銷量可以使 App 出現在排行榜的前面,會帶來一些附加的流量,因為別的用戶可能因為榜單的原因多看兩眼。

首發第 2 天(第 1 天 App Store 更新太慢,沒有數據),Klib 在區、Utilities 這一品類中,Free 排名 22、Grossing 排名 14,算是不錯的成績了。

之後

目前,Klib 算是成功上架 Mac App Store,也收到了很多用戶的反饋。接下來,我會繼續改進 Klib,如增加多看支持、與 Amazon 中的筆記同步、與 Kindle 其他平台的筆記同步、導出至 Evernote、等等。當然,我會非常謹慎地加功能,保持 Klib 的精簡。

致謝



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦