Skip to content

donggyushin/macmo

Repository files navigation

dgmemo

일정 κΈ°μž…μ€ λ§₯으둜, 확인은 μ•„μ΄ν°μœΌλ‘œ 해보고 μ‹Άμ§€ μ•ŠμœΌμ‹ κ°€μš”? dgmemo에 일정, μƒκ°λ‚˜λŠ” 것, 업무 λ“± λͺ¨λ“  것을 κΈ°λ‘ν•΄λ³΄μ„Έμš”. μ• ν”Œμ˜ λͺ¨λ“  λ””λ°”μ΄μŠ€μ™€ μ—°λ™λ©λ‹ˆλ‹€.

macOS iOS Swift SwiftUI License

Features

βœ… Create, edit, and organize memos - κ°„λ‹¨ν•˜κ³  직관적인 λ©”λͺ¨(νƒœμŠ€ν¬) 관리 ν”„λ‘œκ·Έλž¨
βœ… iCloud sync - λͺ¨λ“  apple λ””λ°”μ΄μŠ€μ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•œ 섀계
βœ… Calendar integration - μ• ν”Œ μΊ˜λ¦°λ”μ™€μ˜ μžλ™ 연동

Screenshots

Section 1 Screenshot 2026-01-17 at 12 46 33β€―PM

Installation

macOS

πŸ’» Download on the Mac App Store

dgmemo의 macOS 버전은 ν˜„μž¬ μ•±μŠ€ν† μ–΄μ—μ„œ 확인 κ°€λŠ₯ν•©λ‹ˆλ‹€!

  • πŸ’» Native macOS interface - macOS κ°€μ΄λ“œλΌμΈμ„ μ€€μˆ˜ν•˜μ—¬ κΉ”λ”ν•œ λ””μžμΈμ„ μΆ”κ΅¬ν•©λ‹ˆλ‹€.
  • πŸ”„ Seamless iCloud sync - λ‹Ήμ‹ μ˜ λͺ¨λ“  λ©”λͺ¨λŠ” λ§₯, 아이폰, μ•„μ΄νŒ¨λ“œμ—μ„œ 데이터가 ν˜Έν™˜λ©λ‹ˆλ‹€.
  • πŸ“… Calendar integration - μΊ˜λ¦°λ”μ™€ μžλ™μœΌλ‘œ μ—°λ™λ˜λŠ” 데이터

iOS / iPadOS

πŸ“± Download on the App Store

dgmemo의 iOS 버전은 ν˜„μž¬ μ•±μŠ€ν† μ–΄μ—μ„œ 확인 κ°€λŠ₯ν•©λ‹ˆλ‹€!

  • πŸ“± Native iOS interface - λ§₯ λ²„μ „μ˜ λ””μžμΈμ„ μž¬ν™œμš©ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. iPhone에 μ΅œμ ν™”λœ λ””μžμΈμœΌλ‘œ λ”°λ‘œ κ°œλ°œν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • πŸ”„ Seamless iCloud sync - λ‹Ήμ‹ μ˜ λͺ¨λ“  λ©”λͺ¨λŠ” λ§₯, 아이폰, μ•„μ΄νŒ¨λ“œμ—μ„œ 데이터가 ν˜Έν™˜λ©λ‹ˆλ‹€.
  • πŸ“… Calendar integration - μΊ˜λ¦°λ”μ™€ μžλ™μœΌλ‘œ μ—°λ™λ˜λŠ” 데이터

Calendar Integration

  • Automatic sync: Due dateλ₯Ό μ„€μ •ν•˜λ©΄ μžλ™μœΌλ‘œ μ• ν”Œ μΊ˜λ¦°λ”μ— κΈ°μž…λ©λ‹ˆλ‹€
  • Permission required: μ•± 첫 μ‹€ν–‰μ‹œ μΊ˜λ¦°λ” 접근에 λ™μ˜ν•΄μ£Όμ„Έμš”
  • Smart updates: λ©”λͺ¨μ˜ 제λͺ©, 컨텐츠, 일정 변경에 λ”°λΌμ„œ μžλ™μœΌλ‘œ μΊ˜λ¦°λ” 데이터도 μ—…λ°μ΄νŠΈ λ©λ‹ˆλ‹€

