SwiftData 알아보기 (1)

doyeonjeong_·2023년 6월 20일
1

WWDC

목록 보기
3/4
post-thumbnail
post-custom-banner

Hits

WWDC 영상 바로가기 : Meet SwiftData

안녕하세요 비비입니다!
WWDC23 영상을 탐방하다가 SwiftData에 관심이 생겨 보던 중
보기만하면 기억에 남지 않을 것 같아서 기록을 시작해봅니다.

개인적으로는 JAVA의 SpringBoot 프레임워크가 생각나서
뭔가 CoreData 보다 친숙한 느낌이라 얼른 사용해보고싶네요!

정리한 내용 중 오역이 있다면 언제든지 말씀해주세요 😄


🌲 SwiftData란?

데이터 모델링 및 관리를 위한 프레임워크입니다.
SwiftUI와 마찬가지로 외부 파일 형식이 없는 코드에 전적으로 집중하고,
원활한 API 경험을 위해 새로운 Swift 매크로가 제공하는 표현력에 의존합니다.
또한 SwiftUI와 자연스럽게 통합되며 CloudKitWidgets와 같은 다른 플랫폼 기능과 함께 작동합니다.


🌲 Using the model

@Model 매크로 사용하기

  • Swift 코드에서 모델의 스키마를 정의하는 데 사용됩니다.
  • 클래스를 장식하는걸로 간단하게 스키마를 생성할 수 있습니다.
import SwiftData

@Model
class Trip {
    var name: String
    var destination: String
    var endDate: Date
    var startDate: Date
 
    var bucketList: [BucketListItem]? = []
    var livingAccommodation: LivingAccommodation?
}

*스키마(Schema): Database의 구조와 제약조건에 관해 전반적인 명세를 기술한 것. 즉 어떤 속성(Attribute)들로 이루어진 개체(Entity)들과, 그 개체들끼리의 관계(Relation)에 대한 정의 및 제약조건들을 기술한 것 입니다.

🌿 속성(Attributes)

🌱 Attributes inferred from properties
속성으로 즉시 사용할 수 있도록 값 유형 속성을 조정합니다.

🌱 Support for basic value types
String, Int 및 Float와 같은 기본 값 유형이 포함됩니다.

🌱 Complex value types

  • Struct
  • Enum
  • Codable
  • Collections of value types

컬렉션을 포함하여 구조체, 열거형 및 코딩 가능한 유형과 같은 보다 복잡한 값 유형을 포함할 수 있습니다.
즉, @Model 매크로만으로 속성을 쉽게 정의할 수 있습니다.

🌿 관계(Relationships)

🌱 Relationships are inferred from reference types

  • Other model types
  • Collections of model types

SwiftData 모델은 유형을 관계로 참조합니다.
관계 및 모델 유형 컬렉션을 사용하여 모델 유형 간에 연결할 수 있습니다.

🌿 Additional metadata

🌱 @Model 은 저장된 모든 속성을 수정할 수 있습니다.

🌱 아래의 매크로를 이용해 속성과 관계를 정의합니다.

  • @Attribute
  • @Relationship

🌱 @Transient로 속성을 제외할 수 있습니다.
👉🏻 이건 Model your schema with SwiftData 에서 자세히 봐야겠습니다!

@Model
class Trip {
    @Attribute(.unique) var name: String // Unique 지정
    var destination: String
    var endDate: Date
    var startDate: Date
 
    @Relationship(.cascade) var bucketList: [BucketListItem]? = [] // Trip 객체 삭제시 같이 삭제되도록 설정
    var livingAccommodation: LivingAccommodation?
}

🌲 Working with your data

데이터 바인딩에 사용되는 2가지 주요 개체 ModelContainerModelContext 를 살펴볼게요!

🌿 Model Container

저장하려는 모델 유형 목록을 지정하기만 하면 모델 컨테이너를 만들 수 있습니다.
컨테이너를 설정하여 모델 컨텍스트로 데이터를 가져오고 저장할 준비를 할 수 있습니다.

🌱 Persistence Backend
모델 유형에 대한 영구 백엔드 제공

🌱 Customized with configurations & Provides schema migration options
configurations 속성으로 URL, CloudKit그룹 컨테이너 식별자, 마이그레이션 옵션 등을 커스터마이징할 수 있습니다.

// Initialize with only a schema
let container = try ModelContainer([Trip.self, LivingAccommodation.self])

// Initialize with configurations
let container = try ModelContainer(
    for: [Trip.self, LivingAccommodation.self],
    configurations: ModelConfiguration(url: URL("path"))
)

🧐 이 부분에서는 Trip과 LivingAccommodation을 동시에 container에 담는 것 같은데
DeepDive하면서 어떻게 정의되는건지 한번 더 살펴봐야겠습니다.

🌱 SwiftUI에서 사용하는 방법

import SwiftUI

@main
struct TripsApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(
            for: [Trip.self, LivingAccommodation.self]
        )
    }
}

🌿 Model Context

🌱 Tracking updates
🌱 Fetching model
🌱 Saving changes
🌱 Undoing changes

업데이트 추적, 데이터 가져오기, 변경 사항 저장하기, 변경 사항 실행 쉬소하기 기능의 인터페이스입니다.

