Skip to content

yujaehui/DearDay

Repository files navigation

Dear Day

디어데이 썸네일

기억하고 싶은 모든 날들을 간편하게 관리해보세요.

음양력 계산, 반복 계산, 알림 설정, 그리고 다양한 위젯과 공유 기능으로 중요한 날을 더욱 의미있게 만들어 주는 D-Day 관리 앱입니다.

Dear Day 앱스토어 다운로드


📚 목차

  1. ⭐️ 주요 기능
  2. 📸 스크린샷
  3. 💻 개발 환경
  4. 📋 설계 패턴
  5. 🛠️ 기술 스택
  6. 🚀 트러블 슈팅
  7. 🗂️ 파일 디렉토리 구조
  8. 🛣️ 향후 계획

⭐️ 주요 기능

1. D-Day 등록

  • 특정 날짜를 기준으로 디데이를 등록할 수 있습니다.
  • 날짜수 기반으로 디데이를 등록할 수도 있습니다.

2. D-Day 수정 및 관리

  • 등록된 디데이를 언제든 수정할 수 있으며, 데이터는 안전하게 관리됩니다.

3. 네트워크 기반 음력 날짜 지원

  • 음력을 기준으로 디데이를 등록하고, 양력으로 자동 변환할 수 있습니다.

4. 반복 계산 기능

  • 연 단위 또는 월 단위로 반복되는 디데이를 자동으로 계산합니다.

5. 다양한 정렬 및 그룹화

  • 디데이를 생성일, 제목, 디데이 등 다양한 기준으로 정렬할 수 있습니다.
  • 디데이를 그룹화하여 더 효율적으로 관리할 수 있습니다.

6. 기념일 관리

  • 중요한 기념일을 한눈에 확인하고, 디데이와 함께 관리할 수 있습니다.

7. 로컬 알림 지원

  • D-Day와 기념일에 대해 알림을 설정하여 중요한 날을 놓치지 않습니다.

8. 다양한 위젯 지원

  • 다양한 크기와 스타일의 위젯을 통해 디데이와 기념일을 홈 화면 및 잠금 화면에서 확인할 수 있습니다.

9. 다크 모드 지원

  • 다크 모드 환경에서도 앱을 편안하게 사용할 수 있습니다.

10. 인스타그램 스토리 공유 기능

  • 특별한 날을 인스타그램 스토리를 통해 간편하게 공유할 수 있습니다.
  • 감성적인 스타일로 꾸며진 디데이를 스티커 형태로 만들어 친구들과 공유할 수 있습니다.

📸 스크린샷

메인 타입 설정 디데이 타입 등록 날짜수 타입 등록 이미지 편집
정렬 및 그룹화 디데이 타입 디테일 날짜수 타입 디테일 날짜수 타입 기념일 인스타그램 스토리
홈 화면 위젯 잠금 화면 위젯 위젯 편집 위젯 리스트 편집 알림

💻 개발 환경

  • 개발 기간: 2024.10.14 ~ 2024.12.10
  • 앱 지원 iOS SDK: iOS 16.0 이상
  • 위젯 지원 iOS SDK: iOS 17.0 이상
  • Xcode: 15.0 이상
  • Swift 버전: 5.8 이상

📋 설계 패턴

  • MVVM: UI와 비즈니스 로직 분리
  • 싱글턴 패턴: 전역적으로 관리가 필요한 객체를 재사용하기 위해 사용
  • 프로토콜 기반 DI: 테스트 가능성과 유연성을 위한 의존성 주입 구현

싱글턴 패턴

전역적으로 관리가 필요한 객체들에 대해 싱글턴 패턴을 적용하여 일관성과 성능 최적화를 도모했습니다.

적용 이유

  • 일관된 전역 관리: 동일한 인스턴스를 재사용하여 코드 일관성 유지
  • 성능 최적화: DateFormatter와 같은 비용이 큰 객체의 재사용을 통해 성능 향상
  • 중복 방지: 반복적인 리소스 초기화 방지 및 전역 접근 보장

