Frank's Book
  • Introduction
  • Privacy Policy
  • Git
    • [Git]Fully delete a git repository created with init
  • iOS
    • iOS Book
      • [iOS] Swift Coding Style
      • [iOS] UnitTest With XCode
      • [iOS] Build a Universal Framework for iOS using Swift
      • [iOS] Memory Management
      • [iOS] GCD And Operation Queue
      • [iOS] MVVM
      • [iOS] CoreData
      • [iOS] KVO & KVC
      • [iOS] Asynchronous Operation
      • [iOS] URLSession
      • [iOS] NSTimer & CADisplayLink
      • [iOS] UITextField & UITestView
      • [iOS] UITableView & UICollectionView
      • [iOS] Codable
      • [iOS] Array的sort, filter, map, reduce 函式
      • [iOS] Class vs Struct
      • [iOS] Reference Type vs Value Type
      • [iOS] Object
      • [iOS] IBDesignable & IBInspectable
  • Jenkins
    • Jenkins & Docker
      • [Docker] Docker Commands
      • [Docker] 1. Setup Jenkins with Docker on Mac
      • [Docker] 2. Jenkins建立Mac子節點
      • [Docker] 3. Mac節點build Xcode project設定
      • [Jenkins] 1. Install Jenkins
      • [Jenkins] 2. Change Default User Of Jenkins
      • [Jenkins] 3. Integration with Git
      • [Jenkins] 4. Integration with XCode
      • [Jenkins] 5. Integration with Unit Test
      • [Jenkins] 6. Uninstall Jenkins
      • [Jenkins] 7. Jenkins Commands
      • [Jenkins] 8. Jenkins Plugins
      • [Jenkins] 9. Problem Solving
  • Flutter
    • Flutter Book
      • [Flutter] Update your Flutter path (Mac OS)
      • [Flutter] Release Command
      • [Flutter] Life Cycles
      • [Flutter] AppLifecycleState
      • [Flutter] Navigator Pop時回傳資料
      • [Flutter] Install appium-flutter-driver
  • Leet Code
    • LeetCode Solutions
      • [LeetCode] 1. Two Sum [Easy]
      • [LeetCode] 2. Add Two Numbers [Medium]
      • [LeetCode] 3. Longest Substring Without Repeating Characters [Medium]
      • [LeetCode] 5. Longest Palindromic Substring [Medium]
      • [LeetCode] 7. Reverse Integer [Easy] [LeetCode]
      • [LeetCode] 8. String to Integer (atoi)
      • [LeetCode] 11. Container With Most Water
      • [LeetCode] 13. Roman to Integer
      • [LeetCode]14. Longest Common Prefix
      • [LeetCode] 15. 3Sum
      • [LeetCode] 17. Letter Combinations of a Phone Number
      • [LeetCode] 19. Remove Nth Node From End of List
      • [LeetCode] 20. Valid Parentheses
      • [LeetCode] 21. Merge Two Sorted Lists
      • [LeetCode] 22. Generate Parentheses
      • [LeetCode] 26. Remove Duplicates from Sorted Array
      • [LeetCode] 28. Implement strStr()
      • [LeetCode] 33. Search in Rotated Sorted Array
      • [LeetCode] 34. Find First and Last Position of Element in Sorted Array
      • [LeetCode]36. Valid Sudoku
      • [LeetCode] 38. Count and Say
      • [LeetCode] 46. Permutations
      • [LeetCode] 48. Rotate Image
      • [LeetCode] 49. Group Anagrams
  • Git
    • Git Commands
      • [LeetCode] 50. Pow(x, n)
  • About Author
    • Frank Chen
Powered by GitBook
On this page
  • 命名規則
  • 縮排
  • 註解
  • Protocol 實作
  • 宣告
  • MVC (Model, View, Controller)
  • Guard
  • nil-coalescing operator
  1. iOS
  2. iOS Book

[iOS] Swift Coding Style

Coding Style有時候是主觀的, 這邊主要整理了Apple Sample Code與Clean Code所提供的規則

命名規則

(1.) Apple以Camel Case (駝峰法)方法命名, 除了第1個單字, 每個單字的開頭大寫.

ex: 宣告1個Button

  var theFirstButton = UIButton()    (O)
  var Thefirstbutton = UIButton()    (X)  

(2.) 名字要能夠念出來, 不要用縮寫.

ex: 宣告1個Button

  var theFirstButton = UIButton()    (O)
  var theFirstBtn = UIButton()       (X)  

(3.) 宣告array時, 用s結尾

ex: 宣告1個button array

  var buttons: [UIButton] = []        (O)
  var buttonList: [UIButton] = []     (X)  

(4.) IBOutlet 元件的命名, 其變數結尾與元件型別有關

ex: 宣告1個IBOutlet button

