Skip to content

Chore/#147 앱 아이콘 및 로띠 추가#148

Merged
y-eonee merged 3 commits intodevelopfrom
chore/#147-앱-아이콘
Jan 21, 2026

Hidden character warning

The head ref may contain hidden characters: "chore/#147-\uc571-\uc544\uc774\ucf58"
Merged

Chore/#147 앱 아이콘 및 로띠 추가#148
y-eonee merged 3 commits intodevelopfrom
chore/#147-앱-아이콘

Conversation

@y-eonee
Copy link
Contributor

@y-eonee y-eonee commented Jan 21, 2026

🔗 연결된 이슈

📄 작업 내용

  • 테플을 위한 앱 아이콘 추가했습니다
  • 스플래시, 로딩뷰 로띠 추가했습니다
  • 스유에서는 로띠 넣으려면 유킷이랑 다르게 래퍼 같은게 필요한것 같아서 Extension에 추가했습니다
구현 내용 IPhone 13
GIF

@y-eonee y-eonee linked an issue Jan 21, 2026 that may be closed by this pull request
1 task
@coderabbitai
Copy link

coderabbitai bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

앱 아이콘을 기기별 명시 항목으로 교체하고 스플래시를 정적 이미지에서 Lottie 애니메이션으로 전환하며, lottie-ios SPM 추가 및 관련 프로젝트 파일과 Lottie 래퍼·리소스가 추가되었습니다.

Changes

