λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Swift

SwiftLintλ₯Ό μ μš©ν•˜λ©΄μ„œ μˆ˜μ •ν•œ κ²ƒλ“€πŸ™€

πŸ₯μž…μ‚¬ μ „μ—λŠ” ν”„λ‘œμ νŠΈλ₯Ό ν•  λ•Œ, 항상 SwiftLintλ₯Ό μ μš©ν•˜λ©° κ°œλ°œν–ˆμ—ˆλ‹€.

 

μž…μ‚¬ ν›„, νšŒμ‚¬ ν”„λ‘œμ νŠΈμ—μ„œλŠ” λ¦°νŠΈκ°€ μ μš©λ˜μ–΄ μžˆμ§€ μ•Šμ•˜κ³ , κ·Έ ν•„μš”μ„±μ„ 느껴 린트 μ μš©μ„ μ œμ•ˆν–ˆλ‹€. μž‘μ„±λ˜μ–΄ 있던 μ½”λ“œλ“€μ—μ„œ μˆ˜λ§Žμ€ μ—λŸ¬κ°€ 났고, λ‹€μ†Œ 번거둜운 μž‘μ—…λ“€λ„ μžˆμ—ˆμ§€λ§Œ, λ¬΄μ˜μ‹μ μœΌλ‘œ μž‘μ„±ν•˜λ˜ μ½”λ“œκ°€ ꢌμž₯λ˜λŠ” μ»¨λ²€μ…˜μ΄μ—ˆλ‹€λŠ” 것도 μ•Œκ²Œ 되고, λͺ¨λ₯΄λ˜ μ»¨λ²€μ…˜λ“€λ„ μƒˆλ‘œ μ•Œκ²Œ λ˜μ–΄ 의미 μžˆμ—ˆλ‹€κ³  μƒκ°ν•œλ‹€.

 

μ•„λž˜μ˜ 글은 ν”„λ‘œμ νŠΈμ— 린트λ₯Ό μ μš©ν•˜λ©° μˆ˜μ •ν–ˆλ˜ 과정에 λŒ€ν•œ 기둝이닀.πŸ‘©‍πŸ’»

 

2020λ…„ 8μ›” 14일 κΈˆμš”μΌ (warning: 999+, error: 999+)둜 μ‹œμž‘

SwiftLint 졜초 μ μš©μ‹œ μ•½ 11826개의 μ—λŸ¬λ‘œ μ‹œμž‘ν•¨πŸ˜± (999+/999+)

[ 2020.8.14 ]

 

 

μ œμ™Έν•  κ·œμΉ™κ³Ό νŒŒμΌλ“€μ„ μΆ”κ°€ν•˜λ©΄μ„œ 총 3702κ°œκ°€ 됨 (999+/105)

[ 2020.8.14 ]

// .swiftlint.yml

disabled_rules:
- leading_whitespace
- trailing_whitespace

excluded:
- 파일 μœ„μΉ˜/AppDelegate.swift
- Pods

 

 

line_length μ œμ™Έ μΆ”κ°€ 총 3473개 (999+/89)

[ 2020.8.14 ]

 

μ „λ°˜μ μœΌλ‘œ 길게 μž‘μ„±λœ μ½”λ“œλ“€μ΄ λ§Žμ•˜κ³ , μš°μ„  μ œμ™Έν–ˆλ‹€.

// .swiftlint.yml

disabled_rules:
- line_length

 

 

Libaries μ œμ™Έ 총 2553개 (999+/78)

[ 2020.8.14 ]

μ™ΈλΆ€ 라이브러리 νŒŒμΌλ„ μΆ”κ°€λ‘œ μ œμ™Έν–ˆλ‹€.

// swiftlint.yml

excluded:
- Libraries

 

 

2020λ…„ 8μ›” 18일 ν™”μš”μΌ (warning: 999+, error:78) 둜 μ‹œμž‘πŸ˜Ή

Force Cast Violation: Force casts should be avoided. (force_cast)

[ 24개 - 2020.8.18 ]

κ°•μ œ μΊμŠ€νŒ…ν•˜λŠ” 뢀뢄이 없도둝 μˆ˜μ •ν•˜μ˜€λ‹€. μ•„λž˜λŠ” κ·Έ 쀑 λŒ€ν‘œμ μΈ 2가지 μ˜ˆμ‹œλ‹€.

Dictionary extention μˆ˜μ •

[ 4개 - 2020.8.18 ]

λ”•μ…”λ„ˆλ¦¬μ˜ 킀값을 μ†Œλ¬Έμžλ‚˜ λŒ€λ¬Έμžλ‘œ λ°”κΎΈλŠ” ν•¨μˆ˜κ°€ extension에 μ •μ˜λ˜μ–΄ μžˆμ—ˆλŠ”λ°, κ°•μ œ μΊμŠ€νŒ…μ„ ν•˜λŠ” λ°©μ‹μ΄μ—ˆλ‹€.

