## 발표 자료 대본
#### page 1
- 안녕하세요.
- iOS 10조
- Wavvie팀 입니다.
- 저희가 발표할 주제는
- 집중을 도와주는
- 음원 컨텐츠 앱
- JipJung의 개발기입니다.
#### page 2
- 저희 팀은 저를 포함하여 상진님, 수현님, 기완님 으로 총 4명으로 구성되어있습니다.
#### page 3
- 발표를 진행하기에 앞서
- 먼저 저희 앱의 시연 영상을 보여드리겠습니다.
- 전체 시간 배분상
- 재생 부분이 배속처리되어 어색한 점은
- 이해부탁드립니다.
// 스페이스바 - 재생
#### page 4
- 발표를 이어서 진행하도록 하겠습니다.
- 목차는 다음과 같습니다.
- 이 앱을 만들게 된 계기가 무엇이었는지,
- 구현을 위해 어떤 부분에 집중했는지,
- 그 과정에서 어떤 문제를 겪고 고민했는지에 대해 공유하는 순서로
- 발표를 진행하겠습니다.
#### page 5
- 먼저, JipJung 앱을 만들게된 계기는 무엇이었을까요?
#### page 6
- 단순한 기능 이상의 앱을 제공하고 싶었기 때문에
- 저희 팀은 "소리" 라는 주제로 모이게 되었습니다
#### page 7
- 소리만 제공하는 것은 조금 아쉽다는 생각이 들어서
- 동영상, 애니메이션 같은
- 시각 컨텐츠도 함께 제공하기로 의견을 모았습니다.
- 마침, 저희가 생각한 방향과 비슷한 앱을 찾게 되었고
- 기획,디자인보다 개발,문제해결에 집중하기 위해
- Tide라는 App을 클론하기로 했습니다.
#### page 8
- Tide는
- 풍부한 시청각 컨텐츠와
- 아름다운 애니매이션을 가지고 있는 명상 앱입니다.
- 저희는
- 이 앱의 애니메이션을 똑같이 구현하기 위해
- CGAffineTransform, CoreAnimation, SpriteKit을 사용했습니다.
- Tide와 JipJung 앱의 애니메이션을
- 같이 보여드리면서
- 저희가 애니매이션을 어떻게 구현했는지 설명하겠습니다.
#### page 9
- 첫번째 애니매이션은
- 좌우 스크롤에서 크기가 줄어들었다가 커지는 애니메이션입니다.
- 좌우로 스크롤 할 때
- 카드가 뒤쪽으로 살짝 빠지고
- 다음 카드가 올라오는 애니메이션을 확인하실 수 있습니다.
- 이 부분은
- 터치 포인트의 이동거리에 비례해서
- 크기와
- 모서리 곡률을
- 변경하는 방법으로 구현했습니다.
#### page 10
- 방금 보여드린 화면 아래 부분입니다.
- 여기서 보여드리고 싶은 부분은
- 위아래 스크롤에 따른 상단, 하단 View의 상호작용입니다.
- 위아래로 스크롤을 할 때,
- 우측의 순서도처럼
- 상단 View와 하단 View가 만나게 되면
- 함께 움직일 수 있도록 구현했습니다.
#### page 11
- 다음으로 보여드릴 애니메이션은
- 타이머 화면의 pulse 애니메이션입니다.
- 이 애니메이션은
- 중앙에 있는 원에서 물결이 퍼져 나가는 애니메이션입니다.
- 오른쪽 이미지처럼
- BezierPath(배지어 패스)로 레이어 위에 원 4개를 겹쳐서 그렸고,
- 크기 애니메이션과 투명도 애니메이션을
- CAAnimationGroup으로 묶어서 4초 간격으로 반복했습니다.
#### page 12
- 이번 애니메이션은
- 누적 시간을 측정하는 타이머 화면에서 사용되는
- Comet 애니메이션입니다.
- 이 애니매이션은
- 타이머 글자 주변을 혜성처럼 도는 애니메이션입니다.
- 오른쪽 이미지의 CAGradientLayer를 이용해 그라데이션 색을 설정하고,
- Circle 형태의 BezierPath를 적용했습니다.
#### page 13
- 마지막으로
- 심호흡 화면에서 사용되는 애니메이션입니다.
- 준비 상태에서는 초록색 원이 꿈틀거리고,
- 시작버튼을 누르면 카운트 다운과 함께
- 이어서 설명할
- 숨쉬기 애니매이션이 보여집니다.
#### page 14
- 심호흡 화면은 준비와 실행
- 2가지 상태로 구성되어있습니다.
- 이 두가지 상태에 대해
- 공통되는 애니매이션을 확인하실 수 있는데요,
- 바로 꿈틀거림 애니메이션 입니다.
- 준비 상태에서는 꿈틀거림 애니메이션만 실행되지만,
- 실행 상태에서는 스케일링 애니매이션, 텍스트 변경 애니매이션이 추가로 실행됩니다.
- 여기서 꿈틀거림 애니메이션은
- BezierPath로 도형을 여러개 생성하고
- 각 도형을 CABasicAnimation에 넣어
- 순차적으로 실행되게 구현하였습니다.
- 그리고 마지막으로
- CAAnimationGroup으로 묶고
- 재사용을 위해 파일을 분리하여
- 2가지 모드에서 각각 사용할 수 있게 했습니다.
- 꿈틀거림 애니메이션 말고도,
- 앞서 설명드린 pulse 애니메이션처럼 여러 화면에서 반복 사용되는 애니메이션은
- 분리하여 재사용성을 높였습니다.
- 이처럼 CoreAnimation을 사용하여
- Tide의 애니메이션을 똑같이 구현해보는 경험을 했습니다.
#### page 15
- Tide의 애니메이션을 똑같이 구현하고 나서,
- 저희만의 차별점을 주기 위해 새로운 음원모드인 다크모드를 추가했습니다.
- 다크모드는 기존의 편안한 분위기와 반대로
- 어둡고 신나는 분위기를 연출하기 위해
- SpriteKit의
- SKSpriteNode와 SKLightNode를 이용하여
- 조명 효과를 구현했습니다.
#### page 16
- 지금까지의 발표 내용으로는
- 개발 과정이
- 별로 어렵지않았다고 생각하실지 모릅니다.
- 하지만,
- 그 과정은 가시밭길이었습니다.
- 지금부터 이에 대한 저희의 경험을 공유하겠습니다.
//**********************************************************************
//********************** <-> 여기서 컨텍스트 스위칭 **************************
//**********************************************************************
- 안녕하세요. 계속 발표를 이어나가겠습니다.
#### page 17
- 첫번째 가시밭길은 Git과 함께 시작합니다.
- 저희 팀은 여러 Feature를 upstream/main으로 부터 따와서
- 작업 완료 후 Pull Request Merge로 합치고,
- Feature 작업 중 Main에 변경이 일어나면 Rebase로 다시 변경사항을 반영하는 방식으로 Git을 관리하고 있습니다.
#### page 18
- 그런데 두 Feature에서 모두 파일을 생성하게 되면 어떻게 될까요?
- 한번쯤 다들 겪어 보셨을 텐데 XCode는 먹통이 됩니다.
#### page 19
- 그러면 어떻게 해결할까요?? 프로젝트 첫주차 초보개발자들 답게 구글신의 도움을 받았습니다.
- gitattributes를 root에 생성하고 binary merge=union옵션을 주면 된다는 글을 발견했습니다.
- 실제로 파일을 여러 브랜치에서 생성하고 머지를 테스트 해보았을 때 아무런 문제가 없었습니다.
#### page 20
- 그렇게 프로젝트를 다시 진행하던 중 다음날 한분이 Rebase이후 작업이 안된다고 말씀하셨습니다.
- 그래서 다같이 줌에 모여서 하나하나 원인을 찾아보았습니다.
#### page 21
- 해당 과정에 관한 자세한 내용은 저희 Wavvie팀의 프로젝트 위키에서 확인 하실 수 있습니다.
- 요약하면
- 두 브랜치에서 동일 경로에 하위 폴더를 생성하면
- 합치는 과정에서 Union이 하단에 있는 Group 이하 구문은 변경되지 않은 것으로 처리해서
- 구조가 망가졌던 것입니다.
#### page 22
- 두가지 의견이 있었고 처음엔 1안으로 하려다 2안으로 결정했습니다.
- 아키텍쳐와 기능목록을 깔끔하게 정리하고 작업을 잘 분리하면
- conflict를 처리하면서 보낼 시간을 아낄 수 있다 생각했기 때문입니다.
- 폴더를 모두 생성한 후,
- git은 폴더에 파일이 없으면 추적되지 않기 때문에
- .gitkeep이라는 파일을 만들어서 폴더가 유지되도록 하였습니다.
#### page 23
- 저희가 이 과정을 통해 알게된 사실은
- 어떤 문제도 검색 한번에 처리할 수 없고
- 개념을 완전히 이해하고 있지 않다면,
- 새로운 버그를 만들어낼 수도 있다는 것입니다.
- 그리고 충돌은 언제나 있을 수 있으니
- Git에 대해서 이해하고 충돌을 잘 해결해보자 입니다.
#### page 24
- 두번째 가시밭길은 분업과 협업에 대한 문제였습니다.
- 팀원들 모두가 팀 단위의 협업에 낯설기도하고
- 비대면으로 진행되어 PR에 적힌 설명과 코드 리뷰만으로는
- 서로의 코드를 이해하기 힘들었습니다.
- 그래서 저희는
- 각자 맡은 부분의 로직을
- 그림으로 도식화하여 공유하고
- 질의응답을 하는 시간을 가졌습니다.
#### page 25
- 저희 JipJung 앱에서
- 타이머는 가장 핵심적인 기능 중 하나입니다.
- 기본적인 시간제한이 있는 타이머,
- work와 relax가 반복되는 뽀모도로 타이머,
- 제한 없이 시간을 기록하는 인피티니 타이머,
- 심호흡을 도와주는 Breath들의
- 화면에서 쓰이기 때문에
- 타이머의 상태를 명확하게 정의해야할 필요가 있었습니다.
- 이를 위해
- 타이머 State Diagram을 작성하여 공유하였습니다.
#### page 26
- 음원 재생 기능또한 여러 페이지에서 사용되었기 때문에 State Diagram으로 팀원들 끼리 공유했습니다.
- 각자 혼자서 코드를 이해하려했다면 많은 시간이 소요되었겠지만
- 이러한 Diagram을 작성하며 로직을 설명하는 시간을 가졌기 때문에
- 팀원의 코드를 빠르게 이해할 수 있었습니다.
#### page 27
- 세번째 가시밭길은 Tide와 동일한 무한 스크롤을 구현하는 과정에서 발생했습니다.
- 처음에는 단순히 그림과 같이
- CollectionView를 기반으로 앞뒤에 더미 셀을 추가하여
- 마치 스크롤이 무한대인 것처럼 보이도록 구현했습니다.
#### page 28
- 이렇게 CollectionView로 구현을 하고 나서 확인을 하니
- CollectionView Reusable에 의한
- 화면 깜빡임 문제가 있었습니다.
#### page 29
- 깜빡임 문제 해결을 위해
- CollectionView의 Prefetch라는 기능에 대해 알아보았습니다.
- 아쉽게도
- Prefetch는 현재 셀 주변과 진행방향에 대한 로딩만 가능하기 때문에
- End to End로 이동해야하는 현재의 요구사항에서는
- prefetch 기능을 사용할 수 없었습니다.
- 그래서 저희는 원하는 기능을 가진 View를
- 직접 구현하기로 했습니다.
#### page 30
- View는 3개를 돌려가며 사용하고
- 화면에 필요한 데이터는 배열을 순환하는 형태로 가져와서
- 무한 스크롤 화면을 구현했습니다.
- 오른쪽 영상을 보면
- 의도한대로 작동하는 화면을 볼 수 있습니다.
- 자세한 내용은 저희 Wavvie팀의 프로젝트 위키에서 확인 하실 수 있습니다.
#### page 31
- 팀원과의 고민과 노력을 통해 해결을 했던 이슈도 있지만
- 추후 해결하고 싶은 문제 또한 남아 있습니다.
- 지난 4주차 배포에서 발견한 이슈입니다.
- 이 발표를 듣고 계시는 아이폰 사용자분들은
- 어떤 기종을 사용하고 계신가요?
- 아마 가장 근래에 나온 iPhone 13부터
- 노치가 처음 등장한 iPhone X,
- 혹은 작은 폰을 선호하시면 아이폰 SE도 있으실겁니다.
- 그 많은 기종 중 단 하나,
- 아이폰12 실기기에서만 특정 기능 실행 시,
- 다음 동영상처럼 앱이 갑자기 죽어버렸습니다.
- 이를 해결하기 위해 다양한 기기를 테스트했습니다.
- 아이폰12 프로, 아이폰X, XR, 아이패드 프로 5세대의 실기기에서는
- 아무 문제가 없었고,
- 문제가 발생한 아이폰 12의 시뮬레이터에서도
- 문제는 없었습니다.
- 오직
- 아이폰 12 실기기에서만
- 다음과 같은 로그를 남기면서 앱이 죽었습니다.
#### page 32
- 구체적인 콘솔 에러로그가 없어서
- 왜 죽는지 파악할 수 없었기 때문에
- 어디에서 crash가 나는지 먼저 파악하고자 했습니다.
-
- TestFlight를 이용해 아이폰12를 가진 캠퍼분들에게 배포를 했는데,
- 앱이 죽을 때 리포트 팝업이 뜨지 않아 다른 방법을 찾아야 했습니다.
-
- 저희는 파일서버로 파이어베이스를 이용하고 있었기 때문에
- 파이어베이스에서 제공하는 기능 중 하나인
- 크래시리틱스를 연결하여 리포트를 분석하려 했지만
- 이 방법 역시 리포트는 오지않았습니다.
#### page 33
- 그 다음 선택지로,
- Instruments를 사용하여 문제가 발생하는 부분을 관찰했습니다
- 특정조건에 CPU사용량이 증가하는 것을 볼 순 있지만,
- CPU사용량이 늘어서 터지는지,
- 터지면서 CPU사용량이 늘어나는지는 파악할 수 없었습니다.
- 메모리쪽에서 순환참조가 발생하지도 않았고,
- 메모리의 과다사용에 의한 프로세스 종료도 아니었습니다.
- 메모리 문제가 아니라면
- 애니메이션 연산에 문제가 있지 않을까 추측을 하였습니다.
- 초록색으로 화면을 가득채우는 애니메이션의 스케일링 크기를 줄였더니
- 문제가 해결되었습니다.
/// 애니메이션을 위한 클릭
- 아쉽게도 정확한 원인을 찾지 못해서
- 이에 대한 Apple의 기술 지원을 요청하였고
- 현재 진행 중 입니다.
- 이 과정에서 분석 도구과 배포 도구를 활용하여
- 문제를 해결하는 과정을 경험할 수 있었습니다.
#### page 34
- 이상으로 iOS10조의 발표였습니다.
- 이전의 발표에서 팀원 각각의 역할에 대한 질문이 있으셔서 미리 말씀드리자면
- 화면에 보이는 바와 같이 ~ (표 읽고 설명)
- 궁금하신 부분 질문해주시면 답변드리겠습니다.
- 감사합니다.