Cohort / File(s) 변경 요약
앱 아이콘 자산
Cherrish-iOS/Cherrish-iOS/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json
단일 유니버설 1024 아이콘 항목 제거; iPhone/iPad/ios-marketing 용 다수 기기별 아이콘 항목(29/40/57/60/83.5/1024 등) 및 1x/2x/3x 스케일과 파일명으로 대체; 다크/appearance·legacy 엔트리 삭제.
프로젝트 · 패키지 설정
Cherrish-iOS/Cherrish-iOS.xcodeproj/project.pbxproj, Cherrish-iOS/Cherrish-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
lottie-ios Swift Package 추가(pins, packageReferences, packageProductDependencies, XCRemoteSwiftPackageReference 등) 및 Frameworks 빌드파일 참조 추가; Package.resolved에 lottie 핀 추가.
스플래시 UI 변경
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift
정적 앱 아이콘 대신 LottieView(animationName:"splash", loopMode:.playOnce) 사용으로 변경; onAppear에서 3초 대기 후 navigateBasedOnUserStatus() 호출하도록 네비게이션 로직 분리.
Lottie 래퍼·리소스
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Lottie+.swift, Cherrish-iOS/Cherrish-iOS/Resources/Lottie/splash.json
SwiftUI용 LottieView UIViewRepresentable 래퍼 추가(애니메이션뷰 생성·재생·제약) 및 Lottie 애니메이션 JSON 리소스 추가.
캘린더 D‑day 자산 변경
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Calendar/CalendarMain/CalendarCellView.swift, Cherrish-iOS/Cherrish-iOS/Resources/Assets.xcassets/CalendarIcon/*
CalendarCellView가 선택 상태 D‑Day 시 새로운 Image(.calendarDDay) 사용으로 변경; calendar_D-day.imageset 추가 및 기존 dday.imageset/Contents.json 삭제.

Sequence Diagram(s)

sequenceDiagram
    participant App as 앱 런치
    participant Splash as SplashView
    participant Lottie as LottieView/LottieAnimationView
    participant UD as UserDefaults
    participant Router as Router/네비게이터

    App->>Splash: 스플래시 화면 표시
    Splash->>Lottie: LottieView(animationName:"splash") 생성·재생
    Lottie-->>Splash: 애니메이션 재생(또는 루프/플레이완료)
    Splash->>UD: 사용자 상태 조회 (userId, onboarding 등)
    UD-->>Splash: 상태 반환
    Splash->>Router: navigateBasedOnUserStatus() 호출 → 화면 전환
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Add

Suggested reviewers

  • soseoyo12
  • sum130
  • wotjs020708
🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Out of Scope Changes check ❓ Inconclusive 대부분의 변경사항이 앱 아이콘 및 Lottie 애니메이션과 관련되어 있으나, ChallengeLoadingView의 로딩 화면 수정과 스플래시 Lottie 적용은 이슈 #147의 명시적 범위를 벗어날 수 있습니다. 이슈 #147의 세부 요구사항이 명확하지 않아, 앱 아이콘 외의 추가 UI 변경사항(로딩 화면, 스플래시)이 범위 내인지 확인 필요합니다.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 앱 아이콘 추가 및 Lottie 통합이라는 주요 변경사항을 간결하게 나타내고 있습니다.
Description check ✅ Passed PR 설명이 앱 아이콘 추가, Lottie 스플래시 애니메이션 추가, SwiftUI 래퍼 확장 등의 작업 내용과 연결된 이슈를 명확히 기술하고 있습니다.
Linked Issues check ✅ Passed PR의 코드 변경사항(앱 아이콘 에셋 추가, Lottie 통합, Lottie+ 확장 추가)이 이슈 #147의 앱 아이콘 추가 요구사항을 충족하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/#147-앱-아이콘

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@y-eonee y-eonee requested review from a team, soseoyo12, sum130 and wotjs020708 and removed request for a team January 21, 2026 14:52
@y-eonee y-eonee self-assigned this Jan 21, 2026
@y-eonee y-eonee added 나연🐹 Chore 중요한 수정이 아닐 때 사용 Style UI 구현 labels Jan 21, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Feature/Onboarding/SplashView.swift (1)

35-38: 재진입 시 중복 네비게이션 방지 필요

onAppear가 여러 번 호출되면 지연 작업이 중복 등록될 수 있습니다. 재등장/백그라운드 복귀 시 중복 네비게이션을 막는 가드/취소 로직을 추가해 주세요.

🛠️ 제안 수정
 struct SplashView: View {
     `@EnvironmentObject` private var appCoordinator: AppCoordinator
     
     private let userDefaultService: UserDefaultService
+    `@State` private var navigationWorkItem: DispatchWorkItem?

@@
-        .onAppear {
-            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
-                navigateBasedOnUserStatus()
-            }
-        }
+        .onAppear {
+            guard navigationWorkItem == nil else { return }
+            let workItem = DispatchWorkItem { navigateBasedOnUserStatus() }
+            navigationWorkItem = workItem
+            DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: workItem)
+        }
+        .onDisappear {
+            navigationWorkItem?.cancel()
+            navigationWorkItem = nil
+        }
🤖 Fix all issues with AI agents
In
`@Cherrish-iOS/Cherrish-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved`:
- Around line 13-20: The project is using lottie-ios version "4.6.0" (identity
"lottie-ios") which requires Swift 6.0+, while the project SWIFT_VERSION is set
to 5.0; either update the project Swift setting or pin a compatible lottie
version: change the build setting SWIFT_VERSION to "6.0" in your Xcode project
targets (or workspace build settings) and regenerate packages, or update the
"state.version" for identity "lottie-ios" in Package.resolved to a lower
lottie-ios release that supports Swift 5.x and then run SwiftPM update to ensure
the lockfile and dependencies are consistent.

In `@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Lottie`+.swift:
- Around line 15-35: makeUIView currently creates a new LottieAnimationView but
updateUIView is empty, so changes to animationName or loopMode aren’t applied;
implement the Coordinator pattern to store a persistent reference (e.g.,
coordinator.animationView) when creating the view in makeUIView, assign the
created LottieAnimationView to that coordinator property, and then implement
updateUIView to compare and update the coordinator.animationView: if
animationName changed load/set the new LottieAnimationView animation, update
loopMode, and restart/play as needed so parameter changes are reflected without
recreating the whole SwiftUI view.
♻️ Duplicate comments (1)
Cherrish-iOS/Cherrish-iOS.xcodeproj/project.pbxproj (1)

385-405: Lottie 패키지 참조 추가 확인

SPM 연결은 적절해 보이나, 4.6.0의 호환성/라이선스 확인이 필요합니다(앞선 Package.resolved 코멘트와 동일한 확인 항목).

Comment on lines +13 to +20
{
"identity" : "lottie-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/airbnb/lottie-ios",
"state" : {
"revision" : "0cb03fd7564d27345bcd96144b811e56212949c6",
"version" : "4.6.0"
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

lottie-ios 4.6.0 minimum iOS version Swift support requirements

💡 Result:

  • Minimum iOS deployment target: iOS 13.0+. [1][2]
  • Swift / Xcode requirement for lottie-ios 4.6.0: Xcode 16 / Swift 6.0 or later. [1]

Sources:
[1] lottie-ios 4.6.0 release notes.
[2] Issue/notes reporting lottie-ios raised minimum deployment to iOS 13.0 (4.4.x → 13.0).


🌐 Web query:

lottie-ios license Apache MIT

💡 Result:

  • airbnb/lottie-ios (the native iOS library) is licensed under Apache License 2.0. [1]
  • airbnb/lottie-web is licensed under the MIT License. [2]
  • LottieFiles' dotlottie-ios (a separate .lottie player) is MIT. [3]

If you need the exact license text, check each repo's LICENSE file linked above.

Sources: [1] GitHub — airbnb/lottie-ios (Apache-2.0). [2] GitHub — airbnb/lottie-web (MIT). [3] GitHub — LottieFiles/dotlottie-ios (MIT).


🏁 Script executed:

find . -name "project.pbxproj" -o -name "*.swift" -o -name "project.yml" | head -20

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 1378


🏁 Script executed:

cd Cherrish-iOS && cat -n Cherrish-iOS.xcodeproj/project.pbxproj | grep -i "iphoneos" | head -20

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 745


🏁 Script executed:

cd Cherrish-iOS && cat -n Cherrish-iOS.xcodeproj/project.pbxproj | grep -i "swift" | head -20

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 1239


lottie-ios 4.6.0 Swift 버전 호환성 문제

lottie-ios 4.6.0은 Swift 6.0 이상이 필요하지만, 프로젝트의 SWIFT_VERSION은 5.0으로 설정되어 있습니다. 이는 빌드 실패를 초래할 수 있습니다. Swift 6.0으로 업그레이드하거나 더 낮은 버전의 lottie-ios를 사용해야 합니다.

라이선스는 Apache License 2.0이며 일반적으로 수용 가능합니다. iOS 배포 대상(17.6, 18.2)은 최소 요구 사항(13.0+)을 충족합니다.

🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved`
around lines 13 - 20, The project is using lottie-ios version "4.6.0" (identity
"lottie-ios") which requires Swift 6.0+, while the project SWIFT_VERSION is set
to 5.0; either update the project Swift setting or pin a compatible lottie
version: change the build setting SWIFT_VERSION to "6.0" in your Xcode project
targets (or workspace build settings) and regenerate packages, or update the
"state.version" for identity "lottie-ios" in Package.resolved to a lower
lottie-ios release that supports Swift 5.x and then run SwiftPM update to ensure
the lockfile and dependencies are consistent.

Comment on lines +15 to +35
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: .zero)

let animationView = LottieAnimationView(name: animationName)
animationView.loopMode = loopMode
animationView.play()

animationView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(animationView)

NSLayoutConstraint.activate([
animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
animationView.topAnchor.constraint(equalTo: view.topAnchor),
animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

return view
}

func updateUIView(_ uiView: UIView, context: Context) {}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "Lottie+.swift" -type f

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 141


🏁 Script executed:

fd "Lottie\+\.swift" -type f

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 240


🏁 Script executed:

cat -n "./Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Lottie+.swift"

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 1331


🌐 Web query:

UIViewRepresentable updateUIView lifecycle SwiftUI best practices

💡 Result:

Key points & best practices for UIViewRepresentable lifecycle (makeUIView / updateUIView)

  1. Lifecycle basics
  • makeUIView(...) is called once to create the UIKit view. updateUIView(_:context:) is called repeatedly whenever SwiftUI considers the representable’s inputs/state changed; after makeUIView it will be called at least once. Use dismantleUIView(...) for cleanup. (developer.apple.com)
  1. Treat updateUIView as a sync/diff method
  • Don’t recreate subviews or do heavy allocation in updateUIView. Apply only the minimal updates needed (set properties, update models, call setNeedsLayout). That keeps SwiftUI diffing fast and avoids flicker. (sarunw.com)
  1. Use Coordinator for delegates, actions and two‑way bindings
  • Put delegate/dataSource handlers and callbacks in Context.coordinator so delegate lifetime and bridging are correct. Use @Binding / @ObservedObject on the SwiftUI side and propagate changes in updateUIView or via the coordinator. (ios-swift-explorations.hashnode.dev)
  1. Be explicit about what triggers updates
  • SwiftUI calls updateUIView when inputs change; if you need a full rebuild, change the view’s .id(...) to force re‑creation. Don’t rely on implicit side effects—drive updates from bindings/observable objects. (stackoverflow.com)
  1. Threading and performance
  • All UIKit work must run on the main thread. Offload heavy processing (parsing, layout calculations) to background threads and apply final UI updates in updateUIView on the main thread. Profile with Instruments if performance is a concern. (peerdh.com)
  1. Cleanup & appearance hooks
  • Use dismantleUIView to remove observers/notifications. Complement representable lifecycle with SwiftUI’s onAppear/onDisappear in the parent view when appropriate. (fatbobman.com)

Short checklist when implementing:

  • makeUIView: create and configure once.
  • updateUIView: apply incremental changes only; read bindings/observables here.
  • Coordinator: implement delegates, send events back to SwiftUI.
  • Use .id to force recreate only when necessary.
  • Keep UIKit updates on main thread; heavy work off the main thread.
  • Clean up in dismantleUIView and/or onDisappear.

If you want, I can show a compact example demonstrating these patterns.

Citations:


updateUIView가 비어 있어 애니메이션 속성 변경이 반영되지 않음

animationName 또는 loopMode가 변경되어도 updateUIView가 구현되지 않았으므로 UI에 반영되지 않습니다. 특히 동일한 LottieView를 다른 파라미터로 재사용할 때 버그가 발생할 수 있습니다.

Coordinator 패턴을 사용하여 animationView 참조를 유지한 후, updateUIView에서 애니메이션과 루프 모드를 갱신해야 합니다.

🛠️ 제안 수정
 struct LottieView: UIViewRepresentable {
     let animationName: String
     let loopMode: LottieLoopMode

+    func makeCoordinator() -> Coordinator { Coordinator() }
+
     func makeUIView(context: Context) -> UIView {
         let view = UIView(frame: .zero)

         let animationView = LottieAnimationView(name: animationName)
+        context.coordinator.animationView = animationView
         animationView.loopMode = loopMode
         animationView.play()

         animationView.translatesAutoresizingMaskIntoConstraints = false
         view.addSubview(animationView)

         NSLayoutConstraint.activate([
             animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
             animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
             animationView.topAnchor.constraint(equalTo: view.topAnchor),
             animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
         ])

         return view
     }

-    func updateUIView(_ uiView: UIView, context: Context) {}
+    func updateUIView(_ uiView: UIView, context: Context) {
+        guard let animationView = context.coordinator.animationView else { return }
+        if animationView.animation?.name != animationName {
+            animationView.animation = LottieAnimation.named(animationName)
+        }
+        animationView.loopMode = loopMode
+        animationView.play()
+    }
+
+    final class Coordinator {
+        var animationView: LottieAnimationView?
+    }
 }
🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Lottie`+.swift around
lines 15 - 35, makeUIView currently creates a new LottieAnimationView but
updateUIView is empty, so changes to animationName or loopMode aren’t applied;
implement the Coordinator pattern to store a persistent reference (e.g.,
coordinator.animationView) when creating the view in makeUIView, assign the
created LottieAnimationView to that coordinator property, and then implement
updateUIView to compare and update the coordinator.animationView: if
animationName changed load/set the new LottieAnimationView animation, update
loopMode, and restart/play as needed so parameter changes are reflected without
recreating the whole SwiftUI view.

Copy link
Contributor

@wotjs020708 wotjs020708 left a comment

Choose a reason for hiding this comment

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

고생하셨습니담 어푸푸

Copy link
Contributor

@sum130 sum130 left a comment

Choose a reason for hiding this comment

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

예뿌네욤 어푸푸!! 감사합니다

Copy link
Contributor

@soseoyo12 soseoyo12 left a comment

Choose a reason for hiding this comment

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

수고하셨숨니당

@y-eonee y-eonee changed the title Chore/#147 앱 아이콘 Chore/#147 앱 아이콘 및 로띠 추가 Jan 21, 2026
@y-eonee y-eonee merged commit c7e6624 into develop Jan 21, 2026
1 check was pending
@y-eonee y-eonee deleted the chore/#147-앱-아이콘 branch January 21, 2026 19:12
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/View/ChallengeLoadingView.swift`:
- Around line 21-35: The Lottie animation should respect Reduce Motion and avoid
VoiceOver focus: update ChallengeLoadingView where LottieView(animationName:
"splash", loopMode: .loop) is used to use UIAccessibility.isReduceMotionEnabled
(or `@Environment`(\.accessibilityReduceMotion)) to switch loopMode to a single
play (or replace with a static image) when Reduce Motion is enabled, and add
accessibilityHidden(true) (or .accessibility(hidden: true)) to the LottieView so
it is not focused by VoiceOver; keep the existing layout and text elements
unchanged and only change the LottieView instantiation/attributes.

Comment on lines +21 to 35

LottieView(animationName: "splash", loopMode: .loop)
.frame(width: 130.adjustedW, height: 154.adjustedH)
.padding(.top, 60.adjustedH)

Spacer()
.frame(height: 80.adjustedH)

TypographyText("잠시만 기다려주세요!", style: .title2_sb_16, color: .gray800)
.padding(.top, 17.adjustedH)

Spacer()

TypographyText("AI가 맞춤형 루틴을 제작하고 있어요.", style: .body3_m_12, color: .gray600)
.padding(.bottom, 30.adjustedH)
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Reduce Motion 사용자 배려 추가 권장.
반복 루프 애니메이션은 Reduce Motion이 켜진 경우 1회 재생(또는 정적 대체)로 전환하는 편이 접근성에 유리합니다. 애니메이션이 보이스오버 포커스를 받지 않도록 숨김 처리도 권장합니다.

♿ 제안 변경사항
 struct ChallengeLoadingView: View {
+    `@Environment`(\.accessibilityReduceMotion) private var reduceMotion
     `@ObservedObject` var viewModel: CreateChallengeViewModel   
 
     var body: some View {
         VStack {
@@
-                LottieView(animationName: "splash", loopMode: .loop)
+                LottieView(animationName: "splash", loopMode: reduceMotion ? .playOnce : .loop)
                     .frame(width: 130.adjustedW, height: 154.adjustedH)
                     .padding(.top, 60.adjustedH)
+                    .accessibilityHidden(true)
🤖 Prompt for AI Agents
In
`@Cherrish-iOS/Cherrish-iOS/Presentation/Feature/ChallengeView/View/ChallengeLoadingView.swift`
around lines 21 - 35, The Lottie animation should respect Reduce Motion and
avoid VoiceOver focus: update ChallengeLoadingView where
LottieView(animationName: "splash", loopMode: .loop) is used to use
UIAccessibility.isReduceMotionEnabled (or
`@Environment`(\.accessibilityReduceMotion)) to switch loopMode to a single play
(or replace with a static image) when Reduce Motion is enabled, and add
accessibilityHidden(true) (or .accessibility(hidden: true)) to the LottieView so
it is not focused by VoiceOver; keep the existing layout and text elements
unchanged and only change the LottieView instantiation/attributes.

This was referenced Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Chore 중요한 수정이 아닐 때 사용 Style UI 구현 나연🐹

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Chore] 앱 아이콘

4 participants

Comments