손영빈 // 책 시리즈 앱 만들기#1
Conversation
| enum CodingKeys: String, CodingKey { | ||
| case title, author, pages, summary, dedication, chapters | ||
| case releaseDate = "release_date" | ||
| } |
| var releaseDateFormatted: String { | ||
|
|
||
| // String -> Date로 변경 | ||
| let dateFormatter = DateFormatter() | ||
| dateFormatter.dateFormat = "yyyy-MM-dd" | ||
|
|
||
| // Date로 변경된 정보를 통해 순서 변경, MMMM, en_US로 locale 선언 : 07 -> July로 변경 | ||
| let dateToStringFormatter = DateFormatter() | ||
| dateToStringFormatter.dateFormat = "MMMM d, yyyy" | ||
| dateToStringFormatter.locale = Locale(identifier: "en_US") | ||
|
|
||
| let date = dateFormatter.date(from: releaseDate)! // 적용 | ||
| return dateToStringFormatter.string(from: date) // 다시 String으로 반환 | ||
|
|
||
| } |
There was a problem hiding this comment.
releaseDate를 String 타입으로 정의하지 말고 Date로 정의하면 어떨까 싶은데요.
String타입으로 사용하게 되니깐, String -> Date -> String으로 만들어지는데 비효율적이죠?
JSONDecoder에 dateDecodingStrategy라는 속성이 있는데, 이걸 사용해보세요.
|
|
||
| private var isFolded = false // 상태 저장용 | ||
| private var summaryText = "" // 텍스트 저장 | ||
| var onTapExtraButton: ((Bool) -> Void)? |
There was a problem hiding this comment.
onTapExtraButton 이걸 Delegate로 만들어보면 될듯해요
| override func layoutSubviews() { | ||
| super.layoutSubviews() | ||
|
|
||
| self.layer.cornerRadius = self.frame.height / 2 | ||
| self.clipsToBounds = true | ||
| } |
| extension ViewController { | ||
|
|
||
| func loadBooks() { | ||
| dataService.loadBooks { [weak self] result in |
| } | ||
|
|
||
| // 정보 업데이트 함수 분리, config mainView에 통합 | ||
| func infoUpdate(with book: Book, idx: Int) { |
There was a problem hiding this comment.
함수 네이밍은 동사부터 시작하면 좋을 것 같ㅇ,
idx: Int -> at index: Int
| // Delegate 사용 | ||
| extension ViewController: BookSummaryStackViewDelegate { | ||
|
|
||
| func onTapExtraButton(isFolded: Bool) { |
There was a problem hiding this comment.
delegate 메서드에도 일관된 네이밍 컨벤션이 있습니다.
일반적으로 delegate 메서드는 이벤트를 발생시키는 타입의 이름을 prefix로 사용하여,
이 이벤트가 어디에서 발생했는지를 시그니처만 보고도 알 수 있도록 합니다.
이 케이스에서는 BookSummaryStackView가 이벤트의 주체이므로
func bookSummaryStackViewDidTapExtraButton()
와 같은 형태가 더 적절해 보입니다.
이렇게 하면 delegate를 구현하는 쪽에서 어떤 뷰의 이벤트인지 명확해지고, 다른 delegate 메서드들과 함께 보았을 때도 의미 충돌이 없으며, UIKit delegate 네이밍 컨벤션(tableView(_:didSelectRowAt:) 등)과도 일관성을 유지할 수 있습니다.
| case parsingFailed | ||
| } | ||
|
|
||
| func loadBooks(completion: @escaping (Result<[Book], Error>) -> Void) { |
There was a problem hiding this comment.
@escaping 제거해보세요. 그리고 제거해도 왜 문제 없는지 생각해보고,
위에서 weak self 쓰는 부분에 코멘트 남겼는데 weak self 가 의미없는 이유와 함께
고민해보면 좋을 것 같습니다.
|
드디어 폴더를 만들고 파일 옮기기에 성공하셨네요! 🎉 |
| extraButton.setTitleColor(.systemBlue, for: .normal) | ||
| extraButton.titleLabel?.font = .systemFont(ofSize: 14) | ||
| extraButton.addTarget(self, action: #selector(extraButtonTapped), for: .touchDown) // 함수 연결 | ||
| extraButton.contentHorizontalAlignment = .trailing // 버튼 우측 배치 |
There was a problem hiding this comment.
스택뷰를 사용하지 않고 버튼 정렬만 trailing으로 하는 방법이 있었네요! 참고가 되었습니다
방법이 맞는지는 모르겠지만, 구현해보았습니다.