Skip to content

Conversation

@youz2me
Copy link
Member

@youz2me youz2me commented Nov 12, 2025

👻 PULL REQUEST

📄 작업 내용

  • 휴먼 에러를 방지하고 메모리를 최적화하기 위해 기존 사용되던 DateFormatter 객체 대신 사용할 DateFormatterHelper를 구현했어요.
  • 프로젝트 전체에서 사용되는 날짜 포맷을 DateFormatType enum으로 구현했어요.

💻 주요 코드 설명

DateFormatType 구현

  • 프로젝트 전체에서 사용되던 날짜 포맷을 enum으로 구현하고자 했으나, 각 화면이나 기능마다 사용되는 날짜 포맷이 모두 달라 구현에 어려움을 겪었습니다.
  • 이를 해결하기 위해 enum case의 이름을 기능의 이름이 아닌 포맷이 나타내는 날짜 형식으로 네이밍해(e.g. fullDateTime) 가독성과 재사용성을 높였습니다.
  • 최종 열거형 구조는 다음과 같습니다.
public enum DateFormatType: String {
    case fullDateTime = "yyyy-MM-dd HH:mm:ss"
    case dateTimeWithMinute = "yyyy-MM-dd HH:mm"
    case dashSeparatedDate = "yyyy-MM-dd"
    case dotSeparatedDate = "yyyy.MM.dd"
    case koreanDate = "yyyy년 MM월 dd일"
    case timeOnly = "HH:mm"
}

DateFormatterHelper 구현

  • 기존에 사용하고 있던 DateFormatter의 경우 dateFormat을 하나하나 작성해주어야 했고, ISO 국제 표준에 맞게 대소문자를 구분해 작성해주어야 했기에 휴먼 에러가 발생할 수 있는 환경이었습니다. ([Fix] 게시글, 댓글 셀 뷰 Configure 되지 않는 문제 해결 #312 )
  • 또한 DateFormatter 객체를 반복해서 생성해주어야 했고, timeZone과 locale도 매번 지정해주어야 했기에 DateFormatterHelper를 구현해 흩어진 DateFormatter 로직을 중앙 집중화하고 반복적인 DateFormatter 객체 생성을 방지해 메모리를 최적화하고자 했습니다.

Before:

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone(abbreviation: "KST")
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: dto.time)

After:

let date = DateFormatterHelper.date(from: dto.time, type: .fullDateTime)

📚 참고자료

DateFormatter Apple Documentation
Technical Q&A QA 1480: NSDateFormatter and Internet Dates

✅ 이번 PR에서 이런 부분을 중점적으로 체크해주세요!

잠깐 확인하고 갈까요?
  • 들여쓰기를 5번 이하로 준수했는지, 코드 가독성이 적절한지 확인해주세요.

  • 한 줄당 120자 제한을 준수했는지 확인해주세요.

  • MARK 주석이 정해진 순서와 형식에 맞게 작성되었는지 확인해주세요.

  • 반복되는 상수 값이 있는지, 있다면 Constant enum으로 분리되어 있는지 확인해주세요.

  • 삼항 연산자가 길어질 경우 적절히 개행되어 있는지 확인해주세요.

  • 조건문에서 중괄호가 올바르게 사용되었는지 확인해주세요.

  • 라이브러리 import가 퍼스트파티와 서드파티로 구분되고 알파벳순으로 정렬되었는지 확인해주세요.

  • 용량이 큰 리소스나 호출되지 않을 가능성이 있는 프로퍼티에 lazy var가 적절히 사용되었는지 확인해주세요.

  • 메모리 누수 방지를 위한 weak 참조가 필요한 곳에 적용되었는지 확인해주세요.

  • 도메인 로직과 UI 로직이 적절히 분리되어 있는지 확인해주세요.

🔗 연결된 이슈

@youz2me youz2me requested review from JinUng41 and Copilot November 12, 2025 18:38
@youz2me youz2me self-assigned this Nov 12, 2025
@youz2me youz2me added ♻️ refactor 기존 코드를 리팩토링하거나 수정하는 등 사용 (생산적인 경우) 🦉 유진 🛌🛌🛌🛌🛌🛌🛌🛌🛌🛌 labels Nov 12, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors date formatting across the codebase by introducing a centralized DateFormatterHelper utility class and a DateFormatType enum to standardize date format usage and improve memory efficiency through formatter caching.