프로토콜 기반 DI

유연한 설계와 향후 테스트 가능성을 고려하여 프로토콜 기반 DI 방식을 적용했습니다.

적용 이유

  • Service Layer: API 호출과 데이터 처리를 위한 인터페이스 설계
  • 유연한 설계: 프로토콜을 사용하여 구현체를 쉽게 교체 가능
  • 테스트 준비: Mock 객체를 활용한 테스트 작성 가능성 확보
  • 결합도 감소: 클래스 간 의존성 최소화

적용된 주요 영역

  • DDayRepositoryProtocol
    • Realm 기반 데이터 저장소 관리
  • APIServiceProtocol
    • 네트워크 통신 처리 추상화

향후 계획

  • Mock 객체를 사용한 단위 테스트 작성
  • DI 확장을 위한 컨테이너 또는 팩토리 패턴 연구
    • 의존성 생성을 중앙화하여 코드 관리와 테스트 효율성 향상

🛠️ 기술 스택

기본 구성

  • SwiftUI: iOS 사용자 인터페이스 구성

비동기 처리 및 네트워크 통신

  • Swift Concurrency: 비동기 작업 관리 (async/await, Task, Actor)
  • XMLParser: XML 데이터 파싱 및 처리

데이터 관리

  • Realm: 경량 데이터베이스로 로컬 데이터 관리

UI 개선 및 사용자 경험

  • WidgetKit: 위젯 제작 (iOS 17.0 이상)
  • LocalNotification: 로컬 알림을 통한 사용자 리마인더 및 알림
  • DragGesture: 드래그 제스처 기반의 사용자 인터랙션 처리
  • MagnificationGesture: 확대/축소 제스처를 통한 뷰 조작 지원

앱 간 연동

  • URL Scheme: 딥 링크를 통한 외부 앱 연동 (예: Instagram 스토리 공유)
  • UIPasteboard: 외부 앱과의 데이터 교환을 위한 Pasteboard 사용

🚀 트러블 슈팅

이미지 로드 및 음양력 계산의 비동기 로딩 병렬화

1. 문제 정의

  • D-Day 리스트의 이미지 로드와 음양력 계산을 async/await 기반으로 구현했으나, for 루프 내에서 순차적으로 실행되면서 비동기 함수임에도 불구하고 동기적으로 작동하는 구조적 한계가 존재
  • 특히 음양력 계산은 네트워크 요청이 포함하고 있어, 연결이 불안정한 환경에서는 로딩될 때까지 최대 8초 이상 지연이 발생
  • 이에 따라 UI 반영이 늦어지고, 사용자 경험이 크게 저하되는 문제가 나타남

2. 문제 해결

  • TaskGroup과 async let을 활용하여 이미지 로드와 음양력 계산을 병렬로 처리되도록 구조 개선
  • 각 D-Day 항목에 대해 이미지 로드와 음양력 계산을 동시에 수행하고, 결과는 MainActor에서 UI에 반영
  • OSLog와 Instruments를 사용해 성능 측정 및 병렬화 전후 비교 분석 수행

3. 결과

  • 병렬 처리 적용으로 네트워크 연결 불안정 상황에서도 전체 평균 로딩 시간이 최대 8초 → 약 1초로 단축됨
  • 즉, 네트워크 상태와 관계없이 리스트 렌더링 속도가 안정적으로 유지되어, 초기 화면 진입 지연 문제 해소
  • 이미지 로드와 음양력 계산이 동시에 진행되어 UI 반영 속도 향상 및 사용자 경험 개선
  • Instruments와 OSLog를 통해 적용 전후 성능 데이터를 측정해 개선 효과를 수치로 검증

네트워크 모니터링 기반의 안정적인 API 요청 설계