μ•„λž˜μ˜ 좜처λ₯Ό 톡해 κ°•μ œ μΊμŠ€νŒ…μ΄ 없도둝 μˆ˜μ •ν•˜μ˜€λ‹€. 

// λ³€κ²½ μ „ 
extension Dictionary where Key: ExpressibleByStringLiteral {
    mutating func lowercaseKeys() {
        for key in self.keys {
            let str = (key as! String).lowercased()
            self[str as! Key] = self.removeValue(forKey: key)
        }
    }

    mutating func uppercaseKeys() {
        for key in self.keys {
            let str = (key as! String).uppercased()
            self[str as! Key] = self.removeValue(forKey: key)

        }
    }
}

// λ³€κ²½ ν›„
extension Dictionary where Key: StringProtocol {
    mutating func setAllKeysLowercase() {
        for key in self.keys {
            if let lowercaseKey = key.lowercased() as? Key {
                self[lowercaseKey] = self.removeValue(forKey: key)
            }
        }
    }

    mutating func setAllKeysUppercase() {
        for key in self.keys {
            if let uppercaseKey = key.uppercased() as? Key {
                self[uppercaseKey] = self.removeValue(forKey: key)
            }
        }
    }
}

// 좜처: https://stackoverflow.com/questions/33180028/extend-dictionary-where-key-is-of-type-string

 

UserDefaults value as! Int κ°•μ œ μΊμŠ€νŒ…

[ 2개 - 2020.8.18 ]

`Int`값을 κ°–κ³  μžˆλŠ” UserDefaultsλŠ” κ°•μ œ μΊμŠ€νŒ…ν•˜μ§€ μ•Šκ³  `func integer(forKey defaultName: String) -> Int`λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

// λ³€κ²½ μ „
return FontSize(rawValue: UserDefaults.standard.value(forKey: "ν‚€κ°’") as! Int)

// λ³€κ²½ ν›„
return FontSize(rawValue: UserDefaults.standard.integer(forKey: "ν‚€κ°’"))

 

Type Name Violation: Type name should only contain alphanumeric characters: 'LINE_POSITION' (type_name)
Identifier Name Violation: Enum element name should only contain alphanumeric characters: 'LINE_POSITION_TOP' (identifier_name)

[ 8개 - 2020.8.18 ]

μŠ€μœ„ν”„νŠΈμ—μ„œλŠ” μΉ΄λ©œμΌ€μ΄μŠ€πŸ«κ°€ κΈ°λ³Έ λͺ…λͺ…λ²•μœΌλ‘œ μ‚¬μš©ν•˜κ³  μžˆλ‹€. λ˜ν•œ Enum νƒ€μž…λͺ…은 λŒ€λ¬Έμžλ‘œ μ‹œμž‘ν•˜κ³ , caseλŠ” μ†Œλ¬Έμžλ‘œ μ‹œμž‘ν•œλ‹€.

// λ³€κ²½ μ „
enum LINE_POSITION {
    case LINE_POSITION_TOP
    case LINE_POSITION_BOTTOM
}

// λ³€κ²½ ν›„ 
enum LinePosition {
    case top
    case bottom
}

 

Force Try Violation: Force tries should be avoided. (force_try) 

[3개 - 2020.8.18 ]

try! ꡬ문을 μ‚¬μš©ν–ˆλŠ”λ° μ—λŸ¬κ°€ λ°œμƒν•˜λ©΄ λŸ°νƒ€μž„ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€κ³ , 앱이 κ°•μ œ μ’…λ£Œλ˜λ―€λ‘œ try? ꡬ문이 ꢌμž₯λœλ‹€.

// λ³€κ²½ μ „
let realm = try! Realm()

// λ³€κ²½ ν›„
let realm = try? Realm()

 

Shorthand Operator Violation: Prefer shorthand operators (+=, -=, *=, /=) over doing the operation and assigning. (shorthand_operator) 2889 (999+, 9)

[ 1개 - 2020.8.18 ]

연산을 ν•  λ•Œ, ν”„λ‘œνΌν‹°λ₯Ό 반볡적으둜 λͺ…μ‹œν•˜λŠ” 것보닀 μΆ•μ•½λœ μ—°μ‚° ν‘œν˜„μ„ μ“°λŠ” 것을 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
naviHeight = naviHeight + top

// λ³€κ²½ ν›„
naviHeight += top

 

Vertical Whitespace Violation: Limit vertical whitespace to a single empty line. Currently 2. (vertical_whitespace) 2946 (999+, 9) 

[ 100μ—¬κ°œ - 2020.8.18 ]

μ½”λ“œ 사이에 ν•œ μ€„μ”©λ§Œ 띄도둝 μˆ˜μ •ν–ˆλ‹€.

 

