반응형

SwiftData는 iOS 17.0, iPadOS 17.0, macOS 14, Mac Catalyst 17, tvOS 17, watchOS 10 에서 사용가능

SwfitData는 데이터 모델링 및 관리를 위한 프레임워크입니다.

@Model은 Swift 코드에서 모델의 스키마(schema)를 정의하는데 도움이 되는 Swift 매크로(macro)입니다.

모델 매크로 사용
 - 프로퍼티로부터 속성을 추론합니다.
 - 기본적으로 값 타입을 지원합니다.
 - 복잡한 값 타입을 포함합니다 (Struct, Enum, Codable, Collections)

@Model은 타입의 모든 저장(stored) 프로퍼티를 수정합니다.

@Attribute는 유일한(uniqueness) 제약조건을 추가할 수 있습니다.

@Relationship은 반전 선택을 제어하고 삭제를 처리하는 규칙을 지정할 수 있습니다.

@Model
class Trip {
    @Attribute(.unique) var name: String
    var destination: String
    var endDate: Date
    var startDate: Date
 
    @Relationship(.cascade) var bucketList: [BucketListItem]? = []
    var livingAccommodation: LivingAccommodation?
}

이름(name)은 유일하도록 하고, 버킷리스트(bucketList)는 관계형으로 만들고 여행(Trip)이 삭제될때마다 관련된 버킷리스트 항목을 모두 삭제하도록 합니다. 

SwiftData 모델링은 "Model your schema with SwiftData"를 참조하세요. 

모델 타입으로 작업하고 사용하는데 필요한 2가지 
- ModelContainer
- ModelContext

// 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"))
)

모델 컨테이너(ModelContainer)는 모델 타입에 대한 백앤드(iCloud) 데이터를 제공합니다.  스키마를 지정함으로써 백앤드에 데이터를 구성할 수 있습니다. 

모델 컨텍스트(ModelContext)는 모델의 모든 변경사항을 관찰하고, 추가적인 작업을 제공(업데이트 추적, 데이터 가져오기, 변경사항 저장, 변경사항 실행취소)합니다.

import SwiftUI

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

 

import SwiftUI

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

SwiftUI에서 모델 컨테이너를 만들고나서 뷰 환경(Environment) 변수로 modelContext를 사용합니다.

데이터 가져오기를 위한 개선된 새로운 타입 
- Predicate
- FetchDescriptor

let today = Date()
let tripPredicate = #Predicate<Trip> { 
    $0.destination == "New York" &&
    $0.name.contains("birthday") &&
    $0.startDate > today
}

뉴욕이 목적지이고, 생일에 대한 여행으로 명시

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

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

let trips = try context.fetch(descriptor)

이름으로 정렬하기

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()

여행을 생성하고 추가, 삭제, 저장하기

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 
                 // ...
             }
          }
       }
    }
}

@Query 프로퍼티 래퍼(property wrapper): 데이터베이스에 저장된 항목을 쉽게 로딩하고, 필터링 할 수 있습니다.

SwiftData 컨테이너와 컨텍스트와 사용하는 방법에 대해서는 "Dive Deeper into SwiftData"를 참조하세요. 

 

 

 

반응형
Posted by 까칠코더
,