

## Ground Rules
### 규칙
- TIL, 일일 회고 작성 시간(매일 22시부터 1시간 작성 진행)
- 페어프로그래밍 시간 제한 최대 30분
- 공식문서 읽기
- 컨디션 안 좋을 때 말하기!!!
### 스크럼
- 오전 10시 디스코드에서 진행
- 금일 진행 사항 공유하기(오늘의 할일)
### 프로젝트 규칙
- 네이밍 준수하기(가이드 라인)
- 커밋 메시지 규칙 진행
- 코드에 대한 기록 그때그때 하기
- 캡쳐 많이 하기 찰칵찰칵📸
## 일일 스크럼
### 🙌 07/24 월
- 오늘의 컨디션
- hoon🐝: 졸려요🤣
- MINT😈: 약간 졸린? 여름엔 망고를 먹어야죠!
- 특이사항
- hoon🐝: 밈, 솜과 데이트 ㅎㅎ(with. 호섭이, 보름이)
- MINT😈: 미라클 모닝 장렬하게 실패! 온 세상이 행복하답니다 이제 도망쳐야짛ㅎㅎㅎ
- 오늘 할 일
- [x] 레드망고가 제철이에요~
- [x] 활동학습 예습
- [ ] STEP 1 구현
- [ ] STEP 1 PR
### 🙌 07/25 화
- 오늘의 컨디션
- hoon🐝: 나쁘지 않아요😊
- MINT😈: 흠
- 특이사항
- hoon🐝: 여행 계획하기 ㅋㅋㅋㅋ
- MINT😈: 훈 여수 납치 계획
- 오늘 할 일
- [x] STEP 1 구현
- [x] STEP 1 PR
- [x] 공식문서 스터디
- [ ] URL 공식문서 읽기
- [ ] 여수 계획
### 🙌 07/26 수
- 오늘의 컨디션
- hoon🐝: 몸이 무거워요오....😢
- MINT😈: 케챱이 없어요오....😢
- 특이사항
- hoon🐝: 스트레칭이 필요해요 ㅋㅋㅋㅋ, 1시 반부터 노가리 데이
- MINT😈: 2시부터 1시간 반 정도 토요 스터디 보충
- 오늘 할 일
- [ ] 네트워크 필요한 개체 공부
- [x] 클로저 공식문서
- [x] 활동학습 예습
- [ ] URL
### 🙌 07/27 목
- 오늘의 컨디션
- hoon🐝: 더워요🥵
- MINT😈: 낮잠 예정 후후
- 특이사항
- hoon🐝: 더워서 아무것도 하기가 싫어요 ㅋㅋㅋㅋㅋㅋㅋ 운동도 빼먹을 예정... <-더위 먹는것보다는 포동포동을 선택!
- MINT😈: 오뉴가 제 위에서 자고 이써요 ㅋㅅㅋ <- 오뉴 귀요미
- 오늘 할 일
- [x] URL Session
- [x] 하비께 디엠
- [ ] Github 예시 코드 찾기
### 🙌 07/28 금 (늦잠 꾸러기들~ 언제 일어나시는지 감시 중😏 어라?)
- 오늘의 컨디션
- hoon🐝: 피곤치 MAX!!🥱 <--아침 일찍 왔다가 낭패본 그
- MINT😈: 꽤나 좋아요~ 늦잠 최고 <--좀처럼 일어나지 않는 그녀
- 특이사항
- hoon🐝: 로웬 멘토링 4시 <--멘토링 하시는 동안 자고 올 예정
- MINT😈: 로데 멘토링 4시 <--멘토링 하시는 동안 자고 올 예정
- 오늘 할 일
- [x] README 작성
- [x] 멘토링 4시
- [ ] TCP 강의 영상 <--이거 언제보시나 기다리는 중(밤 10시에 작성!!히히)
- [ ] osi 7계층
- [x] 하비 답변 공부
- [ ] GitHub 예시 코드 찾기
- [ ] 망고쥬스 마시기 <--- ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 스파이망고 ㅋㅋㅋ
### 🙌 07/31 월 (왜 오늘 스크럼 안하시죵?? 저 기대하고 있는뎅!!)
- 오늘의 컨디션
- hoon🐝: 주말에 푹 쉬어서 상태가 좋습니다.😆 <- 꿀피부 그
- MINT😈: 엄청 많이 자서 기뻐요~ 😆 <- 푹자서 기쁜 그녀
- 특이사항
- hoon🐝: 오늘 열심히 책을 볼거에요.🔥🔥🔥
- MINT😈: 저도 책에 집중을 해보겠어요!🌊🌊🌊
- 오늘 할 일
- [x] HTTP 영상 보기
- [x] 책 읽기
### 🙌 08/01 화 (오늘은 무엇을 하실 예정이신가요??)
- 오늘의 컨디션
- hoon🐝: 푹 잤습니다.👍 <--오 푹 주무셨군요??
- MINT😈: 많이 먹었습니닿ㅎㅎㅎ <--맛있게 드셨어요??뭘 드셨을까용?🤩
- 특이사항
- hoon🐝: 오후에 치과! <--오호 오후에 치과가시는군요?
- MINT😈: 민트 점심 먹고 서울 올라가는-! <--응??오늘 서울 올라오세요??
- 오늘 할 일
- [x] HTTP 강의 끝까지
- [x] 책 읽기
### 🙌 08/02 수: (오늘 두 분은 쉬시나요?? 저 실시간 옵저빙하는것 같네요 😏) <-- ㅋㅋㅋㅋㅋ책만 읽은 하루~
- 오늘의 컨디션
- hoon🐝: 해피 해피😊
- MINT😈: 해피 민트!!
- 특이사항
- hoon🐝: 책 완독!!! 내용은 몰라요...🤣🤣🤣 <-- 우와 결국 완독하셨군요!!!
- MINT😈: 쏘오오오오오 해피 민트!!!!!!
- 오늘 할 일
- [x] 책 읽기
- [x] 5,6기 초청 취업 설명회 듣기
### 🙌 08/03 목
- 오늘의 컨디션
- hoon🐝: 몸이 무거워요. ㅋㅋㅋㅋㅋㅋㅋ <--훈 씻으셨나요?
- MINT😈: 꼬질 민트 <-- 킁킁(어디서 꼬수분내가..근데 꼬질민트 귀욤)
- 특이사항
- hoon🐝: 이따가 낮잠을... ㅎㅎ <-- 낮잠 필수!
- MINT😈: 저는 잠시 작은엄마 직장! <--오옷?견학가신건가요?
- 오늘 할 일
- [x] 활동 학습 예습
- [x] osi 7계층 정리
- [x] 오후 8시 멘토링 훈민트 둘 다
- [ ] TCP/IP 정리
### 🙌 08/04 금 (오늘은 무엇을 하실 예정이신가용? 불금인데~🥳)
- 오늘의 컨디션
- hoon🐝: 괜찮아요.🙂 <-- 어디가 어떻게 괜찮은거지요? 상세하게 알려주세요
- MINT😈: 민트 사망 <--민트 어디갔어요?!! 민트를 찾아주세요!
- 특이사항
- hoon🐝: 토요스터디 준비😂 <--화이팅입니다.
- MINT😈: 민트 패스 <--민트는 스크럼 패스인가요?
- 오늘 할 일
- [x] 하비와의 만남 <-- 만나셨나요?(두근두근🤩) 실패!
- [ ]
### 🙌 08/07 월
- 오늘의 컨디션
- hoon🐝: 주말이 행복했습니다😊
- MINT😈: 잠이 부족해서 보충해써요오
- 특이사항
- hoon🐝: 활동 학습 예습~!!
- MINT😈: 히히 기절 한 번 했습니다~
- 오늘 할 일
- [x] 활동 학습 예습
- [x] TLS/SSL 정리
- [ ] HTTP 버전별 정리
- [ ] Cache/cookie 정리
### 🙌 08/08 화 (오늘 스텝2 진행하시나요?!! 두분 화이팅입니다!)
- 오늘의 컨디션
- hoon🐝: 낫배드🙂
- MINT😈: 히히 열심히 걸은 민트😈
- 특이사항
- hoon🐝: 여권 찾기😢
- MINT😈: 훈민트 뽀에버😈
- 오늘 할 일
- [ ] Cache 정리
- [x] HTTPS 정리
### 🙌 08/09 수 (오늘 엄청 바쁘신 두 분~)
- 오늘의 컨디션
- hoon🐝: 아주아주아주 힘듭니다😩 훈 오늘은 낮잠 주무시죠 ㅋㅋㅋㅋ😈 <-- 여권 신청하고 오셨나요?
- MINT😈: 기절트.. 여독...<-- 민트의 행방을 찾습니다~
- 특이사항
- hoon🐝: 여권을 만들기 <-- 외식 예정아니십니까?..아니다 배달인가?
- MINT😈: 저녁은...외식.. <-- 두분 같이 드세요? (같이 먹고 싶다요)
- 오늘 할 일
- [X] URL cache 코드 짜기
- [ ] cache 발표자료 만들기
- [ ] TCP 및 HTTP 버전 별 정리
### 🙌 08/10 목 (훈, 민트 모두 건강 잘 챙기세요ㅠ_ㅠ)
- 오늘의 컨디션
- hoon🐝: 어제 푹쉬어서 좋습니다.😊 <--훈 괜찮으신가요? 네 (다행이네요)
- MINT😈: 집인데 집에 가고 싶은 기분 <--민트도 더위 안 먹게 조심하세요~, 저 그 기분 너무 잘알아요..
- 특이사항
- hoon🐝: 밀린 공부를 호다닥~
- MINT😈: 낮잠 잘래욥😴 <-낮잠 꿀잠
- 오늘 할 일
- [x] cache 발표자료 완성하기, 대본 작성하기
- [x] TCP 및 HTTP 버전 별 정리
- [x] 활동 학습 예습
### 🙌 08/11 금 (아싸!! 불금입니다!!)
- 오늘의 컨디션
- hoon🐝: 이상해요😕 <-이가 아프신건가요?
- MINT😈: 허리 아포요🥲 <-어랏??허리가..허리가 왜?..
- 특이사항
- hoon🐝: 병원을 다녀오겠습니다🏥 <--어랏? 허리는 민트가 아프신대 병원은 왜 훈이 가시죠?😲
- MINT😈: 스트레칭과 산책 필수~😈 <--맞아요 건강지켜야해요
- 오늘 할 일
- [ ] HTTP 버전 별 정리
- [x] 노션에 발표 정리
### 🙌 08/14 월
- 오늘의 컨디션
- hoon🐝: 점점 회복중입니다.😊
- MINT😈: 해피민트~!
- 특이사항
- hoon🐝: 활동 학습 예습
- MINT😈: 즐거운 활동학습! 내일 아부지 생신🎂
- 오늘 할 일
- [x] STEP 2 코드 샘플 찾기
- [x] 공식 문서
- [X] Core Data 활동학습 복습
### 🙌 08/15 화
- 오늘의 컨디션
- hoon🐝: 잘 잤습니다.😆
- MINT😈: 허리 아파서 의자를 정적인 걸로 바꿨어요ㅜㅜ 스트레칭과 자세교정이 시급합니다ㅜ
- 특이사항
- hoon🐝: 오후에 친구들과 여행 계획을 세웁니다.🛫
- MINT😈: 꿈에 훈이 나왔어요!😈
- 오늘 할 일
- [x] STEP 2 코드 샘플 탐색
- [ ] STEP 2 코드 작성
- [ ] STEP 2 PR
- [ ] 공식 문서
### 🙌 08/16 수
- 오늘의 컨디션
- hoon🐝: 푹 잤어요 ㅋㅋㅋㅋㅋㅋ🙂
- MINT😈: 굿~ 엄청 잤어요~
- 특이사항
- hoon🐝: 오후에 잠시 외출하고 오겠습니다.☺️
- MINT😈: 샤인머스캣이 맛있어요!🍇
- 오늘 할 일
- [x] STEP 2 코드 작성
- [x] STEP 2 PR
- [ ] 공식 문서
- [X] 활동 학습 예습
### 🙌 08/17 목
- 오늘의 컨디션
- hoon🐝: 조금 피곤합니다.
- MINT😈: 현재는 졸립니다ㅜ
- 특이사항
- hoon🐝: 활동학습 + 특강 예습
- MINT😈: 오늘 하루가 사라졌어요~
- 오늘 할 일
- [x] 활동학습 예습
- [x] 특강
### 🙌 08/18 금
- 오늘의 컨디션
- hoon🐝: 조금 피곤해요. 그래도 마지막 날!!!🥰
- MINT😈: 캬캬
- 특이사항
- hoon🐝: 아침에 병원을 다녀왔어요 ㅎㅎ. 저녁에는 저도 인천으로~✈️
- MINT😈: 저녁 약속 후후😆
- Mango: 어디가요! 나도 데려가요!!
- 오늘 할 일
- [ ] 리뷰 수정
- [ ] 공식 문서
- [ ] README 작성
- [ ] 망고 데리고 놀기
# 팀 회고
## 우리팀이 잘한 점
-
## 우리팀 개선할 점
-
## 서로에게 좋았던 점 피드백
## 서로에게 하고싶은 말
# PR: STEP 1
## 고민되었던 점
### `Unit Test`에서 `json` 파일 사용
- STEP 1에서는 `API` 서버와 실제 통신을 하지 않고 테스트하기 위해 `box_office_sample.json` 파일을 제공합니다. 제공된 `box_office_sample.json` 파일은 `Unit Test`의 목적으로만 사용될 거라는 예상 때문에 [`BoxOfficeTests`에 `json` 파일을 추가](https://stackoverflow.com/questions/46726498/add-test-assets-for-xctest)하였습니다. 새로운 `Asset Catalog`를 생성하고 `json` 파일을 추가 후 다음과 같이 사용하려고 하였습니다.
```swift
guard let json = NSDataAsset(name: "box_office_sample") else {
return
}
```
위와 같이 사용하면 파일을 불러오지 못하여 `json` 상수에 `nil`이 할당되는 문제가 있었습니다. 확인해 보니 사용하는 `Bundle`이 현재 `BoxOfficeTests` 번들이 아닌 점이 문제였습니다. 문제를 해결하기 위해 사용하는 번들을 지정해 주었습니다.
```swift
let bundle = Bundle(for: JsonDecodeTests.self)
guard let json = NSDataAsset(name: "box_office_sample", bundle: bundle) else {
return
}
```
`Bundle(for:)` 메서드를 사용하여 현재 지정된 클래스가 연결된 `NSBundle` 객체를 반환받고 이를 다시 넣어줌으로써 `box_office_sample`의 파일 위치를 특정하여 사용할 수 있었습니다.
## 해결이 되지 않은 점
### `Equatable protocol`을 외부 파일에서 `extension`으로 구현
- `Unit Test`를 진행하던 도중 `BoxOfficeItemInformation`을 구조체끼리 비교해 주고 싶었습니다. 특별한 타입을 구현한 게 아니라서 단순히 `Equatable`을 채택하면 테스트를 진행할 수 있었습니다. 그런데 저희는 해당 `Equatable protocol`이 단순히 `Unit Test`에서 확인해 보기 위한 것일 뿐이기에 `test file`로 빼주고 싶었습니다. 때문에 `extension`으로 옮겨서 `Equatable`을 채택해 주었는데 다음과 같은 에러가 발생하였습니다.

찾아보니 `Equatable`안에 구현되어 있는 `==` 메서드는 접근 권한이 `public`이 아니라서 다시 `public`으로 만들어주어야 하는 것이었습니다. 프로퍼티가 굉장히 많은데 이를 하나하나 작성해서 비교하는 것은 비효율적일 것 같아 내부의 프로퍼티들을 전부 다 반복으로 돌릴 수 있는 방법을 찾아보다가 결국 `BoxOfficeItemInformation`에서 가장 정체성을 나타내는 유일한 값인 `movieCode`를 비교하는 것으로 `extension`을 작성하였습니다.
```swift
extension BoxOfficeItemInformation: Equatable {
public static func == (lhs: BoxOfficeItemInformation, rhs: BoxOfficeItemInformation) -> Bool {
return lhs.movieCode == rhs.movieCode
}
}
```
# PR: STEP2
## 고민했던 점
### `URLSession shared` 사용
- URLSession 클래스가 task 생성을 위해 기본으로 제공하는 싱글톤 객체입니다. `shared`를 사용하는 경우 다음과 같은 제한이 있었습니다.
- 데이터가 서버에서 도착할 때 점진적으로 데이터를 얻을 수 없다.
- 기본 연결 동작을 사용자 지정할 수 없다.
- 인증 기능에 제한이 있다.
- 앱이 실행 중이지 않은 상태에서 다운로드나 업로드를 실행할 수 없다.
위와 같은 제한 사항이 존재하기 때문에 `shared`를 사용하여는 경우 일반적으로 `cache`, `cookie storage` 또는 `credential storage`를 커스텀 하여 사용하는 것을 피해야 합니다.
현재 프로젝트를 진행하며 위와 같은 제한 사항과 관련한 내용이 없기 때문에 `shared`를 사용하였습니다.
```swift
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
completion(.failure(.dataTaskFail))
return
}
guard let httpResponse = response as? HTTPURLResponse else {
completion(.failure(.responseCasting))
return
}
guard (200...299).contains(httpResponse.statusCode) else {
completion(.failure(.invalidStatus))
return
}
guard let data = data else {
completion(.failure(.noData))
return
}
completion(.success(data))
}
task.resume()
```
추가적으로 찾은 자료에서는 `shared`를 사용하는 경우 configuration을 사용하여 설정하는 부분에 대한 오버헤드가 없기 때문에 더 빠른 속도를 보인다는 내용이었습니다.
- 참고 자료 : [URLSession: shared vs default](https://stackoverflow.com/questions/57971904/shared-urlsession-vs-urlsession-with-default-configuration)
## 해결하지 못한 점
### `handler` 중복 합치기
- `fetchData` 메서드에 `escaping closure`를 사용해 `completion handler`를 구현하였습니다. `Result` 타입을 사용해 실패하면 `error`를 반환하고 성공하면 `data`를 반환하는데 그때 해당 `json data`를 `decode`해 사용할 수 있는 모델을 만들고 싶었습니다. 이때 `Decodable`을 채택한 2개의 서로 다른 모델 타입을 제외하고는 `completion handler`의 내용이 같기에 하나의 프로퍼티로 선언해 전달해주고 싶었습니다.
```swift
private let boxOfficeDataCompletion: (Result<Data, NetworkError>) -> Void = { result in
switch result {
case .success(let data):
guard let decodedData = BoxOfficeData.decode(data: data) else {
return
}
case .failure(let error):
print(error.localizedDescription)
}
}
```
위의 코드에서 guard let 안의 BoxOfficeData만 MovieInformation과 옵션을 줘서 번갈아가며 사용할 수 있게 해주고 싶었습니다.
- 위와 같은 이유로 다음과 같이 2가지 방법을 생각해 보았지만 두 방법 모두 성공하진 못했습니다.
1. closure로 타입 전달
```swift
private let boxOfficeDataCompletion: (Decodable, (Result<Data, NetworkError>)) -> Void = { type, result in
switch result {
case .success(let data):
guard let decodedData = type.decode(data: data) else {
return
}
case .failure(let error):
print(error.localizedDescription)
}
}
```
클로저로 타입을 전달해주는 방법입니다. 다만 이 경우 fetchData 함수에서도 성공한 경우 completion(.success((`type`, data)))로 fetchData에서부터 type을 전달해주어야 합니다. 그러나 이때 type을 전달해 줄 수가 없었습니다.
2. fetchData 함수를 부르는 함수에 타입 전달
```swift
func prepareData<T: Decodable>(request: URLRequest, type: T) {
let handler: (Result<Data, NetworkError>) -> Void = { result in
switch result {
case .success(let data):
guard let decodedData = type.decode(data: data) else {
return
}
print(decodedData)
case .failure(let error):
print(error.localizedDescription)
}
}
fetchData(request: request, completion: handler)
}
```
그러나 이렇게 한 후 사용이 가능한지 실험해보는 과정에서 다음과 같은 에러가 발생하며 Decodable 타입을 사용할 수가 없었습니다.

- 결국 합치지는 못하고 각각 다른 completion handler를 만들어 enum을 통해 전해줄 수 있게 구현하였습니다.
```swift
enum completion {
case boxOfficeData
case movieInformation
var handler: (Result<Data, NetworkError>) -> Void {
switch self {
case .boxOfficeData:
return NetworkManager().boxOfficeDataCompletion
case .movieInformation:
return NetworkManager().movieInformationCompletion
}
}
}
```
## 조언을 얻고 싶은 점
### `URLSession shared` 사용 예시
- 어떤 예시에서 `shared`를 사용하는 것이 좋은지를 찾지 못하였습니다. 기본적으로 `URLSession.init(configuration: .default)`를 바탕으로 `shared`가 만들어졌다고 하는데 어떤 경우에 `shared`를 사용할 수 있을까요? `default`와 `shared`를 사용하는 기준점이 위의 제한 사항 외에도 다른 이유가 있을까요?