-
Notifications
You must be signed in to change notification settings - Fork 0
팀 Swift Style Guide
SeungHwan Lee edited this page Jan 25, 2022
·
3 revisions
- 최소한의 import, 모듈 import시 알파벳순으로 import
- 최대 가로 길이는 100자 제한, 글자수 초과시 개행
- 들여쓰기: Space 4개
- : (콜론) 사용시 오른쪽에만 공백 (삼항연산자에서의 콜론은 예외, 삼항 연산자는 콜론 앞 뒤로 공백)
// Good var nameAgeMap: [String: Int] = [] // Bad var nameAgeMap: [String:Int] = [] var nameAgeMap: [String : Int] = []
- +, -, *, / 등 연산자 앞뒤에는 가독성을 위해 앞뒤로 공백 추가
- , (콤마) 사용시, 콤마 뒤에는 공백 추가
// Good let numbers = [1, 2, 3] // Bad let numbers = [1,2,3] let numbers = [1 ,2 ,3] let numbers = [1 , 2 , 3]
- 불필요한 괄호는 사용x 괄호는 필요할 때만 사용
- 2개 이상의 데이터를 반환할 때는 튜플보다는 struct를 고려, 튜플 사용시 각각의 필드에 이름을 붙이는걸 권장
- 상속이 발생하지 않는 클래스는 final 키워드로 선언
- 프로토콜을 채택할 때는 extension을 통해 관련된 매소드를 작성
- Switch문 사용시 default 사용을 지양 (의도적으로 case 지정)
- 파일의 경우 단일 타입일시, 파일명은 타입명과 같게 명명, 만약 프로토콜 준수로 기존 타입을 확장하는 경우라면 타입명 + 프로토콜명의 조합으로 명명
- lowerCamelCase: 함수, 메소드, 변수, 상수 등에 사용
- UpperCamelCase: 클래스, 구조체, 열거형, Extension 등에 사용
- 약어로 시작할 경우 소문자로 표기하고 그 외의경우 대문자로 표기
// Good let userID: Int? let html: String? let websiteURL: URL? let urlString: String? // Bad let userId: Int? let HTML: String? let websiteUrl: NSURL? let URLString: String?
- 함수의 경우 이름 앞에 get 사용 지양
// Good func name(for user: User) -> String? // Bad func getName(for user: User) -> String?
- Action 함수의 네이밍은 wasTapped 사용 (From Google Style Guide)
@objc private func ratingStarWasTapped(_ sender: UIButton?) { // .. }
- delegate 매소드 정의시, 첫 번째 매개변수는 delegate source 이름이어야 한다.
// Good func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String) func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool // Bad func didSelectName(namePicker: NamePickerViewController, name: String) func namePickerShouldReload() -> Bool
- 리턴 타입이 없는 경우 () 대신 Voide 사용
// Good func updateConstraintns() -> Void { // .. } typealias CompletionHandler = (result) -> Void // Bad func updateConstraintns() -> () { // .. } typealias CompletionHandler = (result) -> ()
- 한 줄 클로저의 경우 괄호 양쪽에 공백 추가
// Good let squares = [1, 2, 3].map { $0 * $0 } // Bad let squares = [1, 2, 3].map {$0 * $0}
- 제네릭의 경우 관계나 역할을 나타낼수 있는 의미있는 이름으로, upper camel case로 나타내야 한다. 단 관계나 역할을 나타낼수 없는 경우 T, U, V 사용 가능
// Good struct Stack<Element> { ... } func write<Target: OutputStream>(to target: inout Target) func swap<T>(_ a: inout T, _ b: inout T) // Bad struct Stack<T> { ... } func write<target: OutputStream>(to target: inout target) func swap<Thing>(_ a: inout Thing, _ b: inout Thing)
- Array Dictionary<T: U> 보다는 [T], [T: U] 사용
// Good var messages: [String]? var names: [Int: String]? // Bad var messages: Array<String> var names: Dictionary<Int, String>?
- 타입 추론이 가능하면 더 간결한 코드를 위해 타입은 생략
// Good let selector = #selector(viewDidLoad) view.backgroundColor = .red let toView = context.view(forKey: .to) let view = UIView(frame: .zero) // Bad let selector = #selector(ViewController.viewDidLoad) view.backgroundColor = UIColor.red let toView = context.view(forKey: UITransitionContextViewKey.to) let view = UIView(frame: CGRect.zero)
- 함수 정의가 최대 길이를 초과하는 경우 아래와 같이 개행
func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { // .. } func animationController( forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController ) -> UIViewControllerAnimatedTransitioning? { // .. }
- 함수 호출 코드가 최대 길이를 초과하는 경우, 파라미터이름을 기준으로 개행
let actionSheet = UIActionSheet( title: "정말 계정을 삭제하실 건가요?", delegate: self, cancelButtonTitle: "취소", destructiveButtonTitle: "삭제해주세요" )
- 파라미터에 클로저가 2개 이상일 경우 내려쓰기를 통해 가독성을 높인다.
UIView.animate( withDuration: 0.25, animations: { // .. }, completion: { finished in // .. } )
- // MARK: 연관된 코드 그룹핑, 해당 그룹에 대한 설명 명시
- // TODO: 추가적으로 할 일 명시
- // FIXME: 수정해야할 것 명시