fir-mac 開發(fā)筆記

練手 Cocoa 開發(fā),開發(fā)并開源了一款 fir.im 的 Mac 客戶端,此篇主要記錄其開發(fā)歷程,總結(jié)一下遇到的問題

緣由

某一天突然翻到自己 GitHub 下有一個(gè)空倉庫,名字叫 fir-mac,提交時(shí)間在 2016 年 6 月 22 號(hào)事秀,恍然大悟原來又是棄坑項(xiàng)目之一。
由于從事 iOS 開發(fā)后一直對(duì) macOS 開發(fā)比較感興趣野舶,感覺 Mac 應(yīng)用有一種天生的美感易迹,更是在 OS X 10.10 Yosemite 之后的扁平化、毛玻璃平道、各種窗口細(xì)節(jié)的優(yōu)化感到和往日使用 Windows 的差異睹欲;那既然都已入蘋果的坑,何不順勢(shì)玩玩 Cocoa 桌面開發(fā)呢一屋, 業(yè)余時(shí)間前后寫了 MyMacMusicPlayerCubicBezier窘疮,也算小入了一點(diǎn)點(diǎn) Cocoa 的門,想繼續(xù)找項(xiàng)目在實(shí)戰(zhàn)中磨練自己冀墨,然后因?yàn)橛卸螘r(shí)間用 fir.im 比較多闸衫,隧萌生了為其做一個(gè) Mac 客戶端的想法。

準(zhǔn)備

開發(fā)之前首先得想想會(huì)遇到最大的問題是什么诽嘉?那應(yīng)該是 fir 的接口蔚出,官方有沒有開放接口?接口有沒有限制含懊?這是我作為一個(gè)第三方開發(fā)人員無法控制的事情身冬,所辛 fir 在很早的時(shí)候就開放了他們的 API 及其文檔,并且借口都比較齊全岔乔,證明他們對(duì)此是保持開放態(tài)度,那么接口的障礙沒有了還有其他問題嗎滚躯?
這時(shí)我就預(yù)估一下了應(yīng)用的整體功能模塊雏门,以及大致實(shí)現(xiàn)方法,把項(xiàng)目難點(diǎn)提前篩出來看看掸掏,fir-mac 作為一個(gè)基于 Mac 系統(tǒng)的 GUI 客戶端茁影,首先是 UI 的搭建,最初想法丧凤,用一個(gè)列表(NSTableView)呈現(xiàn)賬戶下所有的應(yīng)用募闲,然后點(diǎn)擊應(yīng)用可以展開其詳細(xì)信息,感覺應(yīng)該可以實(shí)現(xiàn)愿待,當(dāng)然 UI 動(dòng)畫浩螺、優(yōu)化什么的暫且先不提靴患,畢竟先得把功能做出來才是第一步。

功能架構(gòu)

功能上主要參考 fir web 端要出,包括上傳應(yīng)用鸳君、查看應(yīng)用列表、查看應(yīng)用詳情患蹂,差不多就這樣或颊,簡(jiǎn)簡(jiǎn)單單實(shí)實(shí)在在。

sketch

后來有朋友在微博上評(píng)論說想要掃二維碼下載的功能传于,很快也增加進(jìn)去了囱挑。
如果你是本軟件的使用者,有什么功能上的意見或想法歡迎與我聯(lián)系哦沼溜。

UI設(shè)計(jì)

UI 最終成品基本上也繼承與最初的想法而來看铆,簡(jiǎn)單的 List,彈開應(yīng)用詳情盛末,采用 Vertical Split View Controller 分欄設(shè)計(jì)弹惦,把左右兩邊分開并各自獨(dú)立 NSViewController,從而使業(yè)務(wù)邏輯分離開來悄但,在 Storyboard 上看起來是這個(gè)樣子:

Storyboard

右邊的塊區(qū)域用了 NSBox 作收納子元素和框樣式棠隐,隱藏掉了 Title,想想在 iOS 上搞這個(gè)還得弄個(gè) UIView 設(shè)設(shè)圓角什么的檐嚣。(有時(shí)候總會(huì)想到 CocoaTouch 里的東西去)
Cocoa 里原生提供了三種列表組建助泽,分別是 TableView、Outline View嚎京、Source List嗡贺,而 Outline View、Source List 都是基于 NSOutlineView 的定制鞍帝,而 NSOutlineViewNSTableView 的定制诫睬,所以歸其總都是 NSTableView 一個(gè)東西。

TableView

fir-mac 左邊側(cè)邊欄的列表則用的 TableView帕涌,自定義其 Cell 來展示的:

CustomCell

最后的實(shí)際運(yùn)行效果如下:

Screenshot

可以看到其實(shí)和 Storyboard 相似度很高摄凡,開發(fā)此類小應(yīng)用使用 Storyboard 構(gòu)建 UI 效率非常高,并且因?yàn)榇翱谠O(shè)計(jì)成固定大小蚓曼,要么縮小要么關(guān)閉亲澡,不能縮放,所以也不用去拉 AutoLayout纫版,真的省心床绪。