Keyboard Shortcuts

  • ⌘N - New memo (opens in separate window)
  • Return - Move from title to contents when editing

Development

Key Technologies

  • SwiftUI - Modern UI framework
  • SwiftData - Persistence with schema migration + CloudKit sync
  • EventKit - Calendar integration for due date reminders
  • Factory - Dependency injection framework
  • Tuist - Project generation and dependency management
  • Fastlane - Automated build and release pipeline
image

DataBase

  • CloudKit λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μ‚¬μš©ν•΄μ„œ κ°œλ°œν–ˆμŠ΅λ‹ˆλ‹€. Apple의 iCloud 기반으둜 λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— λ³΄μ•ˆμ μœΌλ‘œ μ·¨μ•½ν•˜μ§€ μ•Šκ³  μ• ν”Œ μƒνƒœκ³„μ˜ λͺ¨λ“  λ””λ°”μ΄μŠ€μ—μ„œ μžμ—°μŠ€λŸ½κ²Œ 같은 데이터에 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€. λ˜ν•œ SwiftDataλ₯Ό μ΄μš©ν•΄μ„œ 둜컬 λ””λΉ„μ™€μ˜ μžμ—°μŠ€λŸ¬μš΄ ν˜Έν™˜ 효과λ₯Ό κΈ°λŒ€ν•˜κ³  κ°„λ‹¨ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

MacmoDomain

μ˜μ‘΄μ„±μ„ μ΅œλŒ€λ‘œ 쀄여 μ•± μ™ΈλΆ€μ˜ λ³€ν™”λ‘œλΆ€ν„° 영ν–₯을 λ°›μ§€ μ•Šκ²Œλ” μ„€κ³„ν•©λ‹ˆλ‹€. κ΅¬ν˜„μ²΄λŠ” λͺ¨λ‘ 숨기고 ν–‰λ™λ§Œ μ •μ˜ν•˜μ—¬ μ»¨ν…μŠ€νŠΈμ— λ”°λΌμ„œ ν•„μš”ν•œ κ΅¬ν˜„μ²΄λ“€μ„ μ£Όμž…ν•  수 μžˆκ²Œλ” μ „λ°˜μ μœΌλ‘œ 앱을 μ„€κ³„ν•©λ‹ˆλ‹€.

  • Entity - App λ‚΄μ—μ„œ ν•„μš”ν•œ κ°μ²΄λ“€μ˜ λͺ¨λΈμ„ μ •μ˜ν•©λ‹ˆλ‹€.
  • Repository - 데이터에 μ ‘κ·Όν•©λ‹ˆλ‹€.
  • Service - μΊ˜λ¦°λ”, ν‘Έμ‰¬λ…Έν‹°ν”ΌμΌ€μ΄μ…˜ λ“± μ™ΈλΆ€ μ„œλΉ„μŠ€μ™€μ˜ 톡합을 μœ„ν•΄ μ •μ˜ν•©λ‹ˆλ‹€.
  • UseCase - Repository와 Service듀을 μ‘°ν•©ν•˜μ—¬ ν•˜λ‚˜μ˜ μ™„κ²°λœ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€.

MacmoData

μ‹€μ œ λ‚΄λΆ€ λ°μ΄ν„°λ² μ΄μŠ€ ν˜Ήμ€ μ™ΈλΆ€ μ„œλΉ„μŠ€μ™€ ν†΅ν•©ν•˜μ—¬ 데이터λ₯Ό λ³€κ²½, μ ‘κ·Όν•˜λŠ” 행동에 λŒ€ν•œ λͺ¨λ“  κ΅¬ν˜„μ„ λ‹΄λ‹Ήν•©λ‹ˆλ‹€.

App

κ°€μž₯ μ΅œμƒλ‹¨ λ ˆμ΄μ–΄λ‘œ μ‹€μ œ μœ μ €μ™€ λ§žλ‹Ώμ•„μžˆκ³  μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ κ·Έ μžμ²΄μž…λ‹ˆλ‹€. μœ μ €μ™€μ˜ μƒν˜Έμž‘μš©μ΄λ‚˜ μ•± μˆ˜μ€€μ˜ μ΄λ²€νŠΈλ“±μ„ μœ„μž„λ°›κ³  λ™μž‘ν•©λ‹ˆλ‹€.

