-
Notifications
You must be signed in to change notification settings - Fork 4
# 메인화면 구성 완료 #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
TyrHanz
wants to merge
3
commits into
main_han
Choose a base branch
from
dev_han
base: main_han
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
# 메인화면 구성 완료 #6
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // | ||
| // AppDelegate.swift | ||
| // Challenge | ||
| // | ||
| // Created by Hanjuheon on 3/13/26. | ||
| // | ||
|
|
||
| import UIKit | ||
| import CoreData | ||
|
|
||
| @main | ||
| class AppDelegate: UIResponder, UIApplicationDelegate { | ||
|
|
||
|
|
||
|
|
||
| func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { | ||
| // Override point for customization after application launch. | ||
| return true | ||
| } | ||
|
|
||
| // MARK: UISceneSession Lifecycle | ||
|
|
||
| func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { | ||
| // Called when a new scene session is being created. | ||
| // Use this method to select a configuration to create the new scene with. | ||
| return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) | ||
| } | ||
|
|
||
| func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) { | ||
| // Called when the user discards a scene session. | ||
| // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. | ||
| // Use this method to release any resources that were specific to the discarded scenes, as they will not return. | ||
| } | ||
|
|
||
| // MARK: - Core Data stack | ||
|
|
||
| lazy var persistentContainer: NSPersistentContainer = { | ||
| /* | ||
| The persistent container for the application. This implementation | ||
| creates and returns a container, having loaded the store for the | ||
| application to it. This property is optional since there are legitimate | ||
| error conditions that could cause the creation of the store to fail. | ||
| */ | ||
| let container = NSPersistentContainer(name: "Challenge") | ||
| container.loadPersistentStores(completionHandler: { (storeDescription, error) in | ||
| if let error = error as NSError? { | ||
| // Replace this implementation with code to handle the error appropriately. | ||
| // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. | ||
|
|
||
| /* | ||
| Typical reasons for an error here include: | ||
| * The parent directory does not exist, cannot be created, or disallows writing. | ||
| * The persistent store is not accessible, due to permissions or data protection when the device is locked. | ||
| * The device is out of space. | ||
| * The store could not be migrated to the current model version. | ||
| Check the error message to determine what the actual problem was. | ||
| */ | ||
| fatalError("Unresolved error \(error), \(error.userInfo)") | ||
| } | ||
| }) | ||
| return container | ||
| }() | ||
|
|
||
| // MARK: - Core Data Saving support | ||
|
|
||
| func saveContext () { | ||
| let context = persistentContainer.viewContext | ||
| if context.hasChanges { | ||
| do { | ||
| try context.save() | ||
| } catch { | ||
| // Replace this implementation with code to handle the error appropriately. | ||
| // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. | ||
| let nserror = error as NSError | ||
| fatalError("Unresolved error \(nserror), \(nserror.userInfo)") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
let nserror = error as NSError
// fatalError()는 프로덕션 앱에서 사용하면 안됩니다.
// 오류 로깅 등 안정적인 오류 처리 방식으로 대체해야 합니다.
print("Unresolved error \(nserror), \(nserror.userInfo)")References
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| } | ||
|
|
||
11 changes: 11 additions & 0 deletions
11
Challenge/Challenge/Assets.xcassets/AccentColor.colorset/Contents.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "colors" : [ | ||
| { | ||
| "idiom" : "universal" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
35 changes: 35 additions & 0 deletions
35
Challenge/Challenge/Assets.xcassets/AppIcon.appiconset/Contents.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "idiom" : "universal", | ||
| "platform" : "ios", | ||
| "size" : "1024x1024" | ||
| }, | ||
| { | ||
| "appearances" : [ | ||
| { | ||
| "appearance" : "luminosity", | ||
| "value" : "dark" | ||
| } | ||
| ], | ||
| "idiom" : "universal", | ||
| "platform" : "ios", | ||
| "size" : "1024x1024" | ||
| }, | ||
| { | ||
| "appearances" : [ | ||
| { | ||
| "appearance" : "luminosity", | ||
| "value" : "tinted" | ||
| } | ||
| ], | ||
| "idiom" : "universal", | ||
| "platform" : "ios", | ||
| "size" : "1024x1024" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||
| <dependencies> | ||
| <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/> | ||
| <capability name="Safe area layout guides" minToolsVersion="9.0"/> | ||
| <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| </dependencies> | ||
| <scenes> | ||
| <!--View Controller--> | ||
| <scene sceneID="EHf-IW-A2E"> | ||
| <objects> | ||
| <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||
| <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||
| <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> | ||
| <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| <color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/> | ||
| <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/> | ||
| </view> | ||
| </viewController> | ||
| <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
| </objects> | ||
| <point key="canvasLocation" x="53" y="375"/> | ||
| </scene> | ||
| </scenes> | ||
| </document> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>_XCCurrentVersionName</key> | ||
| <string>Challenge.xcdatamodel</string> | ||
| </dict> | ||
| </plist> |
4 changes: 4 additions & 0 deletions
4
Challenge/Challenge/Challenge.xcdatamodeld/Challenge.xcdatamodel/contents
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
| <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="false" userDefinedModelVersionIdentifier=""> | ||
| <elements/> | ||
| </model> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>UIApplicationSceneManifest</key> | ||
| <dict> | ||
| <key>UIApplicationSupportsMultipleScenes</key> | ||
| <false/> | ||
| <key>UISceneConfigurations</key> | ||
| <dict> | ||
| <key>UIWindowSceneSessionRoleApplication</key> | ||
| <array> | ||
| <dict> | ||
| <key>UISceneConfigurationName</key> | ||
| <string>Default Configuration</string> | ||
| <key>UISceneDelegateClassName</key> | ||
| <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string> | ||
| </dict> | ||
| </array> | ||
| </dict> | ||
| </dict> | ||
| </dict> | ||
| </plist> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| // | ||
| // MusicModel.swift | ||
| // Challenge | ||
| // | ||
| // Created by Hanjuheon on 3/16/26. | ||
| // | ||
|
|
||
| struct MusicResponse: Decodable { | ||
| let resultCount: Int | ||
| let results: [Music] | ||
| } | ||
|
|
||
| struct Music: Decodable, Hashable, Sendable { | ||
| /// 응답 데이터의 최상위 타입 | ||
| /// 예: "track" | ||
| let wrapperType: String? | ||
|
|
||
| /// 결과 데이터의 종류 | ||
| /// 예: "song" | ||
| let kind: String? | ||
|
|
||
| /// 아티스트 고유 ID | ||
| let artistId: Int? | ||
|
|
||
| /// 앨범(컬렉션) 고유 ID | ||
| let collectionId: Int? | ||
|
|
||
| /// 트랙(곡) 고유 ID | ||
| let trackId: Int | ||
|
|
||
| /// 아티스트 이름 | ||
| let artistName: String? | ||
|
|
||
| /// 앨범명 | ||
| let collectionName: String? | ||
|
|
||
| /// 곡 제목 | ||
| let trackName: String? | ||
|
|
||
| /// 아티스트 페이지 URL | ||
| let artistViewUrl: String? | ||
|
|
||
| /// 앨범 페이지 URL | ||
| let collectionViewUrl: String? | ||
|
|
||
| /// 곡 페이지 URL | ||
| let trackViewUrl: String? | ||
|
|
||
| /// 곡 미리듣기 URL | ||
| let previewUrl: String? | ||
|
|
||
| /// 60x60 사이즈 앨범 이미지 URL | ||
| let artworkUrl60: String? | ||
|
|
||
| /// 100x100 사이즈 앨범 이미지 URL | ||
| let artworkUrl100: String? | ||
|
|
||
| /// 앨범 가격 | ||
| let collectionPrice: Double? | ||
|
|
||
| /// 곡 가격 | ||
| let trackPrice: Double? | ||
|
|
||
| /// 발매일 | ||
| let releaseDate: String? | ||
|
|
||
| /// 총 디스크 수 | ||
| let discCount: Int? | ||
|
|
||
| /// 현재 곡이 속한 디스크 번호 | ||
| let discNumber: Int? | ||
|
|
||
| /// 앨범 내 총 트랙 수 | ||
| let trackCount: Int? | ||
|
|
||
| /// 앨범 내 현재 트랙 번호 | ||
| let trackNumber: Int? | ||
|
|
||
| /// 곡 길이 (밀리초) | ||
| let trackTimeMillis: Int? | ||
|
|
||
| /// 국가 코드 | ||
| let country: String? | ||
|
|
||
| /// 대표 장르명 | ||
| let primaryGenreName: String? | ||
|
|
||
| // Hashable 식별을 위해 가급적 유일한 값인 trackId를 기준으로 고정하는 것이 좋습니다. | ||
| func hash(into hasher: inout Hasher) { | ||
| hasher.combine(trackId) | ||
| } | ||
|
|
||
| static func == (lhs: Music, rhs: Music) -> Bool { | ||
| return lhs.trackId == rhs.trackId | ||
| } | ||
| } | ||
|
|
||
|
|
||
| let mockMusics: [Music] = [ | ||
| Music(wrapperType: nil, kind: nil, artistId: 1, collectionId: 1, trackId: 1, artistName: "아이유", collectionName: "앨범1", trackName: "밤편지", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 2, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 3, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 4, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 5, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 6, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 7, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 8, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 9, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 10, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 11, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil), | ||
| Music(wrapperType: nil, kind: nil, artistId: 2, collectionId: 2, trackId: 12, artistName: "NewJeans", collectionName: "앨범2", trackName: "Ditto", artistViewUrl: nil, collectionViewUrl: nil, trackViewUrl: nil, previewUrl: nil, artworkUrl60: nil, artworkUrl100: nil, collectionPrice: nil, trackPrice: nil, releaseDate: nil, discCount: nil, discNumber: nil, trackCount: nil, trackNumber: nil, trackTimeMillis: nil, country: nil, primaryGenreName: nil) | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| // | ||
| // PodcastModel.swift | ||
| // Challenge | ||
| // | ||
| // Created by Hanjuheon on 3/17/26. | ||
| // | ||
|
|
||
| import Foundation | ||
|
|
||
| struct PodcastResponse: Decodable { | ||
| let resultCount: Int | ||
| let results: [Podcast] | ||
| } | ||
|
|
||
| struct Podcast: Decodable, Hashable { | ||
| let wrapperType: String? | ||
| let kind: String? | ||
| let trackId: Int? | ||
| let artistName: String? | ||
| let collectionName: String? | ||
| let trackName: String? | ||
|
|
||
| let artworkUrl60: String? | ||
| let artworkUrl600: String? | ||
|
|
||
| let collectionPrice: Double? | ||
| let trackPrice: Double? | ||
| let collectionHdPrice: Double? | ||
| let releaseDate: String? | ||
|
|
||
| let collectionExplicitness: String? | ||
| let trackExplicitness: String? | ||
|
|
||
| let trackCount: Int? | ||
| let trackTimeMillis: Int? | ||
|
|
||
| let country: String? | ||
| let currency: String? | ||
| let primaryGenreName: String? | ||
| let contentAdvisoryRating: String? | ||
|
|
||
| let genreIds: [String]? | ||
| let genres: [String]? | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
persistentContainer초기화 실패 시fatalError를 호출하여 앱을 강제 종료하고 있습니다. 프로덕션 환경에서는 앱이 크래시되는 대신, 오류를 기록하고 fallback UI를 보여주는 등 더 안정적인 방식으로 오류를 처리해야 합니다. 이는 앱 안정성에 치명적인 영향을 줄 수 있습니다.// fatalError()는 프로덕션 앱에서 사용하면 안됩니다. // 오류 로깅 및 사용자에게 알림 등 안정적인 오류 처리 방식으로 대체해야 합니다. print("Unresolved error \(error), \(error.userInfo)")References
fatalError는 의도적인 크래시를 유발하므로 이 규칙에 해당합니다. (link)