困難1:接口的調(diào)試

從最開始本以為很簡(jiǎn)單的 form-upload 操作,廢了兩晚上時(shí)間才搞定,因?yàn)?fir 的應(yīng)用包是存在靜態(tài)文件服務(wù)器上的癞己,而且后端采用了不同的云存儲(chǔ)商膀斋,所以上傳文件需要兩個(gè)步驟,第一步先獲取憑證末秃,第二步再用拿到的憑證進(jìn)行表單上傳概页,因?yàn)閼?yīng)用二進(jìn)制和應(yīng)用圖標(biāo)是分開上傳,所以一次提交應(yīng)用的操作其實(shí)會(huì)發(fā)三個(gè)請(qǐng)求练慕,[拿 Token] -> 上傳圖標(biāo) -> 上傳應(yīng)用惰匙。
有點(diǎn)不明白的是應(yīng)用圖標(biāo)本身也是從其應(yīng)用文件中提取出來的,為什么不把這一步拿到服務(wù)端做呢铃将?為了節(jié)省服務(wù)器資源嗎项鬼?還有其應(yīng)用信息,感覺放到服務(wù)端做會(huì)更可靠劲阎,因?yàn)?fir 不止一個(gè)客戶端工具去做上傳绘盟,比如 Website、Command Line Tool悯仙,各種 IDE 插件龄毡,每個(gè)端都需要去編寫這套包解析和兩次上傳請(qǐng)求,首先維護(hù)成本增高锡垄,解析提交的數(shù)據(jù)還不一定是可靠?jī)?nèi)容沦零,造成臟數(shù)據(jù)提交到服務(wù)端。
好吧先不糾結(jié)這個(gè)接口設(shè)計(jì)了货岭,想說的是為啥在一個(gè)上傳文件的功能上繞了彎路路操,最后找到問題是因?yàn)橐粋€(gè)參數(shù)的參數(shù)名寫錯(cuò)了,并且服務(wù)端沒有錯(cuò)誤反饋千贯,仍然返回的請(qǐng)求成功屯仗,這我就懵了,然后抓了一下 web 所請(qǐng)求的參數(shù)值搔谴,拿過來用錯(cuò)誤的參數(shù)名提交居然也成功了魁袜。這就是為啥蒙圈在這這么久的原因。

困難2:包解析

本以為 fir 的接口如上文所說是由服務(wù)端解析應(yīng)用包己沛,提取出應(yīng)用信息比如應(yīng)用名慌核、版本號(hào)等等,結(jié)果發(fā)現(xiàn)其實(shí)是本地解析拿到這些信息然后再提交給接口申尼,拿 iOS 的包來說,后綴為 .ipa垫桂,在 macOS 本地的流程大致如下:

  1. mktemp 命令創(chuàng)建臨時(shí)目錄
  2. unzip 解壓 .ipa 到臨時(shí)目錄
  3. 逐級(jí)目錄查找到 Payload 文件夾
  4. 讀取 Info.plist 文件
  5. 根據(jù) CFBundleIdentifier师幕、CFBundleShortVersionString… 提取出應(yīng)用信息和 ICON 圖標(biāo)
  6. 刪除之前生成的臨時(shí)目錄

mktemp 是一個(gè) linux 命令會(huì)在系統(tǒng)層級(jí)創(chuàng)建一個(gè)臨時(shí)目錄,路徑是隨機(jī)名大致如下 /var/folders/r3/x98gzjpn7rxct9y4rtnjsv5m0000gn/T/,不會(huì)重復(fù)保證一定安全性

unzip 是 linux 下解壓 zip 文件的命令霹粥,通過參數(shù) -d 來指定解壓目的地為之前生成的臨時(shí)目錄

讀取 Info.plist 文件本打算用 defaults 命令來完成灭将,后來發(fā)現(xiàn)實(shí)在不如讀取進(jìn) Dict 操作方便

以上便是用戶選擇一個(gè) .ipa 文件提交上傳前所需做的工作,由于 Android 包 .apk 數(shù)據(jù)結(jié)構(gòu)又不一樣后控,所以支持 Android 應(yīng)用上傳需要另外編寫一套解析邏輯庙曙,故目前 .apk 上傳還未支持。(話說寫這個(gè)真累浩淘,項(xiàng)目開源歡迎有志之士共享一份力量0破印)

引用

由于應(yīng)用主要建立在與 fir.im 接口的 HTTP 通信上,所以引入了 Alamofire 來做所有的網(wǎng)絡(luò)請(qǐng)求张抄,包括數(shù)據(jù)拉取和文件上傳砂蔽;然后因?yàn)榻涌诜祷厮袛?shù)據(jù)格式均為 JSON,為了人性化編程又引入了 SwiftyJSON署惯;項(xiàng)目列表還存在網(wǎng)絡(luò)圖加載左驾,為了省事也直接用了 Kingfisher;因?yàn)橛辛诉@些項(xiàng)目的積淀极谊,我們才能把更多的注意力放在其他事情上诡右,避免很多重復(fù)而基礎(chǔ)的工作,感謝開源轻猖!