Key changes:

  • Created DateFormatterHelper with cached DateFormatter instances to avoid repeated object creation
  • Defined DateFormatType enum with six common date format patterns
  • Replaced all inline DateFormatter instantiations across mappers, view models, and views with calls to the helper

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
Wable-iOS/Core/DateFormatter/DateFormatterHelper.swift New helper class providing cached, reusable DateFormatter instances with thread-safe access
Wable-iOS/Core/DateFormatter/DateFormatType.swift New enum defining standardized date format patterns used throughout the app
Wable-iOS/Data/Mapper/ProfileMapper.swift Refactored to use DateFormatterHelper for parsing account creation date
Wable-iOS/Data/Mapper/NotificationMapper.swift Refactored to use DateFormatterHelper for parsing notification timestamps
Wable-iOS/Data/Mapper/InformationMapper.swift Refactored to use DateFormatterHelper for parsing game schedules, news, notices, and curation dates
Wable-iOS/Data/Mapper/ContentMapper.swift Refactored to use DateFormatterHelper for parsing content timestamps
Wable-iOS/Data/Mapper/CommentMapper.swift Refactored to use DateFormatterHelper for parsing comment timestamps
Wable-iOS/Presentation/Profile/AccountInfo/ViewModel/AccountInfoViewModel.swift Refactored date formatting in view model
Wable-iOS/Presentation/WableComponent/View/PostUserInfoView.swift Refactored date display for Korean date format
Wable-iOS/Presentation/Overview/GameSchedule/View/GameScheduleListViewController.swift Refactored time-only formatting for game schedules
Wable-iOS.xcodeproj/project.pbxproj Added new source files to Xcode project

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Collaborator

@JinUng41 JinUng41 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSCache를 사용하셨네요.
메모리 절약을 위한 캐싱 처리가 인상깊습니다.

저는 해당 상황에서 딕셔너리로 구현했을 것 같네요. ([열거형: 객체])

NSCache를 사용하신 이유, 그리고 어떠한 특징을 가지고 있는지 들어보고 싶어요.

코멘트도 하나 남겨두었으니 고려해 보셔도 좋을 것 같습니다.

고생하셨습니다~

