Big Idea (큰 주제)
- 코드분석
Essential Question (핵심 질문)
- Scrumdinger 에서 해당 코드를 쓴 이유에 대해 나는 잘 이해하고 있을까?
Challenge (도전 과제)
- 하나의 뷰에서 내가 모르는 코드에 대해 분석해보자
Activities (학습 활동)
이번에 할 파일은 ScrumsView 이다.
import SwiftUI
import SwiftData
struct ScrumsView: View {
@Query(sort: \DailyScrum.title) private var scrums: [DailyScrum]
@State private var isPresentingNewScrumView = false
var body: some View {
NavigationStack {
List(scrums) { scrum in
NavigationLink(destination: DetailView(scrum: scrum)) {
CardView(scrum: scrum)
}
.listRowBackground(scrum.theme.mainColor)
}
.navigationTitle("Daily Scrums")
.toolbar {
Button(action: {
isPresentingNewScrumView = true
}) {
Image(systemName: "plus")
}
.accessibilityLabel("New Scrum")
}
.sheet(isPresented: $isPresentingNewScrumView) {
NewScrumSheet()
}
}
}
}
#Preview {
ScrumsView()
}
@Query(sort: \DailyScrum.title) private var scrums: [DailyScrum]
https://developer.apple.com/kr/xcode/swiftdata/
SwiftData - Xcode - Apple Developer
SwiftData를 사용하면 선언적 코드를 사용하여 데이터를 쉽게 유지할 수 있습니다. 일반 Swift 코드를 사용하여 데이터를 쿼리 및 필터링할 수 있으며, SwiftUI와 매끄럽게 통합할 수 있습니다.
developer.apple.com
@Query 는 SwiftData를 가져올 수 있다.
설명을 보면, SwiftData와 SwiftUI가 연동되어 기본 데이터 변경 시 뷰에 라이브 업데이트를 제공하므로 결과를 수동으로 새로고침할 필요가 없다. 라고 나와있다.
SwiftData는
Core Data 의 Persistent 기술과 Swift의 concurrency 기능을 결합하고, 외부 종속성이 없어 최소한의 코드 구현이 가능하다.
기본 모델 데이터를 저장, 여러 기기 간 데이터 동기화 처리도 가능하다. 또한, 캐싱 매커니즘이나 제한적인 오프라인 기능을 제공할 수 있다.
이때 사용하는 매크로들이 바로
@Model, @Attribute, @Relationship 이다.
이들을 모델 속성으로 사용하여 커스터마이징 할 수 있다.
그리고 ModelContext 클래스를 사용하여 model instance 를 C,U,D 한다.
이 뷰 모델을 표시할 때 사용하는 매크로가 바로 @Query 이며, 이를 이용해 조건 또는 Fetch Descriptor 를 지정하면 된다.
이 ModelContext 는 SwiftUI 에서 접근하고, modelContainer 및 ModelContext modifiers 를 이용해 특정 컨텍스트나 컨테이너를 지정할 수도 있다.
여기서 질문1, Scrumdinger 앱에서 DailyScrum 모델에는 왜 Attribute 를 붙이지 않고 사용한거지??

답변을 하자면,
SwiftData에서는 기본적으로 id는 자동으로 인식됨. (이야.. 좋은 세상이다 역시)
- SwiftData는 UUID 타입의 id를 자동으로 고유 식별자(primary key)로 인식합니다.
- 이때 @Attribute를 생략해도 내부적으로는 속성으로 처리되기 때문에 문제가 발생하지 않습니다.
단, Core Data 키워드와 이름이 겹치는 속성 의 이름은 에러가 나니 주의 해야한다.
나도 한번 먹어봤던 경고.. ⚠️
Fatal error: Unable to have an Attribute named description
@Attribute(originalName:)
뭐 이런식으로 회피가 가능하다고는 하는데
그냥 쓰지 말자 (ex: description, hash)
.listRowBackground(scrum.theme.mainColor)
List 의 Row 에서만 쓰는 특수한 listRow.... modifier 들
- listRowBackground(_:)
각 row의 배경을 설정. Color나 View(예: RoundedRectangle)도 지정 가능.
예: .listRowBackground(Color.yellow) - listRowSeparator(_:)
해당 row의 separator(구분선)를 보이거나 숨길 수 있음.
값으로 .visible 또는 .hidden 사용 가능.
예: .listRowSeparator(.hidden) - listRowSeparatorTint(_:)
row separator의 색상을 설정할 수 있음.
예: .listRowSeparatorTint(.red) - listRowInsets(_:)
row의 내부 여백(padding)을 직접 지정할 수 있음.
EdgeInsets를 사용해서 top, leading, bottom, trailing 여백을 조정할 수 있음.
예: .listRowInsets(EdgeInsets(top: 10, leading: 20, bottom: 10, trailing: 20)) - listRowPlatter(_:)
visionOS에서 사용하는 modifier. 일반 iOS에서는 거의 쓰지 않음.
이거 말고도 NavigationLink 에 적용되는 것들 중에 아래와 같은 modifier도 있다.
이건 이정도 있구나로 알아두면 될 듯.
isDetailLink(_:) : iPad에서 Split View로 push할지 여부를 결정
tint(_:) : NavigationLink 내부의 라벨 색상을 커스터마이즈 (iOS 15+)
https://developer.apple.com/documentation/swiftui/navigationstack
NavigationStack | Apple Developer Documentation
A view that displays a root view and enables you to present additional views over the root view.
developer.apple.com
.sheet
func sheet<Content>(
isPresented: Binding<Bool>,
onDismiss: (() -> Void)? = nil,
@ViewBuilder content: @escaping () -> Content
) -> some View where Content : View
https://developer.apple.com/documentation/swiftui/view/sheet(item:ondismiss:content:)
sheet(item:onDismiss:content:) | Apple Developer Documentation
Presents a sheet using the given item as a data source for the sheet’s content.
developer.apple.com
Solution (해결 결과)
- 안그래도 오늘 작업하면서 NavigationStack 을 쓰는데, 이것저것 한번 넣어봐야겠다. 라는 생각이 들었다.
- SwiftData 에 대해 더 자세히 알고 싶어졌다.
- 특히 List 에 CardView 라는 View 를 만들었는데 이상하게 중간쯤부터 이상하게 밑줄이 그어지는 문제가 있었다. 이부분 한번 파봐야겠다.🤔
Reflection (회고)
오늘 배운 것:
SwiftData, NavigationStack 맛보기
오늘은 너무 피곤해서 여기까지ㅠㅠ 뒤에 코드 분석 내용들은 좀 더 빌드업해서 추가로 정리하겠음!!
다음에 공부해보고 싶은 것:
1. 남은 코드 분석
2. 같은 러너인 미니가 알려준 public, private 외에 추가적인 접근제어 open, internal, fileprivate, private(set)과 관련된 키워드
3. SwiftData 더 알아보기
4. NavigationStack 더 알아보기
'iOS > App' 카테고리의 다른 글
Scrumdinger 분석하기 03 /scrum/DetailView.swift (0) | 2025.04.28 |
---|---|
Scrumdinger 분석하기 02-2. /scrum/ScrumsView.swift (0) | 2025.04.17 |
Scrumdinger 분석하기 01. /scrum/CardView.swift (0) | 2025.04.14 |
Scrumdinger 개발 10 : Recording audio (0) | 2025.04.10 |
Scrumdinger 개발 09 : Drawing the timer view (0) | 2025.04.09 |