開源協(xié)議

關(guān)于選擇開源協(xié)議帆吻,一直都沒有太深刻的理解,只知道 MIT 最開放自由蜕依,那就 MIT 咯桅锄,后來看到微博上大家評(píng)論說 MIT 難道不怕又被翻去上架賣錢嗎?之前就有 PPRows 的事情样眠,PPRows 的作者也來跟我說讓我換掉開源協(xié)議友瘤。
翻看了一下,像開發(fā)組件大部分都采用 MIT檐束,寬松辫秧,但是很多完整項(xiàng)目都采用了 GPL-3.0,比如 PHP CMS 系統(tǒng) Drupal 被丧,播放器 iina盟戏、SQLite 數(shù)據(jù)庫瀏覽器 sqlitebrowser 等等,他們采用 GPL-3.0 更是為了限制商業(yè)使用甥桂。作為一個(gè)開源作者的心愿首先肯定是希望自己的項(xiàng)目能發(fā)展起來柿究,項(xiàng)目被他人商業(yè)化估計(jì)很多作者都是不愿看到的事,開源界關(guān)于協(xié)議版權(quán)的鬧的事情已經(jīng)很多了黄选,希望那些不勞而獲通過開源項(xiàng)目結(jié)合流量與市場(chǎng)榨取用戶的人蝇摸,能把更多注意力放在做事情本身婶肩,而不是一點(diǎn)蠅頭小利和旁門左道。

一不小心吐槽了一番貌夕,本文差不多就這樣結(jié)束了律歼,如果你還沒有 star 這個(gè)項(xiàng)目,趕緊來吧:https://github.com/isaced/fir-mac

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末啡专,一起剝皮案震驚了整個(gè)濱河市险毁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌们童,老刑警劉巖畔况,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異病附,居然都是意外死亡问窃,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門完沪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來域庇,“玉大人,你說我怎么就攤上這事覆积√螅” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵宽档,是天一觀的道長(zhǎng)尉姨。 經(jīng)常有香客問我,道長(zhǎng)吗冤,這世上最難降的妖魔是什么又厉? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮椎瘟,結(jié)果婚禮上覆致,老公的妹妹穿的比我還像新娘。我一直安慰自己肺蔚,他們只是感情好煌妈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宣羊,像睡著了一般璧诵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上仇冯,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天之宿,我揣著相機(jī)與錄音,去河邊找鬼苛坚。 笑死澈缺,一個(gè)胖子當(dāng)著我的面吹牛坪创,可吹牛的內(nèi)容都是我干的炕婶。 我是一名探鬼主播姐赡,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼柠掂!你這毒婦竟也來了项滑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤涯贞,失蹤者是張志新(化名)和其女友劉穎枪狂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宋渔,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡州疾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了皇拣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片严蓖。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖氧急,靈堂內(nèi)的尸體忽然破棺而出颗胡,到底是詐尸還是另有隱情,我是刑警寧澤吩坝,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布毒姨,位于F島的核電站,受9級(jí)特大地震影響钉寝,放射性物質(zhì)發(fā)生泄漏弧呐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一嵌纲、第九天 我趴在偏房一處隱蔽的房頂上張望俘枫。 院中可真熱鬧,春花似錦疹瘦、人聲如沸崩哩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邓嘹。三九已至,卻和暖如春险胰,著一層夾襖步出監(jiān)牢的瞬間汹押,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工起便, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棚贾,地道東北人窖维。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像妙痹,于是被迫代替她去往敵國和親铸史。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,527評(píng)論 25 707
  • 今日作業(yè);如何用介紹的六種清單思維模型找到高價(jià)值的事情,建立自己的時(shí)間管理體系 1想要知道如何建立自己的時(shí)間管理體...
    9一維c閱讀 173評(píng)論 0 0
  • 2013.10.28 最近篙议,可能是因?yàn)閷?duì)過往的告別,特別喜歡聽輕搖滾的音樂崭篡,如汪峰的《飛得更高》、《像夢(mèng)一樣自由》...
    Wien超仙子閱讀 256評(píng)論 0 1
  • 夜很深吧秕, 睡前我還在想你琉闪。 我也在好奇你怎么老是在我腦里兜兜轉(zhuǎn)轉(zhuǎn), 應(yīng)該說砸彬, 我滿腦子都是你颠毙。 不知不覺睡著了, ...
    ZZZ大茗閱讀 314評(píng)論 1 1
  • 第四篇了拿霉,寫完今天這事兒應(yīng)該就能做下去了吟秩,先從最簡(jiǎn)單的做起,堅(jiān)持寫上幾年绽淘,總能夠越來越好的涵防。 1:給貓小主聽的音樂...
    coocaa閱讀 166評(píng)論 0 0