@IBOutlet weak var theFirstButton: UIButton!        (O)
@IBOutlet weak var theFirstTouch: UIButton!         (X)  

(5.) IBAction function的命名, 其function結尾與事件有關

ex: 宣告1個IBOutlet button 的 touchUpInside function

@IBAction func theFirstButtonTouchUpInside(_ sender: UIButton) {       (O)
}   

(6.) Singleton或共用的實體, 取名為shared

ex: 宣告一個Singleton Class

class SingletonClass {       
   static let shared = SingletonClass()
}

(7.) Class與資料夾名稱以Camel Case (駝峰法)方法命名, 但第1個字也是大寫

ex: 宣告一個 Class

class MyClass {       
}

(8.) Function的命名盡量以動詞開頭, 參數越少越好, 1個Function只做單一的1件事情,

內容越精簡且越有可讀性越好

ex:

func updateUI() {  
    self.updateTitleLabel()  
    self.updateButtonColor()   
}

func updateTitleLabel() { 
  //只更新TitleLabel  
}

func updateButtonColor() {   
  //只更新ButtonColor     
}

(9.) 較短的命名若能解釋清楚, 勝過較長的命名

較短的命名若不能解釋清楚, 較長的命名更好

(10.) 統一的命名, 比如說跟更新UI有關的function都用update開頭, 方便搜尋

ex:

func updateUI() {       
}

func updateTitleLabel() {       
}

func updateButtonColor() {       
}

(11.) Delegates命名, 第一個參數通常是delegate source

ex:

func myViewDidSelect(_ myView: MyView, name: String)                 (O)
func myViewShouldReload(_ myView: MyView) -> Bool                    (O)


func myView(name: String)                                            (X)
func myViewShouldReload() -> Bool                                    (X)

縮排

(1.) 括號與換行

Swift推的:

if (isHappy) {
  // Do something
} else {
  // Do something else
}

比較少人用的:

(微軟推的, 仔細觀察apple 的 sample code, 偶而也會有這種style出現)

if (isHappy)
{
  // Do something
}
else 
{
  // Do something else
}

(2.) 冒號, 逗號後留一個空格

let names: [String: String] = ["developer": "frank", "team": "F&Z"]

(3.) -> 前後留一個空格

func myViewShouldReload() -> Bool  

(4.) { 前留一個空格

if (isHappy) {
  // Do something
}

(5.)空白行

空白行是必要的, 代表一個邏輯的轉折

func myViewShouldReload() -> Bool {
   var number = 0
   var title = "myName"

   self.doSomething()
   self.doAnotherThing()
}

註解

(1.) 最好的註解就是不需要使用註解, 由命名上就能了解程式的意義, 有時讀註解比讀code更花時間, 也必須花額外時間去維護註解.

(2.) TODO

if (isHappy) {
  // TODO: Do something
}

(3.) 警告特殊情形

if (isHappy) {
  // something will happen...
}

Protocol 實作

Preferred:

class ViewController: UIViewController {
}

// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
}

// MARK: - UIScrollViewDelegate
extension ViewController: UIScrollViewDelegate {
}

Not Preferred:

class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate {
  // all methods
}

宣告

(1.) 宣告空白Array & Dictionary

Preferred:

var titles: [String] = []
var songs: [String: Int] = [:]

Not Preferred:

var titles = [String]()
var songs = [String: Int]()

(2.) 使用structure儲存相關的變數

struct StoryboardID {
    static let viewController = "viewController"
    static let noteViewController = "noteViewController"
    static let newViewController = "newViewController"
}

(3.) 使用enum使參數變得有意義

enum payType :Int {
    case cash, card, other
}

MVC (Model, View, Controller)

MVC為iOS App 開發最常用的架構, 但Apple 提到除了 view controller, 還可以另外建立 model controller 和 helper controller, 讓程式的分工更為清楚.

(1.) Model Controller

負責實現 model 的相關功能. 比方你在做一個資料庫 App, 要處理 data的新增, 修改, 刪除, 查詢等動作, 可以另外定義一個dataController 實現來相關功能, 讓viewController更為精簡

(2.) Helper Controller

負責特定的功能, 例如可以建立一個 NetworkController, 專門處理 App與後台溝通的部分

Guard

(1.) 利用guard 判斷tableview的cell

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
        guard cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as? MyCell else {
            fatalError("dequeueReusableCell failed")
        }
        
        cell.initWithData()

        return cell
}

(2.) 利用guard 一次判斷

func saveData(data: MyData?, name:String?) {
    guard data != nil,
        name != nil,
        name.count > 0 else {
            return
    }
    
    //do something here
}

nil-coalescing operator

利用 ??語法設定變數為nil時的預設值

let userName = userNameTextField.text ?? "unknown"          
PreviousiOS BookNext[iOS] UnitTest With XCode

Last updated 6 years ago