fir-mac 開發筆記

練手 Cocoa 開發,開發並開源了一款 fir.im 的 Mac 客戶端,此篇主要記錄其開發歷程,總結一下遇到的問題linux

原因

某一天忽然翻到本身 GitHub 下有一個空倉庫,名字叫 fir-mac,提交時間在 2016 年 6 月 22 號,恍然大悟原來又是棄坑項目之一。
因爲從事 iOS 開發後一直對 macOS 開發比較感興趣,感受 Mac 應用有一種天生的美感,更是在 OS X 10.10 Yosemite 以後的扁平化、毛玻璃、各類窗口細節的優化感到和往日使用 Windows 的差別;那既然都已入蘋果的坑,何不順勢玩玩 Cocoa 桌面開發呢, 業餘時間先後寫了 MyMacMusicPlayerCubicBezier,也算小入了一點點 Cocoa 的門,想繼續找項目在實戰中磨練本身,而後由於有段時間用 fir.im 比較多,隧萌生了爲其作一個 Mac 客戶端的想法。git

準備

開發以前首先得想一想會遇到最大的問題是什麼?那應該是 fir 的接口,官方有沒有開放接口?接口有沒有限制?這是我做爲一個第三方開發人員沒法控制的事情,所辛 fir 在很早的時候就開放了他們的 API 及其文檔,而且藉口都比較齊全,證實他們對此是保持開放態度,那麼接口的障礙沒有了還有其餘問題嗎?
這時我就預估一下了應用的總體功能模塊,以及大體實現方法,把項目難點提早篩出來看看,fir-mac 做爲一個基於 Mac 系統的 GUI 客戶端,首先是 UI 的搭建,最初想法,用一個列表(NSTableView)呈現帳戶下全部的應用,而後點擊應用能夠展開其詳細信息,感受應該能夠實現,固然 UI 動畫、優化什麼的暫且先不提,畢竟先得把功能作出來纔是第一步。github

功能架構

功能上主要參考 fir web 端,包括上傳應用、查看應用列表、查看應用詳情,差很少就這樣,簡簡單單實實在在。web

sketch

後來有朋友在微博上評論說想要掃二維碼下載的功能,很快也增長進去了。
若是你是本軟件的使用者,有什麼功能上的意見或想法歡迎與我聯繫哦。sql

UI設計

UI 最終成品基本上也繼承與最初的想法而來,簡單的 List,彈開應用詳情,採用 Vertical Split View Controller 分欄設計,把左右兩邊分開並各自獨立 NSViewController,從而使業務邏輯分離開來,在 Storyboard 上看起來是這個樣子:數據庫

TableView

右邊的塊區域用了 NSBox 做收納子元素和框樣式,隱藏掉了 Title,想一想在 iOS 上搞這個還得弄個 UIView 設設圓角什麼的。(有時候總會想到 CocoaTouch 裏的東西去)
Cocoa 裏原生提供了三種列表組建,分別是 TableView、Outline View、Source List,而 Outline View、Source List 都是基於 NSOutlineView 的定製,而 NSOutlineViewNSTableView 的定製,因此歸其總都是 NSTableView 一個東西。編程

TableView

fir-mac 左邊側邊欄的列表則用的 TableView,自定義其 Cell 來展現的:後端

CustomCell

最後的實際運行效果以下:瀏覽器

screenshot

能夠看到其實和 Storyboard 類似度很高,開發此類小應用使用 Storyboard 構建 UI 效率很是高,而且由於窗口設計成固定大小,要麼縮小要麼關閉,不能縮放,因此也不用去拉 AutoLayout,真的省心。安全

困難1:接口的調試