Colon Violation: Colons should be next to the identifier when specifying a type and next to the key in dictionary literals. (colon) 

[ 900μ—¬κ°œ - 2020.8.18 ]

μŠ€μœ„ν”„νŠΈμ—μ„œλŠ” νƒ€μž… μ •μ˜(let a: Int?)λ‚˜ λ”•μ…”λ„ˆλ¦¬μ—μ„œ(Dictionary[key: _, value: _]) 콜둠`:`을 μ‚¬μš©ν•  λ•Œ, μ•žμ€ 뢙이고 λ’€λŠ” ν•œ μΉΈ 슀페이슀λ₯Ό λ„£λŠ” 게 μΌλ°˜μ μ΄λ‹€. λ§Žμ€ 뢀뢄이 그렇지 μ•Šμ•„, λͺ¨λ‘ μˆ˜μ •μ„ ν•˜μ˜€λ‹€.

// λ³€κ²½ μ „
var localized:String {}

// λ³€κ²½ ν›„
var localized: String {}

 

Trailing Semicolon Violation: Lines should not have trailing semicolons. (trailing_semicolon) (999+, 9) 

[ 4개 - 2020.8.18 ]

μ½”λ“œ 끝에 μ„Έλ―Έμ½œλ‘ `;`이 λΆ™μ–΄ μžˆλŠ” κ²½μš°κ°€ μžˆμ—ˆλ‹€. μŠ€μœ„ν”„νŠΈμ—μ„œλŠ” μ„Έλ―Έμ½œλ‘ μ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μΌλ°˜μ μ΄λ―€λ‘œ μ‚­μ œν–ˆλ‹€.

 

 

Unneeded Break in Switch Violation: Avoid using unneeded break statements. (unneeded_break_in_switch) (999+, 9) 

[ 10개 - 2020.8.18 ]

μŠ€μœ„ν”„νŠΈμ˜ Switch 문은 caseλ₯Ό λ§Œμ‘±μ‹œν‚¨ 후에 λ‹€μŒ case둜 fall throughλ₯Ό ν•˜μ§€ μ•Šμ•„, break문이 ν•„μš”μ—†λ‹€.  case에 λŒ€ν•œ λ™μž‘μ΄ 아무것도 없을 λ•Œλ§Œ μ‚¬μš©ν•˜λ©΄ 되기 λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ break문을 μ œκ±°ν–ˆλ‹€.

 

 

Unneeded NotificationCenter Removal Violation: Observers are automatically unregistered on dealloc (iOS 9 / macOS 10.11) so you should't call removeObserver(self) in the deinit. (unneeded_notification_center_removal) 

[ 4개 - 2020.8.18 ]

(μŠ€μœ„ν”„νŠΈλŠ” 더 이상 ν•„μš”ν•˜μ§€ μ•Šμ€ μΈμŠ€ν„΄μŠ€λ₯Ό μžλ™μœΌλ‘œ ν• λ‹Ή ν•΄μ œν•˜μ—¬ λ¦¬μ†ŒμŠ€λ₯Ό ν™•λ³΄ν•œλ‹€. SwiftλŠ” μžλ™ μ°Έμ‘° 계산(ARC)을 톡해 μΈμŠ€ν„΄μŠ€μ˜ λ©”λͺ¨λ¦¬ 관리λ₯Ό μ²˜λ¦¬ν•œλ‹€. μΌλ°˜μ μœΌλ‘œ μΈμŠ€ν„΄μŠ€ 할당이 ν•΄μ œλ  λ•Œ μˆ˜λ™μœΌλ‘œ 정리할 ν•„μš”κ°€ μ—†λ‹€.)

 

OS X 10.11와 iOS 9.0λΆ€ν„° NSNotificationCenter 및 NSDistributedNotificationCenterλŠ” 더 이상 할당이 ν•΄μ œλ˜λ €λŠ” λ“±λ‘λœ μ˜΅μ €λ²„μ—κ²Œ μ•Œλ¦Όμ„ 보내지 μ•ŠλŠ”λ‹€. λ”°λΌμ„œ, μ˜΅μ €λ²„κ°€ ν• λ‹Ή ν•΄μ œ λ°©λ²•μœΌλ‘œ 등둝을 μ·¨μ†Œν•  ν•„μš”κ°€ μ—†λ‹€.

-[NSNotificationCenter addObserverForName : object : queue : usingBlock] λ©”μ„œλ“œλ₯Ό ν†΅ν•œ 블둝 기반 μ˜΅μ €λ²„λŠ” μ‹œμŠ€ν…œμ΄ μ—¬μ „νžˆ μ΄λŸ¬ν•œ μ˜΅μ €λ²„μ— λŒ€ν•œ κ°•λ ₯ν•œ μ°Έμ‘°λ₯Ό λ³΄μœ ν•˜λ―€λ‘œ 더 이상 μ‚¬μš©ν•˜μ§€ μ•Šμ„ λ•ŒλŠ” 등둝을 ν•΄μ œν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ μ œλŒ€λ‘œ μ œκ±°ν•΄ μ£Όμ§€ μ•ŠμœΌλ©΄ μ˜΅μ €λ²„κ°€ μ†Œμ†λœ κ°μ²΄κ°€ ν•΄μ œλ˜μ—ˆμ„ λ•Œ, Notification μ΄ μ „λ‹¬λ˜λ©΄ 앱이 μ£½λŠ”λ‹€.

 