1. 문제 정의

  • 네트워크 연결이 끊긴 상태에서도 API 요청이 실행되어 불필요한 서버 호출이 발생하는 문제가 존재
  • 또한, 네트워크가 복구 후에도 자동으로 재시도되지 않아 데이터가 최신 상태로 동기화되지 않는 문제가 발생
  • 사용자가 앱을 재실행해야만 정상적인 네트워크 요청이 가능했으며, 이는 불편한 사용자 경험을 초래

2. 문제 해결

  • NWPathMonitor를 활용해 네트워크 상태를 실시간 감지하는 로직을 구현
  • 네트워크가 오프라인일 경우 요청을 시도하지 않고, 즉시 실패 메시지를 반환하여 불필요한 API 호출 차단
  • onReceive를 통해 뷰 단에서 네트워크 상태 변화를 감지하고, 복구 시 자동으로 요청을 재시도하도록 흐름 개선

3. 결과

  • 불필요한 서버 호출 제거로 네트워크 리소스 사용 최소화
  • 네트워크 복구 시 자동 동기화가 가능해져, 앱 재실행 없이도 최신 데이터 반영 가능
  • 사용자 입장에서 장애 상황에서도 자연스러운 흐름 유지, 앱 신뢰도 및 사용성 향상

이미지 다운샘플링으로 메모리 절약

1. 문제 정의

  • D-Day 등록 및 수정 과정에서 이미지 업로드 시, 고해상도 이미지를 그대로 로드하면 메모리 사용량이 급격히 증가
  • 예를 들어, 7680x4320 해상도의 이미지를 처리할 경우 원본 이미지를 그대로 디코딩하게 되면 메모리 사용량이 최대 175MB에 달하며 과도한 리소스 소모가 발생
  • 이에 따라 화면 전환 지연, 뷰 렌더링 지체 등 앱의 응답성 저하와 성능 저하 현상이 관찰됨

2. 문제 해결

  • 이미지 디코딩 단계에서의 CGImageSourceCreateThumbnailAtIndex를 활용한 다운샘플링 기법 도입
  • 디코딩 이전의 이미지 크기 축소를 통한 메모리 로딩 최소화 및 불필요한 리소스 낭비 방지

3. 결과

  • 동일 해상도의 이미지에 대해 다운샘플링 적용 시 메모리 사용량이 175MB → 49.8MB로 약 71.5% 감소
  • 메모리 절감으로 인해 화면 전환 및 렌더링 지연 현상 해소, 앱의 전체적인 안정성과 반응 속도 향상
  • 고해상도 이미지 사용 환경에서도 일관된 사용자 경험 유지 가능

DTO 패턴을 활용한 Realm 객체의 스레드 안전성 문제 해결

1. 문제 정의

  • D-Day 객체를 삭제할 때, 'Object has been deleted or invalidated.' 오류가 발생
  • Realm에서 객체를 삭제하면 해당 객체는 무효화(invalidated) 되는데, 뷰에서는 삭제된 객체를 참조하고 있기 때문에 발생
  • 또한 D-Day 객체의 네트워크 요청이 비동기로 실행되면서, 'Realm accessed from incorrect thread.' 오류가 발생
  • Realm 객체는 생성된 스레드에서만 접근이 가능한데, 객체에 대한 네트워크 요청이 백그라운드 스레드에서 실행되면서 충돌

2. 문제 해결

  • Realm 객체를 직접 사용하지 않고 DTO (Data Transfer Object) 패턴을 도입하여 Struct로 데이터 관리
  • Realm 객체가 삭제되더라도 뷰에서 직접 참조하지 않아, 데이터 무효화 문제를 방지하고 앱의 신뢰성을 향상
  • 또한, DTO는 Realm과 독립적인 값 타입이므로 스레드 간 제약 없이 활용 가능
  • 네트워크 요청 등 비동기 처리에서도 DTO를 사용해 스레드 충돌 없이 안정적인 데이터 처리 구현

3. 결과

  • Realm 객체 삭제 후에도 뷰와의 참조 충돌 없이 앱 크래시 없이 안정적인 동작 유지
  • 백그라운드 스레드에서도 DTO를 통해 데이터 전달이 원활하게 처리, 스레드 충돌 문제 해결
  • Realm 데이터 흐름의 스레드 안전성과 신뢰성 확보, 전반적인 구조 안정성 향상

