/iOS07-DoolDa

우리 둘만의 다이어리, 둘다

Primary LanguageSwift

둘다 : 우리 둘만의 다이어리

Untitled


🦔🦔🦔

Swift Xcode


프로젝트 소개 🦔

친구와 단 둘이서 공유하고 싶은 추억이 있나요?

둘다에서 친구와 함께한 추억을 기록 해 보세요

페이지가 하나씩 채워질 수록 친구와의 관계도 깊어질 거에요


배포 링크 🔗

둘다를 직접 실행할 수 있는 배포링크입니다.

둘다 배포링크


Bool 바다 소개 🔥

S007 김민주 S017 박세원 S027 양승훈 S053 정지승
@minglely @ehWld @yabby1997 @JungJiSeung

동작 화면 📱

둘다의 실제 동작화면 입니다.🦔
페어링 화면 이미지 넣기 텍스트 넣기 스티커 넣기
페이지 보기 페이지 필터 페이지 수정 폰트 변경

주요 기능 ✨

🦔 친구와 연결하기

  • 당신의 코드로 친구를 초대해 보세요
  • 초대코드를 입력한 사람이 먼저 페이지를 작성할 수 있어요
  • 새로고침 버튼을 눌러서 친구와 연결되었는지 확인할 수 있어요

🦔 페이지 꾸미기

  • 하루의 내용을 글과 사진, 스티커로 기록해보세요
  • 원하는 속지의 색깔을 골라 다이어리의 분위기를 바꿔보세요

🦔 다이어리 보기

  • 좌측 상단의 버튼을 누르면 두가지 레이아웃 모드를 토글할 수 있어요
  • 필터 버튼으로 원하는 페이지를 골라보세요

🦔 페이지 수정하기 & 공유하기

  • 각 페이지를 수정하거나 공유할 수 있어요
  • 오른쪽 하단 편집 버튼으로 페이지를 수정할 수 있어요.
  • 왼쪽 하단 공유 버튼으로 페이지를 이미지로 저장하거나 다른사람과 공유할 수 있어요

🦔 푸시알림 보내기

  • 다이어리 작성을 완료하면 상대방에게 푸시알림이 전달돼요
  • 새로고침을 통해 상대방에게 다이어리 작성을 요청할 수 있어요

🦔 폰트 변경하기

  • 제공되는 다양한 폰트들 중 원하는 폰트를 선택할 수 있어요
  • 선택된 폰트로 앱 전반의 기본 폰트가 변경되며, 앱이 종료되어도 기본 폰트 선택이 유지돼요.

Architecture🏛 : MVVM-C

둘다에서 사용하고 있는 프로젝트 구조 입니다.

스크린샷 2021-12-03 오전 12 45 04

기술적 도전 💪

프로젝트를 진행하면서 저희가 시도한 기술적 도전을 소개합니다.

💵 다이어리 캐싱 with CoreData

  • 다이어리 페이지 캐싱을 위해 데이터베이스를 직접 관리하지 않아도 객체 인스턴스를 통해 CRUD작업을 할 수 있는 CoreData를 사용하였습니다.
  • 다이어리 페이지는 디스크에 캐싱하고 이에 대한 메타 데이터를 CoreData에 캐싱합니다. 다이어리 페이지 데이터를 사용할 때 CoreData 와 서버에 기록된 마지막 편집 시간을 비교하고, 이를 통해 서버로부터 다시 다이어리 페이지 데이터를 가져와야 하는지를 판단합니다. 이는 불필요한 통신을 줄여 통신 비용을 감소시키고, 더 나은 사용자 경험을 제공합니다.

🚜 Combine

  • 파이프라인을 통해 계층간 데이터 전달과 비동기 이벤트 처리를 가능하도록 하는 Combine framework를 사용하였습니다. 애플에서 직접 제공하는 First Party Framework인 만큼 가장 신뢰할 수 있으며, NotificationCenter 와 Timer 등 기존의 Swift 비동기 코드와도 통합하기 유리하다는 장점에 따라 이를 선택하였습니다.
  • UIControl과 UIGestureRecognizer의 이벤트를 위한 커스텀 Publisher와 Subscription 정의해 유저로부터 발생하는 비동기 이벤트에 대해서도 Combine 을 활용할 수 있도록 했습니다. 이를 통해 프로젝트 전반의 비동기 이벤트 처리에 있어 통일성과 코드 가독성을 향상시킬 수 있었습니다.

🏛 Clean Architecture & MVVM-C

  • 비즈니스 로직과 변경이 자주 발생하는 외부의 레이어를 명확하게 분리하여 결합도를 낮추고  ViewController 간의 의존성을 낮추기 위해서 Clean Architecture 기반의 MVVM-C 패턴을 선택했습니다.
  • ViewModel이 Coordinator 의 인터페이스를 통해 Scene을 전환시킬 수 있도록 하고, 각 Scene에 대한 의존성을 Coordinator 가 직접 주입하도록 했습니다. 이를 통해 ViewController 가 유저 입출력만을 담당하여 단일 책임 원칙을 지킬 수 있도록 했습니다. 이를 통해 각 객체 간의 결합도를 낮추고, 독자적으로 테스트가 가능한 구조로 설계하여 유지보수성을 높일 수 있었습니다.

🌚 다크모드 지원

  • iOS 13 버전 이후로 다크 모드 지원하도록 HIG에서 권장하고 있기 때문에, 둘다에서도 완벽한 다크모드를 지원하고자 했습니다.

🎢 CGAffineTransform

  • 모든 다이어리에 표시될 객체의 각도와 크기 조절을 가능하도록 해, 다이어리를 꾸미는 사용자의 자유도를 높이고자 했습니다. 이를 위해 사용자의 제스처를 인식하여 CGRect, scale, angle 값을 객체에 저장하고, 이를 실제 View에 보여주기 위한 변환 과정에서 CGAffineTransform을 활용했습니다.

🎨 DynamicAnimator

  • 시각적인 효과를 더해주기 위해 UIDynamicAnimator 를 활용했습니다

  • 중력 효과를 주기 위해서 UIGravityBehavior 를 사용했습니다.

  • 실제 기기가 받는 중력으로 애니메이션을 구현하기 위해 CoreMotion을 함께 사용했습니다.

  • 스티커간 충돌 효과를 주기 위해 UICollisionBehavior 를 사용했습니다.

  • 스티커에 탄성 효과를 주기 위해 UIDynamicItemBehavior를 활용했습니다.