Dependencies Container

  • Container 내뢀에 각 νƒ€μž…λ³„λ‘œ μ˜μ‘΄μ„±μ„ λ“±λ‘ν•΄μ€λ‹ˆλ‹€. μ΄λ•Œμ—, 앱이 μ‹€ν–‰λ˜λŠ” context에 λ§žμΆ”μ–΄μ„œ λ‹€λ₯Έ κ΅¬ν˜„μ²΄λ“€μ„ μ£Όμž…ν•΄μ€„ 수 μžˆμŠ΅λ‹ˆλ‹€. ViewModel μ—μ„œλŠ” Container λ₯Ό 톡해 λ“±λ‘λœ κ΅¬ν˜„μ²΄λ“€μ„ μ‚¬μš©ν•˜λ©΄ μƒμ„±μžλ₯Ό λ”λŸ½νžˆμ§€ μ•ŠμœΌλ©΄μ„œλ„ context 에 맞게 Impl κ΅¬ν˜„μ²΄, Mock κ΅¬ν˜„μ²΄ 등을 μ•Œμ•„μ„œ μ£Όμž…λ°›μ„ 수 있게 λ˜μ–΄μ„œ Preview, Test μž‘μ„± 등에 μœ λ¦¬ν•©λ‹ˆλ‹€.
  • μ˜μ‘΄μ„±μ„ μƒμ„±μžλ₯Ό ν†΅ν•΄μ„œ 직접 μ£Όμž…λ°›μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μ½”λ“œκ°€ μ§€μ €λΆ„ν•΄μ§€κ³ , μž‘μ€ λ³€κ²½ 사항에도 code changes κ°€ λ§Žμ•„μ§€λŠ” Dependency Drilling 을 λ°©μ§€ν•΄ 쀄 수 μžˆμŠ΅λ‹ˆλ‹€.
  • κΈ°μ‘΄ μ½”λ“œκ°€ Service Locator Pattern 을 μ€€μˆ˜ν•˜κ³  μžˆλ‹€κ³  ν•΄μ„œ μ•žμœΌλ‘œμ˜ μ½”λ“œ μž‘μ„±μ— 항상 @Injected annotation을 μ‚¬μš©ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. 상황에 따라 ν•„μš”ν•˜λ‹€λ©΄ μœ λ™μ μœΌλ‘œ μ˜μ‘΄μ„±μ„ 직접 μ£Όμž…λ°›κ²Œ λ§Œλ“€μ–΄μ€λ‹ˆλ‹€.

NavigationManager

NavigationStack의 path에 직접 μ ‘κ·Όν•˜μ—¬ μ•±μ˜ λ„€λΉ„κ²Œμ΄νŒ…μ„ κ΄€λ¦¬ν•΄μ€λ‹ˆλ‹€. Appμ—μ„œ EnvironmentObject둜 등둝해주기 λ•Œλ¬Έμ— Depth κ°€ κΉŠμ€ μ»΄ν¬λ„ŒνŠΈλ“€μ—μ„œλ„ λ°”λ‘œ 직접 접근이 κ°€λŠ₯ν•©λ‹ˆλ‹€.

iOSURLSchemeManager

μ•±κ³Ό κ·Έ μ–΄λ– ν•œ μ˜μ‘΄μ„±λ„ 생기지 μ•Šκ³  pure ν•œ String κ°’ 만으둜 μ•±μ˜ λ„€λΉ„κ²Œμ΄μ…˜μ„ μ‘°μž‘ν•  수 있게 λ„μ™€μ€λ‹ˆλ‹€. Widget, Push Notification, DeepLink λ“± ν™œμš©μ„±μ΄ 맀우 λ²”μš©μ μž…λ‹ˆλ‹€.

Entity

Memo

μ•±μ˜ 핡심 도메인 λͺ¨λΈμž…λ‹ˆλ‹€. μ‚¬μš©μžκ°€ μž‘μ„±ν•˜λŠ” λ©”λͺ¨(νƒœμŠ€ν¬)의 λͺ¨λ“  정보λ₯Ό λ‹΄κ³  μžˆμŠ΅λ‹ˆλ‹€.