🗂️ 파일 디렉토리 구조

DearDay
 ┣ Assets.xcassets
 ┃ ┣ AccentColor.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┣ AppIcon.appiconset
 ┃ ┃ ┣ Contents.json
 ┃ ┃ ┗ Logo.png
 ┃ ┗ Contents.json
 ┣ Extension
 ┃ ┗ String+Extension.swift
 ┣ Manager
 ┃ ┣ DateFormatterManager.swift
 ┃ ┣ ImageDocumentManager.swift
 ┃ ┗ NotificationManager.swift
 ┣ Model
 ┃ ┗ DDay.swift
 ┣ Network
 ┃ ┣ APIKey.swift
 ┃ ┣ APIService.swift
 ┃ ┣ NetworkMonitor.swift
 ┃ ┣ SolarDataItem.swift
 ┃ ┗ SolarDateXMLParser.swift
 ┣ Preview Content
 ┃ ┗ Preview Assets.xcassets
 ┃ ┃ ┗ Contents.json
 ┣ Protocol
 ┃ ┣ APIServiceProtocol.swift
 ┃ ┗ DDayRepositoryProtocol.swift
 ┣ Realm
 ┃ ┣ AppGroupID.swift
 ┃ ┣ DDayRepository.swift
 ┃ ┗ RealmConfiguration.swift
 ┣ View
 ┃ ┣ AddDDayView.swift
 ┃ ┣ AnniversaryView.swift
 ┃ ┣ DDayCardView.swift
 ┃ ┣ DDayDetailView.swift
 ┃ ┣ DDayImageCardView.swift
 ┃ ┣ DDayView.swift
 ┃ ┣ EditDDayView.swift
 ┃ ┣ ImagePicker.swift
 ┃ ┗ SelectDDayTypeAlertView.swift
 ┣ ViewModel
 ┃ ┗ DDayViewModel.swift
 ┣ ViewModifier
 ┃ ┣ FormStyleViewModifier.swift
 ┃ ┣ MainStyleViewModifier.swift
 ┃ ┗ RowStyleViewModifier.swift
 ┣ ContentView.swift
 ┣ DearDay.entitlements
 ┣ DearDayApp.swift
 ┗ Info.plist
 
 DearDayAccessoryWidget
 ┣ Assets.xcassets
 ┃ ┣ AccentColor.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┣ AppIcon.appiconset
 ┃ ┃ ┣ Contents.json
 ┃ ┃ ┗ Logo.png
 ┃ ┣ WidgetBackground.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┗ Contents.json
 ┣ DearDayAccessoryWidget.swift
 ┣ DearDayAccessoryWidgetBundle.swift
 ┗ Info.plist
 
 DearDayWidget
 ┣ Assets.xcassets
 ┃ ┣ AccentColor.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┣ AppIcon.appiconset
 ┃ ┃ ┣ Contents.json
 ┃ ┃ ┗ Logo.png
 ┃ ┣ WidgetBackground.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┗ Contents.json
 ┣ AppIntent.swift
 ┣ DearDayWidget.swift
 ┣ DearDayWidgetBundle.swift
 ┗ Info.plist
 
 DearDayListWidget
 ┣ Assets.xcassets
 ┃ ┣ AccentColor.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┣ AppIcon.appiconset
 ┃ ┃ ┣ Contents.json
 ┃ ┃ ┗ Logo.png
 ┃ ┣ WidgetBackground.colorset
 ┃ ┃ ┗ Contents.json
 ┃ ┗ Contents.json
 ┣ AppIntent.swift
 ┣ DearDayListWidget.swift
 ┣ DearDayListWidgetBundle.swift
 ┗ Info.plist

🛣️ 향후 계획

  • 다국어 지원
  • 사용자 맞춤 테마

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages