簡單寫個配置,加快開發速度,減少修改的成本
身為一個隕石開發工程師,常常在改變設置是一件理所當然的事情,上頭要求什麼我們就變成什麼(神說要有光,就有了光)。
舉幾個例子來說,像是 APP 的整體配色(我們就改了 3、4 次)或是圓角不明顯,動畫效果不一樣快等等,其他各位客官自行腦補。因此,我們需要把這些統一的設定記錄在某個地方,其他人參考這些設定即可,如此一來,再也不用害怕修修改改了。
其實這篇文章要講的事情很簡單,其實就是一些在開發專案上的小技巧,因為專案會變動是一件很正常的事情,只是要怎麼讓這些變動用最小的力氣解決,也就是讓我們改的成本(時間)減少。因此這次就來教大家一些我在開發專案時的小技巧吧。
因為身為 iOS 工程師,所以文章中的一些方式可能就是採用 iOS 的特性或是 iOS 才有的功能來實作,但我相信這些概念在其他程式語言通用,也能夠用其他的方式時做出相同的效果的。
相信在開發專案的時候,常常有很多時候都在調整元件的顏色上,因為每個元件都可能有一個顏色,但這些顏色可能都是固定的,所以在這邊我們會為這些顏色來建立簡單的配置。
在這邊,我們可以使用 extension
的方式來設定我們 App 中所需的顏色,我們可以為這些顏色命名,像是主要顏色、次要顏色、按鈕顏色或陰影顏色等等,根據你的需求來命名:
如此一來我們在選配顏色的時候一樣可以透過 UIColor.
來選擇我們剛剛所 extension
的靜態常數:
因為所有顏色都會參考某個常數,所以之後如果主要顏色要改動,我們只需要改動 primaryColor
那麼 App 整體的主要顏色就會被改動了,不需要再一個一個手動慢慢修改了。
你也可以額外建立一個 enum
來存放這些靜態變數:
這樣使用的時候必須要加上該 enum
的名稱才能使用:
常常我們在寫一些需要動態計算尺寸的地方時,可能會寫了一些什麼 width + (10 x 3)) / 2
之類 hard code的程式碼,但是其實我們除了 width
之外,我們不曉得其他數字代表著什麼,因此我們可以把一些值存到一些常數中方便使用,同時也了解他代表什麼。
下面我們示範一個沒有創建常數的版本,這邊是我們在製作一個 9 宮格的 CollectionView,其中幾段程式碼區段:
在 numberOfItemsInSection
因為是九宮格所以可能 (3 * 3)
或是 9
還能夠明白他的意思。但是在 sizeForItemAt
的地方,其中在計算 length
的時候寫了 collectionView.bounds.width - (5 * CGFloat(3 - 1)) / 3
一長串的程式碼,我們不懂其中的每個數字代表著什麼,只能夠大該猜出他是想要計算出一行 3 個 cell 的寬度。
因此我們可以宣告一些常數來處理這些數據,這邊我們先新增以下屬性:
我們創建了行(row)、列(colume)以及間距(spacing)的常數屬性,接這我們在剛剛上面的程式碼區段中使用它們:
看一下畫面:
如此一來我們就能夠輕易了解其中每個值是如何被計算出來的,加上我們不適用 hard code 的方式來輸入值,所以我們可以變動任何值,假設我們把 rows
改成 10
、columns
改成 5
和 spaceing
改成 1
,我們也不需要調整任何項目,直接運行即可:
當然如果你有些 String 類型的值可能常常使用到的話,你也能夠使用一個常數屬性來管理他們,不僅能夠透過該常數名稱來了解是什麼,同時也防止了可能輸入錯誤的狀況。
在 iOS 開發中,使用 UITableView 或是 UICollectionView 來開發是很常見的,而我們常常會根據其 section 或 row 來區分該 IndexPath 位置的 cell 該怎麼呈現,但 section 和 row 分別來看都只是一個單純的整數值,在我們進行 switch 的時候總是需要加上 default,並且想要更換 section 或 row 的順序時,總是會把程式碼剪來剪去的。因此我們需要讓這些數字有明顯的名稱來區分它們。
很幸運的我們有 enum 這個強大的類型可以使用,我們可以藉由在 enum 後面標記 Int,讓可以透過 rawValue
產生我們 enum 的類型。
我們下面示範一個範例,該設計圖有分為 banner, news, products 以及 footer 的區塊,我們會根據這些內容來定義一個 enum 名為 Section
:
接著我們創建一個名為 sections
的 Array,類型為剛剛所建立的 [Section]
。(懶惰一點可以使用 Section.allCase
)
這邊我們 UITableViewDataSource
的程式碼會變成這樣,順便用一下之前所新增的顏色:
這邊你能夠很清楚的看到每個 case
做了什麼相對應的事情,接著讓我們運行一下程式碼:
這時如果想要改變介面,想要變成有兩個 banner 跟三個 product,同時移除 news,並且把 footer 移至最上面。這時,我們只要把我們 section
中的內容按照需求改變即可,所以我們的 sections
會變成:
這時我們只要直接在運行一次程式碼即可,不需改動任何程式碼:
如此一來無論區塊怎麼調整,對我們來說只需要簡單調整 sections
的內容即可,大大減少了修改時的成本。
在同一個專案中,可能許多的風格或是顏色都很雷同或是一模一樣,這時候我們可以寫一個方法統一管理這些元件,例如有幾個按鈕在不同畫面上都長得一樣,需要切圓型的圓角、白色框線然後黑底白字,這時我們可以為他撰寫個方法來產生它:
接著我們只需要讓我們的按鈕執行 button.customized()
即可,讓我們運行看看結果吧:
當然並不是所有元件都是套用同一個模板,可能某些地方會有些不同,這時候你可以為這些不同的地方,使用參數方式帶入新值來改變它。像是我們想要我們客製化的按鈕可以自行修改標題、背景色以及框線寬度,我們可以把上面 cutsomized
函數改成這樣:
這時候再回到我們想要客製化按鈕的地方,你會發現我們可以使用 customized 函數來做許多不同的調整,而沒有輸入參數的地方則會使用我們預設的默認值。像是如果沒輸入 backgroundColor
那麼就會默認為 .black
而 borderWidth
則是 1
:
如此一來我們可以用一個方法來創建不同的客製化元件。當然你也是能使用 enum 來管理不同 style 的按鈕:
接著我們一樣就能夠透過 setupButton
這個函數來設置我們的按鈕:
接著我們運行一下也能獲得想要的結果:
當然上述這些操作你也能夠定義一些 subClass 來做管理也是很實用的。你還能夠使用 @IBDesignable
和 @IBInspectable
來對元件做快速設定,但是比較麻煩的是之後再調整時可能需要一個一個調整。
當然你也可以使用 IBDesignable 來新增一個客製化屬性就是了,像是上方的 style 作法,但是沒看過有人有這樣做就是了。 ?
常常我們在開發的時候可能會分成 Development、Staging 和 Production,我們通常會根據這些環境不同來微調某部分的程式碼。舉例來說,像是 API,可能會根據環境不同我們的 baseURL 的網址也會不同,這邊我們有幾種做法來做切換:
我們也可以寫一個 enum
來管理他們:
當然我們也可以使用 git 分別建立 develop 跟 staging 的分支來處理不同環境的情況,而 master 分支就是處理 production 的情況。
我們可以在 Xcode 中根據環境建立不同的 Target,我們在 Project 的 Generl 下的 TARGETS,可以右鍵點選我們原有的 target 來複製它:
並且建立不同環境下的 Config 的文件:
接著設定這些檔案只屬於特定 Target 下的內容:
之後我們會在每個 Config 文件中編寫相同的結構,只是在 baseURL
中有不同:
之後我們在運行不同的 target 時,我們所取得的 baseURL
也會不同。
RD 人生
前面也有提到,專案需求會變動是正常的,但要如何用做小的力氣去做到改變多個方面就是一門學問了,以上這些方法都是我在開發的時候學習到的一些小技巧分享給大家,面對需要一直頻繁改變的隕石開發環境,這些方法對我來說蠻實用的 ?。如果有什麼不適當的操作或是更好管理的方式,也歡迎各位讀者與我交流,互相切磋 ??。