λ”°λΌμ„œ, deinitμ—μ„œ removeObserver(self)λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„ λ˜λ―€λ‘œ μ‚­μ œν•˜μ˜€λ‹€. 

 

 

Unused Closure Parameter Violation: Unused parameter "timer" in a closure should be replaced with _. (unused_closure_parameter) 

[ 54개 - 2020.8.18 ]

μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” ν΄λ‘œμ € νŒŒλΌλ―Έν„°λ“€μ„ `_` μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μžλ‘œ λ³€κ²½ν•˜μ˜€λ‹€. 

// λ³€κ²½ μ „
webRTCClient?.set(remoteSdp: description, completion: { (error) in

// λ³€κ²½ ν›„
webRTCClient?.set(remoteSdp: description, completion: { _ in

 

 

2020λ…„ 8μ›” 19일 μˆ˜μš”μΌ (warning: 741, error:9)둜 μ‹œμž‘πŸ€―

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration. (opening_brace)  (741, 9)

[ 1076개 - 2020.8.19 ]

ν•¨μˆ˜ λ“±μ—μ„œ μ•žμ˜ λŒ€κ΄„ν˜Έ`{`λ₯Ό μ—΄ λ•Œ, μ•ž μͺ½μ— 곡백이 ν•œ μΉΈ λ“€μ–΄κ°€μ•Ό ν•˜λŠ”λ°, λΆ™μ–΄ μžˆλŠ” 것듀을 λͺ¨λ‘ μˆ˜μ •ν–ˆλ‹€.

// λ³€κ²½ μ „
func setTableView(){}

// λ³€κ²½ ν›„
func setTableView() {}

 

λ˜ν•œ, λΆˆν•„μš”ν•œ 주석과 iOS 버전별 λΆ„κΈ° 처리 뢀뢄을 μ‚­μ œν–ˆλ‹€. 개발 μ΄ˆλ°˜μ—λŠ” iOS 10λΆ€ν„° μ§€μ›ν•˜λ €κ³  ν–ˆμœΌλ‚˜, 개발 κ³Όμ •μ—μ„œ iOS 11둜 λ³€κ²½λ˜μ—ˆλ‹€. iOS 10을 μœ„ν•œ λΆ„κΈ° μ²˜λ¦¬κ°€ λ‚¨μ•„μžˆμ–΄, 이λ₯Ό μ‚­μ œν•˜μ˜€λ‹€. 

 

 

 

2020λ…„ 8μ›” 20일 λͺ©μš”일 (warning: 767, error: 8)둜 μ‹œμž‘πŸ˜£

Switch and Case Statement Alignment Violation: Case statements should vertically align with their enclosing switch statement. (switch_case_alignment) (767, 8) 

[ 10개 - 2020.8.20 ]

μŠ€μœ„ν”„νŠΈμ˜ Switch문은 Case ꡬ문과 μ•žμͺ½μ΄ λ™μΌν•˜κ²Œ 정렬이 λ˜μ–΄μ•Ό ν•˜λŠ”λ° 그렇지 μ•Šμ€ 뢀뢄이 μžˆμ–΄ μˆ˜μ •ν–ˆλ‹€.

// λ³€κ²½ μ „
switch something {
case .A:
    ...
    case .B:
    ...
    default:
    ...

// λ³€κ²½ ν›„
switch something {
case .A:
...
case .B:
...
default:
...

 

Control Statement Violation: if, for, guard, switch, while, and catch statements shouldn't unnecessarily wrap their conditionals or arguments in parentheses. (control_statement) (757, 8) 

[ 2개 - 2020.8.20 ]

μŠ€μœ„ν”„νŠΈμ—μ„œλŠ” if ꡬ문 λ“±μ˜ 쑰건 뢀뢄을 μ†Œκ΄„ν˜Έλ‘œ 묢지 μ•Šμ•„λ„ λœλ‹€.

// λ³€κ²½ μ „
if(widthRatio > heightRatio) {}

// λ³€κ²½ ν›„
if widthRatio > heightRatio {}

 

Comma Spacing Violation: There should be no space before and one after any comma. (comma) 

[ 26개 - 2020.8.20 ]

콀마`,`λ₯Ό μ‚¬μš©ν•œ 경우, κ·Έ μ•žμ€ λΆ™κ³  κ·Έ λ’€λŠ” ν•œ μΉΈμ”© 곡백이 λ“€μ–΄κ°€μ•Ό ν•˜λŠ”λ° 그렇지 μ•Šμ€ κ²½μš°λ“€μ΄ μžˆμ–΄μ„œ μˆ˜μ •ν–ˆλ‹€.

 

 

Statement Position Violation: Else and catch should be on the same line, one space after the previous declaration. (statement_position) 

[ 297개 - 2020.8.20 ]

else ꡬ문이 이전 κ΄„ν˜Έμ™€ λ™μΌν•œ 쀄에 ν‘œμ‹œν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
if {

}
else {

}



// λ³€κ²½ ν›„ 
if { 

} else {

}

 

Mark Violation: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...' (mark)  (445, 8)

[ 4개 - 2020.8.20 ]

Mark μ£Όμ„μ˜ ν˜•νƒœλŠ” `// MARK:` λ‚˜ `// MARK: -`λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

 

Returning Whitespace Violation: Return arrow and return type should be separated by a single space or on a separate line. (return_arrow_whitespace) (441, 8)

[ 42개 - 2020.8.20 ]

λ°˜ν™˜ νƒ€μž…μ„ μ•Œλ €μ£ΌλŠ” ν™”μ‚΄ν‘œ`->`와 λ°˜ν™˜ νƒ€μž… 사이에 곡백이 ν•œ μΉΈμ”© ν•„μš”ν•œλ° λΆ™μ–΄ μžˆλŠ” κ²½μš°λ“€μ΄ μžˆμ—ˆλ‹€.

// λ³€κ²½ μ „
func ν•¨μˆ˜()->λ°˜ν™˜νƒ€μž… {}

// λ³€κ²½ ν›„
func ν•¨μˆ˜() -> λ°˜ν™˜νƒ€μž… {}

 

Weak Delegate Violation: Delegates should be weak to avoid reference cycles. (weak_delegate) 

[ 5개 - 2020.8.20 ]

delegate ν”„λ‘œνΌν‹°λŠ” μˆœν™˜ μ°Έμ‘°λ₯Ό 막기 μœ„ν•΄ weak μ°Έμ‘°λ₯Ό ν•΄μ•Ό ν•œλ‹€. 

// λ³€κ²½ μ „
var delegate: 클래슀Delegate?

// λ³€κ²½ ν›„
weak var delegate: 클래슀Delegate?

 

Class Delegate Protocol Violation: Delegate protocols should be class-only so they can be weakly referenced. (class_delegate_protocol) 

[ 2개 - 2020.8.20 ]

delegate ν”„λ‘œν† μ½œμ€ μ•½ν•œ μ°Έμ‘°λ₯Ό ν•  수 μžˆλ„λ‘ class μ „μš©μ΄ λ˜μ–΄μ•Ό ν•œλ‹€.

// λ³€κ²½ μ „
protocol 클래슀Delegate {
...
}

// λ³€κ²½ ν›„
protocol 클래슀Delegate: class {
    ...
}

 

Trailing Newline Violation: Files should have a single trailing newline. (trailing_newline)

[ 8개 - 2020.8.20 ]

파일의 끝에 빈 쀄이 μ—¬λŸ¬ 쀄인 κ²½μš°κ°€ μžˆμ—ˆλ‹€. 파일의 끝에 빈 쀄은 ν•œ μ€„λ§Œ λ“€μ–΄κ°€λŠ” 것을 ꢌμž₯ν•œλ‹€.

 

 

No Space in Method Call Violation: Don't add a space between the method name and the parentheses. (no_space_in_method_call) (378, 8)

[ 6개 - 2020.8.20 ]

λ©”μ„œλ“œ 호좜 μ‹œμ— λ©”μ„œλ“œμ™€ κ΄„ν˜Έ 사이에 곡백이 λ“€μ–΄κ°€λŠ” κ²½μš°κ°€ μžˆμ—ˆλ‹€. λΆ™μ΄λŠ” 것을 ꢌμž₯ν•˜κ³  μžˆλ‹€.

 

 

Syntactic Sugar Violation: Shorthand syntactic sugar should be used, i.e. [String: Int] instead of Dictionary<String, Int>. (syntactic_sugar)

[ 102개 - 2020.8.20 ]

Dictionary νƒ€μž…μ„ μ‚¬μš©ν•  λ•Œ, `Dictionary<Key, Value>` 보닀 `[Key: Value]`둜 λͺ…μ‹œν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
var νŒŒλΌλ―Έν„° = Dictionary<String, Int>()

// λ³€κ²½ ν›„
var νŒŒλΌλ―Έν„° = [String: Int]()

 

 

Syntactic Sugar Violation: Shorthand syntactic sugar should be used, i.e. [Int] instead of Array. (syntactic_sugar)

[ 32개 - 2020.8.20 ]

Array νƒ€μž…μ„ μ‚¬μš©ν•  λ•Œ, `Array<Element>` 보닀 `[Element]`둜 λͺ…μ‹œν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
var νŒŒλΌλ―Έν„° = Array<String>()

// λ³€κ²½ ν›„
var νŒŒλΌλ―Έν„° = [String]()

 

 

Void Return Violation: Prefer -> Void over -> (). (void_return) 

[ 1개 - 2020.8.20 ]

Void νƒ€μž…μ„ λ°˜ν™˜ν•˜λŠ” 경우, 빈 κ΄„ν˜Έ `()`λ₯Ό μ“°λŠ” 것보닀 `Void`λ₯Ό λͺ…μ‹œν•˜λŠ” 것을 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
func ν•¨μˆ˜(completion: @escaping () -> ()) {}

// λ³€κ²½ ν›„
func ν•¨μˆ˜(completion: @escaping () -> Void) {}

 

 

Computed Accessors Order Violation: Computed properties should declare first the getter and then the setter. (computed_accessors_order) 

[ 17개 - 2020.8.20 ]

μ—°μ‚° ν”„λ‘œνΌν‹°μ— `get`κ³Ό `set`의 μˆœμ„œκ°€ `get`이 λ¨Όμ € λ‚˜μ™€μ•Ό ν•œλ‹€. 

 

 

Implicit Getter Violation: Computed read-only properties should avoid using the get keyword. (implicit_getter) 

[ 1개 - 2020.8.20 ]

`set`을 ν•˜μ§€ μ•ŠλŠ” 읽기 μ „μš© μ—°μ‚° ν”„λ‘œνΌν‹°μ˜ 경우 `get` ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

 

 

Vertical Parameter Alignment Violation: Function parameters should be aligned vertically if they're in multiple lines in a declaration. (vertical_parameter_alignment) 

[ 4개 - 2020.8.20 ]

ν•¨μˆ˜ νŒŒλΌλ―Έν„°λ“€μ΄ λ”°λ‘œ ν•œ 쀄씩 μž‘μ„±λ˜μ–΄ μžˆμ—ˆλŠ”λ°, κ·Έ νŒŒλΌλ―Έν„°λ“€μ΄ μ •λ ¬λ˜μ§€ μ•Šμ€ κ²½μš°κ°€ μžˆμ—ˆλ‹€. 

 

 

 

2020λ…„ 8μ›” 21일 κΈˆμš”μΌ (warning: 244, error: 8)둜 μ‹œμž‘πŸ€”

For Where Violation: where clauses are preferred over a single if inside a for. (for_where) 

[ 8개 - 2020.8.21 ]

for λ¬Έ μ•ˆμ—μ„œ if 문으둜 쑰건 확인을 ν•˜λŠ” 경우, 그보닀 for문에 where 절 μ‚¬μš©μ„ ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
for index in 3..<array.count {
    if index % 2 == 1 {
    ...
    }
}

// λ³€κ²½ ν›„
for index in 3..<array.count where index % 2 == 1 {
...
}

 

 

Immutable value 'str' was never used; consider replacing with '_' or removing it 

[ 2개 - 2020.8.21 ]

μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μƒμˆ˜κ°€ 있으면 μ™€μΌλ“œμΉ΄λ“œ μ‹λ³„μž `_`둜 λŒ€μ²΄ν•˜κ±°λ‚˜ μ‚­μ œν•œλ‹€.

 

 

Empty Enum Arguments Violation: Arguments can be omitted when matching enums with associated types if they are not used. (empty_enum_arguments) 

[ 2개 - 2020.8.21 ]

Switchλ¬Έμ—μ„œ enum을 μ‚¬μš©ν•  λ•Œ, enum의 μ—°κ΄€ 값을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μ‚­μ œν•΄λ„ λœλ‹€.

// Ex)
enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

// λ³€κ²½ μ „
switch productBarcode {
case .upc(_,_,_,_):
    print("UPC: \(productBarcode.self)")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}

// λ³€κ²½ ν›„
switch productBarcode {
case .upc:
    print("UPC: \(productBarcode.self)")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}

 

 

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument. (multiple_closures_with_trailing_closure) 

[ 12개 - 2020.8.21 ]

ν΄λ‘œμ €κ°€ μ—¬λŸ¬ 개 μžˆλŠ” ν•¨μˆ˜μ˜ 경우, λ§ˆμ§€λ§‰ ν΄λ‘œμ € νŒŒλΌλ―Έν„°λ₯Ό μΆ•μ•½ν•˜μ§€ μ•ŠλŠ” 것을 더 ꢌμž₯ν•œλ‹€.

// λ³€κ²½ μ „
UIView.animate(withDuration: 0.2,
               animations: {}, 
}) { _ in
    self.removeFromSuperview()
}

// λ³€κ²½ ν›„
UIView.animate(withDuration: 0.2,
      	      animations: {},
      	      competion: { _ in
       	          self.removeFromSuperview() 
})

 

 

Legacy Constructor Violation: Swift constructors are preferred over legacy convenience functions. (legacy_constructor) 

[ 6개 - 2020.8.21 ]

μŠ€μœ„ν”„νŠΈμ—μ„œλŠ” 였래된 C ν•¨μˆ˜λ³΄λ‹€ βœ¨μƒˆλ‘œμš΄ sturct initializerλ₯Ό μ‚¬μš©ν•˜κΈ°λ₯Ό ꢌμž₯ν•˜κ³  μžˆλ‹€. 

// λ³€κ²½ μ „
NSMakeRange(0, length)

// λ³€κ²½ ν›„
NSRange(location: 0, length: length)

 

 

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace. (closure_parameter_position) 

[ 13개 - 2020.8.21 ]

ν΄λ‘œμ €μ˜ νŒŒλΌλ―Έν„°κ°€ λ‹€μŒ μ€„λ‘œ λ„˜μ–΄κ°€ μžˆλŠ” κ²½μš°κ°€ μžˆμ—ˆλŠ”λ°, νŒŒλΌλ―Έν„°λ“€μ΄ ν΄λ‘œμ €μ˜ κ΄„ν˜Έμ™€ 같은 쀄에 μœ„μΉ˜ν•΄μ•Ό ν•œλ‹€λŠ” 것이닀.

 

 

Redundant Discardable Let Violation: Prefer _ = foo() over let _ = foo() when discarding a result from a function. (redundant_discardable_let) 

[ 12개 - 2020.8.21 ]

ν•¨μˆ˜μ˜ λ°˜ν™˜ 값을 μ‚¬μš©ν•˜μ§€ μ•Šμ„ λ•Œ, `let _  = ν•¨μˆ˜()`보닀 κ·Έλƒ₯ `_ = ν•¨μˆ˜()` 둜 μ‚¬μš©ν•˜λŠ” 것이 더 μ’‹λ‹€.

μ•„λ‹ˆλ©΄ ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ @discardableResultλ₯Ό λΆ™μ—¬μ£Όλ©΄ λ°˜ν™˜ 값이 μ‚¬μš©λ˜μ§€ μ•Šλ”λΌλ„ μ—λŸ¬κ°€ λœ¨μ§€ μ•Šκ²Œ ν•  수 μžˆλ‹€. 

// λ³€κ²½ μ „
let _ = ν•¨μˆ˜λͺ…()

// λ³€κ²½ ν›„
_ = ν•¨μˆ˜λͺ…()

OR

@discardableResult
func ν•¨μˆ˜λͺ…() -> λ°˜ν™˜κ°’ {

}

 

 

Unused Optional Binding Violation: Prefer != nil over let _ = (unused_optional_binding) 

[ 2개 - 2020.8.21 ]

μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ˜΅μ…”λ„ 바인딩은 nil이 μ•„λ‹Œ 것을 ν™•μΈν•˜λŠ” 방식이 더 μ’‹λ‹€.

// λ³€κ²½ μ „
if let _ = λ³€μˆ˜ {}

// λ³€κ²½ ν›„
if λ³€μˆ˜ != nil {}

 

 

Redundant Optional Initialization Violation: Initializing an optional variable with nil is redundant. (redundant_optional_initialization) 

[ 1개 - 2020.8.21 ]

μ˜΅μ…”λ„ λ³€μˆ˜λΌλ©΄ μ΅œμ΄ˆμ— μžλ™μœΌλ‘œ nil둜 μ΄ˆκΈ°ν™”κ°€ 되기 λ•Œλ¬Έμ— λͺ…μ‹œν•΄μ£Όμ§€ μ•Šμ•„λ„ λœλ‹€.

// λ³€κ²½ μ „
var λ³€μˆ˜λͺ…: String? = nil

// λ³€κ²½ ν›„
var λ³€μˆ˜λͺ…: String?

 

 

Redundant String Enum Value Violation: String enum values can be omitted when they are equal to the enumcase name. (redundant_string_enum_value)

[ 19개 - 2020.8.21 ]

String νƒ€μž…μ˜ Enumμ—μ„œ λ™μΌν•œ 값이라면 μ€‘λ³΅μœΌλ‘œ 쓰지 μ•Šμ•„λ„ μ‚¬μš©ν•  수 μžˆμ–΄ μ‚­μ œν•˜μ˜€λ‹€.

// λ³€κ²½ μ „
enum CallType: String {
   case video = "video"
   case voice = "voice"
 }

// λ³€κ²½ ν›„
enum CallType: String {
    case video
    case voice
}

 

 

Identifier Name Violation: Variable name should be between 3 and 40 characters long: 'vc' (identifier_name)

[ 60개 => 28개 - 2020.8.21 ]

ViewController λ³€μˆ˜κ°€ 'vc'둜 λŒ€λΆ€λΆ„ μž‘μ„±λ˜μ–΄ μžˆμ—ˆλŠ”λ°, μ’€ 더 λͺ…ν™•ν•˜κ²Œ νŠΉμ • 컨트둀러 λ³€μˆ˜λͺ…μœΌλ‘œ λ³€κ²½ν•˜μ—¬ μ–΄λ–€ λ·°μ»¨νŠΈλ‘€λŸ¬μΈμ§€ μ•Œ 수 μžˆλ„λ‘ μˆ˜μ •ν–ˆλ‹€.

 

 

Expression implicitly coerced from 'Date?' to 'Any'

[ 2개 - 2020.8.21 ]

μ•”μ‹œμ μœΌλ‘œ Any νƒ€μž…μœΌλ‘œ κ°•μ œλœ Date? νƒ€μž…μ„ String νƒ€μž…μœΌλ‘œ λ°”κΏ”μ£Όμ—ˆλ‹€.

// λ³€κ²½ μ „
print("date: ", Date νƒ€μž… λ³€μˆ˜)

// λ³€κ²½ ν›„
print("date: \(String(describing: Date νƒ€μž… λ³€μˆ˜))")

 

 

File Line Length Violation: File should contain 400 lines or less: currently contains 401 (file_length)

[ 9개 - 2020.8.21 ]

- 400쀄 μ΄ν•˜λ‘œ 큰 μˆ˜μ • 없이 κ°„λ‹¨νžˆ 쀄일 수 μžˆλŠ” 2개의 파일만 μˆ˜μ •ν–ˆλ‹€.

 

 

Orphaned Doc Comment Violation: A doc comment should be attached to a declaration. (orphaned_doc_comment)

[ 40개 => 29개 2020.8.21 ]

- λ¬Έμ„œ 주석이 μ•„λ‹Œλ° '/' 기호λ₯Ό 3개 이상 μ“°λŠ” 곳이 μžˆμ—ˆλ‹€. ν•„μš”ν•œ 뢀뢄을 μ œμ™Έν•œ 3곳만 μˆ˜μ •ν–ˆλ‹€. 

 

 

Comment Spacing Violation: Prefer at least one space after slashes for comments. (comment_spacing)

- 주석 // λ‹€μŒμ— 곡백이 μžˆμ–΄μ•Ό 함.

 

 

Trailing Comma Violation: Collection literals should not have tailing commas. (trailing_comma)

[ 1개]

- μ»¬λ ‰μ…˜ μš”μ†Œ λ§ˆμ§€λ§‰ κ°’ 뒀에 콜둠이 뢙은 κ²½μš°κ°€ μžˆμ–΄ μ‚­μ œν–ˆλ‹€.

 

 

Closing Brace Spacing Violation: Closing brace with closing parenthesis should not have any whitespaces in the middle.(closing_brace)

[ 1개]

- λ‹«νžˆλŠ” μ†Œκ΄„ν˜Έ μ•ˆμ— μžˆλŠ” λ‹«νžˆλŠ” λŒ€κ΄„ν˜Έ 사이에 곡백이 μžˆμ–΄ μ‚­μ œν–ˆλ‹€.

 

 

μ΅œμ’…μ μœΌλ‘œ swiftlint.yml κ·œμΉ™ μˆ˜μ •

[ 2020.8.24 ]

이미 μž‘μ„±λ˜μ–΄ μžˆλŠ” μ½”λ“œμ˜ μˆ˜μ •μ΄ 크게 ν•„μš”ν•  것 κ°™μ•„ function, file λ“±μ˜ length, parameter count λ“±μ˜ κ·œμΉ™μ€ μ „λΆ€λ‹€ μˆ˜μ •ν•˜μ§€ λͺ»ν•˜κ³   μ œμ™Έλ₯Ό ν•˜μ˜€λ‹€. μ°¨μ°¨ λ¦¬νŒ©ν† λ§μ΄ 되면 쒋을 것 κ°™λ‹€.😏 length에 λŒ€ν•œ 쑰건도 맀우(?) λ„‰λ„‰νžˆ μ£Όμ—ˆλŠ”λ°.. 점차 μ½”λ“œ κ°œμ„ μ„ ν•  수 있길 κΈ°λŒ€ν•œλ‹€. 😁

disabled_rules:
- leading_whitespace
- trailing_whitespace
- line_length
- cyclomatic_complexity
- function_body_length
- function_parameter_count
- orphaned_doc_comment

opt_in_rules:
type_body_length:
    - 1000
    - 1500

file_length:
    warning: 3000
    error: 4000

type_name:
    min_length:
        warning: 1
    max_length:
        warning: 80
        error: 100

identifier_name:
    min_length:
        warning: 1

excluded:
- 파일 μœ„μΉ˜/AppDelegate.swift
- Pods
- Libraries