Comment on lines +38 to +54
private extension DateFormatterHelper {
private static func getFormatter(for type: DateFormatType) -> DateFormatter {
let key = type.rawValue as NSString

if let cached = formatterCache.object(forKey: key) {
return cached
}

let formatter = DateFormatter()
formatter.dateFormat = type.rawValue
formatter.locale = Locale(identifier: "ko_KR")
formatter.timeZone = .current

formatterCache.setObject(formatter, forKey: key)
return formatter
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DateFormatter를 반환하는 책임을 헬퍼가 아닌 다른 객체가 하면 생성과 활용의 책임이 분리될 수 있을 것 같습니다.

디자인 패턴 중 생성 패턴을 이용해 보면 좋을 것 같아요.

이렇게 하면 인스턴스 반환만 원할 때는 해당 객체만을 이용하는 것이죠.

당장 떠오르는 것은 팩토리 패턴 혹은 추상 팩토리 패턴이 있을 수 있겠네요.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

간단한 로직이기도 하고 지금 수준이 딱 적당한 구현 크기라고 생각해서 책임을 나누지는 않았는데요!

해당 부분에 대해 조금 더 논의해보면 좋을 것 같아요. 현재 Core 레이어에 함께 존재하는 PhotoPickerHelper에 대해서도 이야기 나누고 싶은 부분이 있어... 회의 안건으로 건의드립니다! 리뷰 감사합니다 😊

@youz2me
Copy link
Member Author

youz2me commented Nov 13, 2025

NSCache를 사용하셨네요.
메모리 절약을 위한 캐싱 처리가 인상깊습니다.

저는 해당 상황에서 딕셔너리로 구현했을 것 같네요. ([열거형: 객체])

NSCache를 사용하신 이유, 그리고 어떠한 특징을 가지고 있는지 들어보고 싶어요.

코멘트도 하나 남겨두었으니 고려해 보셔도 좋을 것 같습니다.

고생하셨습니다~

@JinUng41 리뷰 감사합니다! DateFormatter를 사용하는 화면이 많고 객체가 끊임없이 생성되다 보니 어떻게 메모리를 최적화할 수 있을지에 대해 고민을 많이 했었는데요. 현재는 나올 수 있는 열거형 케이스가 6개 정도 있고, 이 부분을 고려해 딕셔너리로 각 케이스마다 객체를 선언하고 UserDefaults로 관리하는 방안도 생각보았습니다.

그러나

  1. 수동으로 메모리를 관리해주어야 한다는 점
  2. 백그라운드로 앱이 이동해도 메모리를 계속 점유하고 있다는 점
  3. 메모리를 많이 사용할 경우 캐시가 해제되지 않아 효율적이지 않다는 점

때문에 관련 대안을 찾아보았고, NSCache가 위 문제를 어느정도 해결해줄 수 있다는 점을 알게 되었어요.

  1. 시스템이 자동으로 메모리를 관리한다는 점
  2. memory warning이 발생하면 메모리에서 자동 해제된다는 점
  3. Dictionary와 달리 별도의 동기화 코드 없이 사용 가능하고 Thread-safe하다는 점

물론 구현의 복잡성 때문에 Dictionary를 사용하는 부분이 조금 더 합리적일 수도 있을 것 같다는 생각을 했는데요, DateFormatter를 사용하는 화면이 여러 개다 보니 Thread-safe한 코드를 만들기 위해 NSCache를 선택했습니다. (대신 최대한 간단하게 Helper 클래스 하나만을 사용해서 구현했어요!)

좋은 의견 주셔서 감사합니다! 답변이 되었으면 좋겠는데요 ㅎㅎ 좋은 의견 또 주시면 같이 이야기해보면 좋을 것 같아요.

@JinUng41
Copy link
Collaborator

NSCache를 사용하셨네요.
메모리 절약을 위한 캐싱 처리가 인상깊습니다.
저는 해당 상황에서 딕셔너리로 구현했을 것 같네요. ([열거형: 객체])
NSCache를 사용하신 이유, 그리고 어떠한 특징을 가지고 있는지 들어보고 싶어요.
코멘트도 하나 남겨두었으니 고려해 보셔도 좋을 것 같습니다.
고생하셨습니다~

@JinUng41 리뷰 감사합니다! DateFormatter를 사용하는 화면이 많고 객체가 끊임없이 생성되다 보니 어떻게 메모리를 최적화할 수 있을지에 대해 고민을 많이 했었는데요. 현재는 나올 수 있는 열거형 케이스가 6개 정도 있고, 이 부분을 고려해 딕셔너리로 각 케이스마다 객체를 선언하고 UserDefaults로 관리하는 방안도 생각보았습니다.

그러나

  1. 수동으로 메모리를 관리해주어야 한다는 점
  2. 백그라운드로 앱이 이동해도 메모리를 계속 점유하고 있다는 점
  3. 메모리를 많이 사용할 경우 캐시가 해제되지 않아 효율적이지 않다는 점

때문에 관련 대안을 찾아보았고, NSCache가 위 문제를 어느정도 해결해줄 수 있다는 점을 알게 되었어요.

  1. 시스템이 자동으로 메모리를 관리한다는 점
  2. memory warning이 발생하면 메모리에서 자동 해제된다는 점
  3. Dictionary와 달리 별도의 동기화 코드 없이 사용 가능하고 Thread-safe하다는 점

물론 구현의 복잡성 때문에 Dictionary를 사용하는 부분이 조금 더 합리적일 수도 있을 것 같다는 생각을 했는데요, DateFormatter를 사용하는 화면이 여러 개다 보니 Thread-safe한 코드를 만들기 위해 NSCache를 선택했습니다. (대신 최대한 간단하게 Helper 클래스 하나만을 사용해서 구현했어요!)

좋은 의견 주셔서 감사합니다! 답변이 되었으면 좋겠는데요 ㅎㅎ 좋은 의견 또 주시면 같이 이야기해보면 좋을 것 같아요.

네 답변 감사합니다! 고생하셨어요~

@youz2me youz2me merged commit 45597d9 into develop Nov 13, 2025
@youz2me youz2me deleted the prefix/#313-dateformatterservice branch November 13, 2025 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

♻️ refactor 기존 코드를 리팩토링하거나 수정하는 등 사용 (생산적인 경우) 🦉 유진 🛌🛌🛌🛌🛌🛌🛌🛌🛌🛌

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Refactor] DateFormatter 통합을 위한 DateFormatterService 구현

3 participants