Swift Style Guide

660 阅读2分钟

Delegate

func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool

Constans

enum Math {
  static let e = 2.718281828459045235360287
  static let root2 = 1.41421356237309504880168872
}

let hypotenuse = side * Math.root2

struct Configs {
    struct App {
        static let githubUrl = "https://github.com/"
        static let bundleIdentifier = "com.public.SwiftHub"
    }
}

Control Flow

for _ in 0..<3 {
  print("Hello three times")
}

for (index, person) in attendeeList.enumerated() {
  print("\(person) is at position #\(index)")
}

for index in stride(from: 0, to: items.count, by: 2) {
  print(index)
}

for index in (0...3).reversed() {
  print(index)
}
for item in collection where item.hasProperty {
  // ...
}

Lazy

lazy var locationManager = makeLocationManager()

private func makeLocationManager() -> CLLocationManager {
  let manager = CLLocationManager()
  manager.desiredAccuracy = kCLLocationAccuracyBest
  manager.delegate = self
  manager.requestAlwaysAuthorization()
  return manager
}

RxSwift

private var viewSubject = BehaviorSubject<Bool>(value: false)
public var viewStatus: Observable<Bool> {
    return viewSubject.asObservable()
}

Enum

public enum HTTPStatus: Int {
  case ok = 200

  case badRequest = 400
  case notAuthorized = 401
  case paymentRequired = 402
  case forbidden = 403
  case notFound = 404

  case internalServerError = 500
}

Func

  • 刷新视图的方法名要以 refresh 为首
  • 更新数据的方法名要以 update 为首
  • 调整视图的方法名要以 adjust 为首
  • 配置 configure
  • initialSetup
  • updateUIFromModel

Struct

Stanford

struct PlayingCard {
    
    /// Suit of the card
    var suit: Suit
    
    /// Rank of the card
    var rank: Rank
    
    /// Represents a Suit in a playing card
    enum Suit: String {
        case spades     = "♠️"
        case hearts     = "♥️"
        case clubs      = "♣️"
        case diamonds   = "♦️"
        
        /// Array containing all possible suits
        static var all: [Suit] = [.spades, .hearts, .clubs, .diamonds]
    }
    
    /// Represents the Rank in a playing card
    enum Rank {
        case ace
        case face(String) // ugly design
        case numeric(Int)
        
        /// The order of each Rank
        var order: Int {
            switch self {
            case .ace: return 1
            case .numeric(let pips): return pips
            case .face(let kind) where kind == "J": return 11
            case .face(let kind) where kind == "Q": return 12
            case .face(let kind) where kind == "K": return 13
            default: return 0 // ugly design
            }
        }
        
        /// Array containing all possible suits
        static var all: [Rank] {
            // Ace
            var allRanks: [Rank] = [.ace]
            
            // 2...10
            for pips in 2...10 {
                allRanks.append(.numeric(pips))
            }
            
            // Jack, Queen, King
            allRanks += [.face("J"), .face("Q"), .face("K")]
            return allRanks
        }
    }
}

// Make `PlayingCard` confrom to `CustomStringConvertible`
extension PlayingCard: CustomStringConvertible {
    /// String representation of a `PlayingCard`
    var description: String {
        return "\(rank)\(suit)"
    }
}

// Make `PlayingCard.Suit` confrom to `CustomStringConvertible`
extension PlayingCard.Suit: CustomStringConvertible {
    /// String representation of a `PlayingCard.Suit`
    var description: String {
        return rawValue
    }
}

// Make `PlayingCard.Rank` confrom to `CustomStringConvertible`
extension PlayingCard.Rank: CustomStringConvertible {
    /// String representation of a `PlayingCard.Rank`
    var description: String {
        switch self {
        case .ace: return "A"
        case .numeric(let pips): return String(pips)
        case .face(let kind): return kind
        }
    }
}

关键字

  • @discardableResult

View层级

  • container
  • content

Stop Using Booleans

enum BoolEnum {
    /// Bool have only we values, so declared on and off cases here.
    case on
    case off
    
    /// isOn and isOff varaibles for getting is on and off
    var isOn: Bool {
        self == .on
    }
    var isOff: Bool {
        self == .off
    }
    /// switchType method we can use to switch current value into another value
    mutating func switchType() {
        switch self {
        case .on:
            self = .off
        case .off:
            self = .on
        }
    }
    
    /// currentValue will give what is the current value.
    var currentValue : Bool {
        switch self {
        case .on:
            return true
        case .off:
            return false
        }
    }
}


/// Variable Declartion
var isDataLoading : BoolEnum = .on


/// check is data loading on
if isDataLoading.isOn {
    print("Loading is on")
}

/// check is data loading off
if isDataLoading.isOff {
    print("Loading is off")
}

/// Switch varaible state
isDataLoading.switchType()

/// Get current value of varaible
isDataLoading.currentValue

String

isEmpty vs. count == 0 O(1) vs O(N) 使用 isEmpty

参考