從最開始本覺得很簡單的 form-upload 操做,廢了兩晚上時間才搞定,由於 fir 的應用包是存在靜態文件服務器上的,並且後端採用了不一樣的雲存儲商,因此上傳文件須要兩個步驟,第一步先獲取憑證,第二步再用拿到的憑證進行表單上傳,由於應用二進制和應用圖標是分開上傳,因此一次提交應用的操做其實會發三個請求,[拿 Token] -> 上傳圖標 -> 上傳應用。
有點不明白的是應用圖標自己也是從其應用文件中提取出來的,爲何不把這一步拿到服務端作呢?爲了節省服務器資源嗎?還有其應用信息,感受放到服務端作會更可靠,由於 fir 不止一個客戶端工具去作上傳,好比 Website、Command Line Tool,各類 IDE 插件,每一個端都須要去編寫這套包解析和兩次上傳請求,首先維護成本增高,解析提交的數據還不必定是可靠內容,形成髒數據提交到服務端。
好吧先不糾結這個接口設計了,想說的是爲啥在一個上傳文件的功能上繞了彎路,最後找到問題是由於一個參數的參數名寫錯了,而且服務端沒有錯誤反饋,仍然返回的請求成功,這我就懵了,而後抓了一下 web 所請求的參數值,拿過來用錯誤的參數名提交竟然也成功了。這就是爲啥蒙圈在這這麼久的緣由。

困難2:包解析

本覺得 fir 的接口如上文所說是由服務端解析應用包,提取出應用信息好比應用名、版本號等等,結果發現實際上是本地解析拿到這些信息而後再提交給接口,拿 iOS 的包來講,後綴爲 .ipa,在 macOS 本地的流程大體以下:

  1. mktemp 命令建立臨時目錄
  2. unzip 解壓 .ipa 到臨時目錄
  3. 逐級目錄查找到 Payload 文件夾
  4. 讀取 Info.plist 文件
  5. 根據 CFBundleIdentifierCFBundleShortVersionString… 提取出應用信息和 ICON 圖標
  6. 刪除以前生成的臨時目錄

mktemp 是一個 linux 命令會在系統層級建立一個臨時目錄,路徑是隨機名大體以下 /var/folders/r3/x98gzjpn7rxct9y4rtnjsv5m0000gn/T/,不會重複保證必定安全性

unzip 是 linux 下解壓 zip 文件的命令,經過參數 -d 來指定解壓目的地爲以前生成的臨時目錄

讀取 Info.plist 文件本打算用 defaults 命令來完成,後來發現實在不如讀取進 Dict 操做方便

以上即是用戶選擇一個 .ipa 文件提交上傳前所需作的工做,因爲 Android 包 .apk 數據結構又不同,因此支持 Android 應用上傳須要另外編寫一套解析邏輯,故目前 .apk 上傳還未支持。(話說寫這個真累,項目開源歡迎有志之士共享一份力量!)

引用

因爲應用主要創建在與 fir.im 接口的 HTTP 通訊上,因此引入了 Alamofire 來作全部的網絡請求,包括數據拉取和文件上傳;而後由於接口返回全部數據格式均爲 JSON,爲了人性化編程又引入了 SwiftyJSON;項目列表還存在網絡圖加載,爲了省事也直接用了 Kingfisher;由於有了這些項目的積澱,咱們才能把更多的注意力放在其餘事情上,避免不少重複而基礎的工做,感謝開源!

開源協議

關於選擇開源協議,一直都沒有太深入的理解,只知道 MIT 最開放自由,那就 MIT 咯,後來看到微博上你們評論說 MIT 難道不怕又被翻去上架賣錢嗎?以前就有 PPRows 的事情,PPRows 的做者也來跟我說讓我換掉開源協議。
翻看了一下,像開發組件大部分都採用 MIT,寬鬆,可是不少完整項目都採用了 GPL-3.0,好比 PHP CMS 系統 http://www.javashuo.com/tag/drupal ,播放器 iina、SQLite 數據庫瀏覽器 sqlitebrowser 等等,他們採用 GPL-3.0 更是爲了限制商業使用。做爲一個開源做者的心願首先確定是但願本身的項目能發展起來,項目被他人商業化估計不少做者都是不肯看到的事,開源界關於協議版權的鬧的事情已經不少了,但願那些坐享其成經過開源項目結合流量與市場榨取用戶的人,能把更多注意力放在作事情自己,而不是一點蠅頭小利和旁門左道。

一不當心吐槽了一番,本文差很少就這樣結束了,若是你尚未 star 這個項目,趕忙來吧:github.com/isaced/fir-…

相關文章
相關標籤/搜索