import SwiftUI

struct ContextView : View {
    @Environment(\.modelContext) private var context
}
import SwiftData

// 1. 일반적으로 모델 컨테이너를 생성한 후 뷰의 환경에서 modelContext를 가져오는 경우
let context = container.mainContext

// 뷰 계층 구조 외부에서 공유된 기본 액터 바인딩 컨텍스트를 제공하도록 모델 컨테이너에 요청하거나
// 2. 주어진 모델 컨테이너에 대한 새 컨텍스트를 간단히 인스턴스화 하는 경우
let context = ModelContext(container)

컨텍스트가 있으면 데이터를 가져올 준비가 된 것입니다.

🧐 라고 소개는 되어있지만, 정확하게 context가 뭘 의미하는건지는 조금 더 알아봐야겠습니다. 왜냐하면 위에서 modelContainer[Trip.self, LivingAccommodation.self]으로 2개의 model을 동시에 가지고 있는데 context를 활용하여 데이터를 어떻게 가져온다는건지 이 코드만 보고 확신할 수는 없네요..!

🌿 Fetching your data

🌱  새로운 Swift 기본 유형

  • Predicate
  • FetchDescriptor

🌱  SortDescriptor의 개선 사항

🪴 Predicate

let today = Date()
let tripPredicate = #Predicate<Trip> { 
    $0.destination == "New York" && // 목적지 : 뉴욕
    $0.name.contains("birthday") && // 키워드 : 생일
    $0.startDate > today // 오늘 이후, 계획된 여행 탐색
}

메모리의 데이터를 필터링 하여 가져오기 위한 쿼리 조건이라고 해야할까요
CoreData 에서 사용하던 NSPredicate의 iOS 17 버전이라고 할 수 있습니다.

🪴 FetchDescriptor

let descriptor = FetchDescriptor<Trip>(predicate: tripPredicate)

let trips = try context.fetch(descriptor)

FetchDescriptorSwiftData 쿼리를 맞춤화하는 방법을 제공합니다.
위와같이 필터 조건을 지정한 후 FetchDescriptor를 통해 가져올 수 있습니다.

🪴 SortDescriptor

🌱 Updated to support all Comparable types Swift native keypaths
기본 Swift 유형 및 키 경로를 지원하기 위해 모든 비교 유형을 지원하도록 업데이트 되었습니다.

let descriptor = FetchDescriptor<Trip>(
    sortBy: SortDescriptor(\Trip.name),
    predicate: tripPredicate
)

let trips = try context.fetch(descriptor)

SortDescriptor를 사용하여 가져온 여행을 구성할 순서를 지정할 수 있습니다.

🌿 More FetchDescriptor options

PredicateSortDescriptor 외에도 prefetch할 관련 개체를 지정하고
결과 수를 제한하고 결과에서 저장되지 않은 변경 사항을 제외하는 등의 작업을 수행할 수 있습니다.

🌱 Relationships to prefetch
🌱 Result limits
🌱 Exclude unsaved changes

🌿 Modifying your data

ModelContext를 사용하여 이러한 작업을 구동함으로써 데이터를 쉽게 생성, 삭제 및 변경할 수 있습니다.

🌱 Basic operations (CRUD)

  • Inserting
  • Deleting
  • Saving
  • Changing
var myTrip = Trip(name: "Birthday Trip", destination: "New York")

// Insert a new trip
context.insert(myTrip)

// Delete an existing trip
context.delete(myTrip)

// Manually save changes to the context
try context.save()

@Model 매크로는 ModelContext가 변경 사항을 자동으로 추적하고 다음 저장 작업에 포함하도록 돕는다고 합니다.


🌲 Using SwiftData with SwiftUI

  • SwiftUI와의 원활한 통합
  • 쉬운 구성
  • 자동으로 데이터 Fetching

🌿 View Modifiers

데이터 저장소를 구성하고, 옵션을 변경하고, 실행 취소를 활성화하고, 자동 저장을 전환할 수 있습니다.

🌱 Leverage scene and view modifiers (뭐라고 해석하면 좋을지 혹시 아시는 분 계실까요 ?)
🌱 .modelContainer를 사용하여 데이터 저장소 구성
🌱 SwiftUI environment로 등록하여 사용하기

설정한 후 데이터 사용을 시작하는 가장 쉬운 방법은 새로운 @Query 속성 래퍼입니다.
한 줄의 코드로 데이터베이스에 저장된 모든 항목을 쉽게 로드하고 필터링할 수 있습니다.

import SwiftUI

struct ContentView: View  {
    @Query(sort: \.startDate, order: .reverse) var trips: [Trip]
    @Environment(\.modelContext) var modelContext
    
    var body: some View {
       NavigationStack() {
          List {
             ForEach(trips) { trip in 
                 // ...
             }
          }
       }
    }
}

🌲 마무리하며…

Meet SwiftData는 소개하는 내용이 많아 구체적인 코드를 살펴보기엔 짧은 감이 있네요 !
다음은 Build an app with SwiftData를 보고 조금 더 DeepDive 해보겠습니다!
부족한 글이지만 읽어주셔서 감사합니다 😊

profile
블로그 이사중 🚚 byukbyak.tistory.com
post-custom-banner

0개의 댓글