11월 3일 (수) 멘토링 - boostcampwm-2021/iOS04-OwnMyWay GitHub Wiki
멘토링
-
ViewModel Input/Output
-
ViewModel을 추상화할지 말지
-
레포지토리에서 에셋에 있는 로컬 제이슨 데이터에 접근하기 위해 NSDataAsset을 썼는데, 그게 Ukit에 의존적이라 레포지토리가 UIKIt에 의존하게 되어벌임 -> 우짠데
- 그냥 스토리지에 넣고 번들에서 로딩하면 됨 (파일을 로드해도 되고)
- JSON 시리얼라이저나 인코더/디코더 써서 원하는 형태로 바꾸면 됨
- 에셋 말고 파일로 가져오면 UIKit 의존성이 없어질 것이야
- 사실 크게 중요한 부분은 아니긴 함
- 리소스라서 되어있는거
- 정리: 프로젝트 파일 안에 json 파일이 존재하고 경로를 따서 불러오기
-
self를 명시적으로 붙이는게 좋은가?
- 객체의 프로퍼티나 함수를 사용할때 self를 사용하는 컨벤션의 기준을 어떻게 잡으면 좋을까
- 한 사람이 짠 것처럼 보일 수 있게 맞추는게 좋을텐데 말이야
- self는 장단이 없어보임 -> 다 붙이시는 편임 -> 안붙이는 팀도 많아서 다수결로 정하는 수준;
- 그 다음은 보통 파라미터가 3개 이상일때 개행을 어떻게 할까? -> 이것도 취향이라 가위바위보를 해서 지키면 될듯
- 집중해야하는 컨벤션은 스위프트 스타일 가이드 -> 함수 이름 잘 짓기
- 위에서 하든 말든 통일만 되면 ㄱㅊ다면 함수명을 짓는 방법과 파라미터 이름에 조금 더 집중하는게 좋을 것임
- 기준은 스위프트 스타일 가이드
- 스타일 시트나 레이 벤더리치가 뭐지? 아무튼 여기서 만들어놓은거 따라도 좋음
- 객체의 프로퍼티나 함수를 사용할때 self를 사용하는 컨벤션의 기준을 어떻게 잡으면 좋을까
-
린트 라인 100자로 정해놨는데 너무 빡빡함
- xcode 설정을 애초에 100자로 정해놓으심
- 개행을 잘 활용하면 좋은데 한줄에 있어야 더 편한게 있을순 있음
- 이때는 별로 안중요한듯
- 린트를 무시하는 코드를 넣어서 의도적으로 무시하는 경우도 잇나봄
- 결론: 우리의 문제다
- 못들었음;;
- 무슨 옵션을 true로 한다고 하신거같음
- 읽기 편하게 이렇게 하시는 편임
- 파라미터도 옵션마다 개행하고 스타일 차이임
- extension을 활용해서 코드를 줄일수도 있음
- 반복적인걸 한명이 총대매고 익스텐션으로 정리해도 좋음
- 유틸성 코드를 테스트를 하는 것도 좋음
- 테스트는 어떻게하면 좋을지 다음주쯤에 보여주심
- convinience init을 만들어서 편의성 메소드를 만들어도 좋아
UIEdgeInsets(all: 12.0)
- 가독성이 좋아지니까 해보자
-
에펠탑을 검색할때 엪을 잡지 못함
- 검색 로직이 들어갈것 -> 가져온 데이터들중에서
- 한글자를 입력할때마다 검색을 함 -> 영어는 문제가 없는데 한글은 에펠을 치는 중에 엪이 될수도 있고...
- inputChanged에서 스트림을 흘려보내면 중간중간 결과값이 없어 깜빡거릴수도 있지 않을까? 걱정
- 검색은 요청량을 줄이기 위해 debounce를 사용함
- 쓰로틀과 디바운스라는 2가지 개념
- 쓰로틀은 요청을 몇초마다 짤라서 보내주는 형태임
- 디바운스는 검색이나 입력에 많이 사용
- 가나다를 치면 실제로 500ms로 디바운스를 걸면 500ms동안 발생한 이벤트중에서 가장 마지막것만 적용함
- 실제는 더 짧지만 (200ms)
- abc를 빠르게 치면 abc라는 마지막 요청만 감
- 쓰로틀이나 디바운스를 안걸면 가나다라만 쳐도 8번정도 요청이 간다
- 둘 중 하나를 걸면 되는데 콤바인에 이미 있음
- 액션을 넣을때 걸던지 디바운스 처리를 뷰모델에서 해도 됨
- 뷰컨에서 디바운스 처리를 해줘도 됨
- 쓰로틀은 버튼에서 많이함
- 버튼을 광클하면 푸시 2번되는 현상을 막을 수 있다
- 디바운스랑 다르게 한 번 누르면 몇초동안 이벤트를 무시함
- 마지막 이벤트가 상대적으로 더 중요하다 -> 디바운스
- 각 이벤트가 중요도가 동일하다 -> 쓰로틀
- 디바운스는 정해진 시간동안 같은 이벤트가 또 발생하면 이전의 이벤트를 취소시킴
- switchToLatest를 사용하면 이벤트를 중간에 취소시킬 수 있음
- 쓰로틀을 걸었다 -> ABCD를 입력했는데 AB와 ABCD로 두번 끊어서 들어갈 수도 있음 -> 저걸 쓰면 AB를 취소시킴
- 검색은 응답도 빠르고 자동완성을 보여줘야하다보니 이런걸 잘 쓰진 않는데 좋아요 요청 같은걸 하는 경우엔 쓰로틀을 걸고 저걸 또 추가함
-
코디네이터 차일드가 외잇을까
- 코디네이터가 가장 쉬운 구현이 이런거임
- 전체 코디네이터가 있고 거기에 모든 인터페이스 다 붙이기
- 조금 복잡한거 -> 앱 코디네이터 + 각 피쳐들에 대한 코디네이터가 차일드로 붙음
- 코디네이터라는 인터페이스 정의할때 트리구조로 차일드가 찢어짐
- 자식의 자식에도 코디네이터를 계속 붙이는 방식
- 모델이나 피쳐 단위로 쪼개질수도 있어서 이렇게 함
- ribs 개념 보면 트리구조로 붙여감
- 예시가 조금은 다른데 코디네이터도 비슷하게 구현됨
- 빡세게 구현하면 특정 화면에서 특정 도메인으로 이동할땐 step? 도 있대
- 앱 코디네이터에서 작업해보자 -> 화면이 별로 없음
- 인터페이스 여러개 붙이고 마지막에 다 모여서 어떻게 분리할지 고민해보기
- 딜리게이트 처리가 필요할 수도 있음
- A ->B 화면 이정도하는데 딜리게이트로 정보를 넘겨주면 편한데 코디네이터로 하면 이벤트를 코디네이터가 처리해줘야함
- 이런거 고민
- 나누는건 나중에 하자
- 트리구조로 관리가 된다
- 예시는 다른 화면 이동할때 탭이 다르다보니 코디네이터를 매번 선언해서 사용함
- 메모리 해제가 안되게 이렇게 작업하는거
- 차일드가 배열로 들고 있는 레퍼런스도 몇개 보고 트리로 구성하는 것도 어떤 화면이 갈 수 있는 경로를 담는건가?
- 안넣어주면 메모리에서 사라짐
- 우리가 만드는 앱 코디네이터는 씬딜리가 들고있으니 안사라지는데 이걸 쪼개서 차일드로 만들다보면 자식 코디네이트가 사라져버릴 수도 있음
- 코디네이터를 생성하고 start를 호출한 다음에 코디네이터가 사라져버리면 안되잖아
- 의존성을 받아서 아래로 그려주는거니까 사라지면 안된단말이야
- 차일드 구조가 명확해야하니까 다 지정하는거
- 무슨 뜻인지 이해가 안됨
- 코디네이터를 생성하고 start를 호출한 다음에 코디네이터가 사라져버리면 안되잖아
- 결론: 일단 앱코디네이터가 몰아놓고 나중에 정리
- 코디네이터가 가장 쉬운 구현이 이런거임
엔티티는 속성만 딱 있음 -> Codable같은거 없음 -> DTO를 한번더 가공해서 넘기기?
- MovieResponseDTO를 MovieDTO로 바꾸고 그걸 다시 MoviePage로 바꾸고 Movie로 바꾸기도 함
- 비즈니스 로직상 리모트와 로컬에서 가져온걸 동시에 보여주게 될수도
- 데이터 격리를 위해 계속 이렇게 변환해주는 것
- 네트워킹으로 받은것도 보여주고 캐싱해놓은것도 보여줌
- 전역적으로 쓰게되면 섞어서 보여주는게 힘들어짐
- 도메인의 영역으로 분리해줘야 종속되지 않고 작업이 가능할 것임
- Movie는 모두가 공유하는 진짜 딱 데이터만 있는 엔티티임
- 앱 전역적으로 사용되는 모델은 엔티티
네트워크/코어데이터에서 받아오는 타입 DTO는 코더블이 필요하니까 격리시켜놓고 도메인 레이어단으로 넘어올때 변환을 해서 사용한다!
- DTO 이름 자체가 네트워크나 코어데이터에서 받아올때 쓰는 데이터 전달용 객체임
- 이걸로 어떤 문제를 해결할 수 있는지를 알면 good
변경되면 좋을 부분
- 레포지토리 인터페이스랑 구현체가 같은 파일 안에 있음
- 실제 클린 아키텍처에선 두개의 위치가 다르다!
- 위치가 다르다는건: 레포리토리는 도메인 레이어 / 구현체는 데이터 레이어
- 모듈로 쪼개면 두개의 위치가 다름 -> 현재는 같은 앱 타겟이라 문제가 없음
- 프로토콜과 구현 객체는 원칙적으로 다른 위치 (파일이든 타겟이든) 에 있는게 더 좋은 구조임
- 클린 아키텍처대로 도메인 레이어, 데이터 레이어, 프레젠트 레이어를 아예 폴더 구조로 쪼개고 작업하는 것도 좋은 생각
- 엔티티와 DTO가 섞여서 사용되는듯
- 네트워킹하거나 로컬에서 데이터 가져오는 레포지토리 구현체 (클래스/구조체)는 데이터 레이어
- 유즈케이스는 ? 레이어
- 공부하는 중이니까 원리대로 해보는게 좋지 않겟나 질문: 뷰모델이랑 유즈케이스도 프로토콜로 추상화를 시켜놓음 -> 이때도 구현체와 인터페이스를 분리해야 하는가?
- 뷰와 뷰모델은 같은 프레젠테이션 레이어라 파일을 구분할 필요가 없음
- 레포지토리는 종속적인 인터페이스가 있고 구현체는 자유롭게 바뀔 수 있으니까
- 프레젠테이션과 데이터는 서로 모름
- 뷰모델은 유즈케이스를 통해 정보를 받아오고, 유즈케이스는 레포지토리를 통해 가져와야함
- 유즈케이스는 레포지토리의 인터페이스를 알아야 가져올 수 있겠지
- 근데 레포지토리가 실제 어떤 방식으로 가져올지는 유즈케이스가 몰라도 됨
- 구조를 잘 나누면 코드를 이해하기 쉬울것임 폴더 구조부터 그렇게 해보고 나중에 프레임워크로 분리해보는 것도 좋은 경험일 것임
final을 왜 붙이는지를 알아야함
- 다이나믹 디스패치 개념이 나옴
좋은건 코드컨벤션을 정리할때 이유가 납득이 안되면 거부하는 것도 좋음
- 왜 좋지? 회사에선 안좋을수도 ㅋㅋ
다음 버튼 구현을 누가 봤을때 이해가 잘 안될수도 -> 자세히 적기 화면 전환, 바인딩, 코어데이터 상관없어보이는 세 가지가 섞여있음
- 그룹핑이 잘 되어있으면 좋음
- 화면 전환 이슈라면 코디네이터를 이용해서 빈 화면을 볼 수 있다 이런것까지 하면 좋음
- 팀원들이 바빠지면 옆사람들이 뭐하는지 모를 수 있는데 이슈가 상세하면 그런걸 파악하기 좋음
코디네이터같은 초기세팅이 오래걸리는 것들이 끝나면 뒤쪽은 할만 할 것임
너무 설탕을 치는건 안좋지만 초반에 편의성 관련 작업을 해주면 좋음
회고 할때 피드백을 많이 해주면 좋음 -> 긍정적, 개선점 피드백
- 이걸 이렇게 해보면 더 좋지 않을까
- 이런 피드백을 안해보면 회사에서 솔직하지 않다는 인상을 줄 수도 있음
- 아쉬웠던 부분을 말해주는건 좋은데 너무 blame하면 안됨
캘린더에서 날짜 범위가 좀 늦게뜨는것 같다
- 222222