ν”„λ‘œνΌν‹° νƒ€μž… μ„€λͺ…
id String 고유 μ‹λ³„μž
title String λ©”λͺ¨ 제λͺ©
contents String? λ©”λͺ¨ λ‚΄μš© (λ§ˆν¬λ‹€μš΄ 지원)
due Date? 마감일
done Bool μ™„λ£Œ μ—¬λΆ€
eventIdentifier String? μ—°λ™λœ μΊ˜λ¦°λ” 이벀트 ID
createdAt Date 생성일
updatedAt Date μˆ˜μ •μΌ
images [ImageAttachment] 첨뢀 이미지 λͺ©λ‘

Computed Properties:

  • isUrgent - 마감일이 3일 이내이고 λ―Έμ™„λ£ŒμΈ 경우 true
  • isOverDue - 마감일이 μ§€λ‚œ 경우 true

CalendarDay

μΊ˜λ¦°λ” λ·°μ—μ„œ νŠΉμ • λ‚ μ§œμ— λ©”λͺ¨λ₯Ό λ§€ν•‘ν•˜κΈ° μœ„ν•œ λͺ¨λΈμž…λ‹ˆλ‹€.

ν”„λ‘œνΌν‹° νƒ€μž… μ„€λͺ…
year Int 연도
month Int μ›”
day Int 일
memo Memo ν•΄λ‹Ή λ‚ μ§œμ˜ λ©”λͺ¨

Repository

UserPreferenceRepository

μ‚¬μš©μž μ„€μ • 및 μ•± μƒνƒœλ₯Ό μ €μž₯ν•˜κ³  λΆˆλŸ¬μ˜€λŠ” μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. UserDefaultsλ₯Ό 톡해 μ˜μ†ν™”λ©λ‹ˆλ‹€.

λ©”μ„œλ“œ μ„€λͺ…
getMemoSort() / setMemoSort(_:) λ©”λͺ¨ μ •λ ¬ κΈ°μ€€ (생성일/μˆ˜μ •μΌ/마감일)
getAscending() / setAscending(_:) μ •λ ¬ μˆœμ„œ (μ˜€λ¦„μ°¨μˆœ/λ‚΄λ¦Όμ°¨μˆœ)
getStatistics() / setStatistics(_:) 톡계 λ·° νƒ€μž…
getMemoSortCacheInSearch() / setMemoSortCacheInSearch(_:) 검색 ν™”λ©΄ μ •λ ¬ κΈ°μ€€ μΊμ‹œ
getMemoSearchQuery() / setMemoSearchQuery(_:) 검색어 μΊμ‹œ
getSelectedMemoId() / setSelectedMemoId(_:) μ„ νƒλœ λ©”λͺ¨ ID
getMemoDraft() / setMemoDraft(_:) μž‘μ„± 쀑인 λ©”λͺ¨ μž„μ‹œ μ €μž₯
getAppTabEnum() / setAppTabEnum(_:) ν˜„μž¬ μ„ νƒλœ νƒ­
getCalendarDotVisibleMode() / setCalendarDotVisibleMode(_:) μΊ˜λ¦°λ” dot ν‘œμ‹œ λͺ¨λ“œ

MemoRepository

λ©”λͺ¨ λ°μ΄ν„°μ˜ CRUD 및 쑰회λ₯Ό λ‹΄λ‹Ήν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. SwiftDataλ₯Ό 톡해 μ˜μ†ν™”λ˜λ©°, iCloudλ₯Ό 톡해 κΈ°κΈ° κ°„ λ™κΈ°ν™”λ©λ‹ˆλ‹€.

Prerequisites

  • Xcode 26.0+
  • Tuist 4.0+
  • macOS 15.0+

Setup

# Clone the repository
git clone https://github.com/donggyushin/macmo.git
cd macmo

# Generate Xcode project
tuist generate

# Open in Xcode
open macmo.xcworkspace

Building for Release

tuist generate
[bundle exec] fastlane mac release
[bundle exec] fastlane ios release

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the project
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Security & Privacy

  • Local storage - All data stored locally on your device
  • iCloud sync - Data synced through your personal iCloud account
  • Calendar privacy - Calendar access only used for syncing your memos, no data sharing
  • No tracking - No analytics or user tracking
  • Open source - Full source code available for review

Support

Author

Donggyu Shin - @donggyushin


⭐ Star this repository if you found it helpful! ⭐

About

A clean, simple memo application for macOS and iOS with iCloud sync.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors