-
Notifications
You must be signed in to change notification settings - Fork 2
๐ HMH Swift Style Guide
๐ฅ ์ฝ๋๋ ํ๋ช ์ด ์ง ๊ฒ์ฒ๋ผ ์์ฑํ๋ ๊ฒ์ด ๋ชฉํ์ ๋๋ค. SwiftLint๋ ์ฌ์ฉํ์ง ์๋ ๋์ , ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ์ ์ฑ์ค๋ฝ๊ฒ ํด์ฃผ์ธ์.
UpperCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
-
ViewController
,TableViewCell
,CollectionViewCell
์ค์ด์ง ์๊ณ ์ฌ์ฉ
-
์์๋ณผ ์ ์๋ ๋ค์ด๋ฐ์ ์ฌ์ฉํด์ฃผ์ธ์!
-
lowerCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
ex.
nameList
-
์์๋ณผ ์ ์๋ ๋ค์ด๋ฐ ์ฌ์ฉํ๊ธฐ
-
ํจ์ ์ด๋ฆ์๋ lowerCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
-
Action ํจ์์ ๋ค์ด๋ฐ์ '์ฃผ์ด + ๋์ฌ + ๋ชฉ์ ์ด' ํํ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Tap(๋๋ ๋ค ๋)*์ย
UIControlEvents
์ย.touchUpInside
์ ๋์ํ๊ณ , *Press(๋๋ฆ)*๋ย.touchDown
์ ๋์ํฉ๋๋ค. - will~์ ํน์ ํ์๊ฐ ์ผ์ด๋๊ธฐ ์ง์ ์ด๊ณ ,ย did~๋ ํน์ ํ์๊ฐ ์ผ์ด๋ ์งํ์ ๋๋ค.
-
should~๋ ์ผ๋ฐ์ ์ผ๋กย
Bool
์ ๋ฐํํ๋ ํจ์์ ์ฌ์ฉ๋ฉ๋๋ค.
- Tap(๋๋ ๋ค ๋)*์ย
-
API ๊ด๋ จ ํจ์๋ get, post, put, delete๋ฑ์ ์ ๋์ฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
-
์ข์ ์:
func backButtonDidTap() { // ... }
-
๋์ ์:
func back() { // ... } func pressBack() { // ... }
-
enum์ ์ด๋ฆ์๋ UpperCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
-
enum์ ๊ฐ case์๋ lowerCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ข์ ์:
enum Result { case .success case .failure }
๋์ ์:
enum Result { case .Success case .Failure } enum result { case .Success case .Failure }
- ํ๋กํ ์ฝ์ ์ด๋ฆ์๋ UpperCamelCase๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- Delegate์ผ ๊ฒฝ์ฐ
Delegate
/ ์ด์ธ์๋Protocol
์ ๋ฏธ์ฌ๋ฅผ ์ฌ์ฉํด์ฃผ์ธ์
Protocol PickerDelegate { .. }
-
setUI
: UI ์์ฑ๊ณผ ๊ด๋ จ๋ ๋ด์ฉ์ ์์ฑํฉ๋๋ค.-
setHierarchy
: ๋ทฐ ๊ณ์ธต ๊ด๊ณ๋ฅผ ์์ฑํฉ๋๋ค. -
setConstraints
: ๋ ์ด์์ ์ค์ ๊ด๋ จ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
-
-
configure~
: ์ถํ์ ์คํ์ผ์ ์ ํด์ผ ํ ๋ ์ฌ์ฉํฉ๋๋ค. -
addTarget
: ๋ฒํผ์ Event๋ฅผ ์ถ๊ฐํ ๋ ์ฌ์ฉํฉ๋๋ค. -
setDelegate
: delegate๋ฅผ ์ค์ ํ ๋ ์ฌ์ฉํฉ๋๋ค.
ํจ์ ์์ฑ ์์
๐ ์๋ช ์ฃผ๊ธฐ ๊ด๋ จ ํจ์ โ ์ปค์คํ ํจ์ (๋ ์ด์์ ์ฐ์ ) โ objc ํจ์-
View ํ ํ๋ฆฟ
import UIKit import SnapKit import Then final class MainView: UIView { override init(frame: CGRect) { super.init(frame: frame) setUI() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func setUI() { setHierarchy() setConstraints() } func setHierarchy() { self.addSubview(scrollView) } func setConstraints() { view.snp.makeConstraints { $0.edges.equalToSuperview() } } func configureImageView() { view.backgroundColor = .white } func addTarget() { button.addTarget(self, action: #selector(backArrowButtonTapped), for: .touchUpInside) } }
extension
์ผ๋ก ๋ชจ๋ ๋ถ๋ฆฌํด์ ์์ฑํด์ฃผ์ธ์
- ํ๋์ extension์ ํ๋กํ ์ฝ ํ๋์ฉ๋ง ์ ์ฉํฉ๋๋ค.
๋ชจ๋ ์ํฌํธ๋ ์ํ๋ฒณ ์์ผ๋ก ์ ๋ ฌํฉ๋๋ค. ๋ด์ฅ ํ๋ ์์ํฌ๋ฅผ ๋จผ์ ์ํฌํธํ๊ณ , ๋น ์ค๋ก ๊ตฌ๋ถํ์ฌ ์๋ํํฐ ํ๋ ์์ํฌ๋ฅผ ์ํฌํธํฉ๋๋ค.
import UIKit
import SwiftyColor
import SwiftyImage
import Then
import URLNavigator
์๋ช ์ฃผ๊ธฐ ์์๋๋ก ์์ฑํด์ฃผ์ธ์
class MovieRatingViewController: UITableViewController {
// MARK: - View controller lifecycle methods
override func viewDidLoad() {
// ...
}
override func viewWillAppear(_ animated: Bool) {
// ...
}
// MARK: - Movie rating manipulation methods
@objc private func ratingStarWasTapped(_ sender: UIButton?) {
// ...
}
@objc private func criticReviewWasTapped(_ sender: UIButton?) {
// ...
}
}
-
ํจ์ ์ ์๊ฐ ์ต๋ ๊ธธ์ด๋ฅผ ์ด๊ณผํ๋ ๊ฒฝ์ฐ์๋ ์๋์ ๊ฐ์ด ์ค๋ฐ๊ฟํฉ๋๋ค.
func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath ) -> UICollectionViewCell { // doSomething() } func animationController( forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController ) -> UIViewControllerAnimatedTransitioning? { // doSomething() }
-
ํจ์๋ฅผ ํธ์ถํ๋ ์ฝ๋๊ฐ ์ต๋ ๊ธธ์ด๋ฅผ ์ด๊ณผํ๋ ๊ฒฝ์ฐ์๋ ํ๋ผ๋ฏธํฐ ์ด๋ฆ์ ๊ธฐ์ค์ผ๋ก ์ค๋ฐ๊ฟํฉ๋๋ค.
let actionSheet = UIActionSheet( title: "์ ๋ง ๊ณ์ ์ ์ญ์ ํ์ค ๊ฑด๊ฐ์?", delegate: self, cancelButtonTitle: "์ทจ์", destructiveButtonTitle: "์ญ์ ํด์ฃผ์ธ์" )
๋จ, ํ๋ผ๋ฏธํฐ์ ํด๋ก์ ๊ฐ 2๊ฐ ์ด์ ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ ๋ฌด์กฐ๊ฑด ๋ด๋ ค์ฐ๊ธฐํฉ๋๋ค.
UIView.animate( withDuration: 0.25, animations: { // doSomething() }, completion: { finished in // doSomething() } )
-
if let
ย ๊ตฌ๋ฌธ์ด ๊ธธ ๊ฒฝ์ฐ์๋ ์ค๋ฐ๊ฟํ๊ณ ํ ์นธ ๋ค์ฌ์๋๋ค.if let user = self.veryLongFunctionNameWhichReturnsOptionalUser(), let name = user.veryLongFunctionNameWhichReturnsOptionalName(), user.gender == .female { // ... }
-
guard let
ย ๊ตฌ๋ฌธ์ด ๊ธธ ๊ฒฝ์ฐ์๋ ์ค๋ฐ๊ฟํ๊ณ ํ ์นธ ๋ค์ฌ์๋๋ค.ยelse
๋ยguard
์ ๊ฐ์ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ์ ์ฉํฉ๋๋ค.guard let user = self.veryLongFunctionNameWhichReturnsOptionalUser(), let name = user.veryLongFunctionNameWhichReturnsOptionalName(), user.gender == .female else { return }
๋น ์ค
-
๋น ์ค์๋ ๊ณต๋ฐฑ์ด ํฌํจ๋์ง ์๋๋ก ํฉ๋๋ค.
-
๋ชจ๋ ํ์ผ์ ๋น ์ค๋ก ๋๋๋๋ก ํฉ๋๋ค.
-
MARK ๊ตฌ๋ฌธ ์์ ์๋์๋ ๊ณต๋ฐฑ์ด ํ์ํฉ๋๋ค.
-
extension ์ ์ ์ค ๋ฐ๊ฟ์ ํ๋๋ง.
// MARK: Layout override func layoutSubviews() { // doSomething() } // MARK: Actions override func menuButtonDidTap() { // doSomething() }
์ฌ์ฉ์ ์ง์ํ๊ณ , ์ค๋ฅ๊ฐ ๋ฐ์ํ ๋ / ๊ผญ ํ์ํ ๋๋ง ์ฌ์ฉํด์ฃผ์ธ์
๊น๋ํ ์ฝ๋ ์์ฑ์ ์ํด ์ฃผ์์ ์ต๋ํ ์์ฑํ์ง ์์ต๋๋ค.
-
๊ฐ๋ฅํ๋ค๋ฉด ๋ณ์๋ฅผ ์ ์ํ ๋ ํจ๊ป ์ด๊ธฐํํ๋๋ก ํฉ๋๋ค.ย [Then](https://github.com/devxoul/Then)์ ์ฌ์ฉํ๋ฉด ์ด๊ธฐํ์ ํจ๊ป ์์ฑ์ ์ง์ ํ ์ ์์ต๋๋ค.
let label = UILabel().then { $0.textAlignment = .center $0.textColor = .black $0.text = "Hello, World!" }
-
Literal์ String๊ณผ Image๋ฅผ ํ ํ์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
enum ImageLiterals { enum NavigationBar { static var icArrowLeft: UIImage { .load(named: "ic_back")} } }
-
์์๋์ง ์๋
class
๋final class
๋ก ์ ์ธํด์ฃผ์ธ์ -
class
์์ ๋ณ์๋ค์private
์ผ๋ก ์ ์ธํด์ฃผ์ธ์ -
๊ฐ์ ์ธ๋ํ์ ์ฌ์ฉ์ ์ง์ํฉ๋๋ค.