iOS

[iOS] Handling Different Data Types in Core Data / 코어 데이터에서 서로 다른 데이터 타입 다루기

Kim_Baechu 2022. 10. 19. 01:07

https://developer.apple.com/documentation/coredata/handling_different_data_types_in_core_data

Handling Different Data Types in Core Data

다양한 데이터 유형에 대한 레코드를 생성, 저장 및 표시합니다.

Overview

많은 앱들은 다른 종류의 정보를 유지하고 표시해야 합니다.

Core Data는 Date(날짜) 또는 Decimal(십진수) 유형과 같은 모든 데이터베이스에 대한 공통 특성 및 Transformable 유형으로 처리되는 비표준 특성을 포함하여 다양한 특성을 제공합니다.

또한 Transient(임시) 및 Derived(파생) 속성을 제공하므로 앱이 다른 데이터로부터 데이터를 파생할 수 있습니다.

이 예제는 북 레코드 집합을 만들고 표시하여 이러한 모든 데이터 유형을 처리하는 방법을 보여 줍니다.

실행 후 이 샘플은 레코드가 없는 경우 레코드를 자동으로 생성하고 목록에 표시합니다.

그 레코드들은 출판된 달에 따라 분류되며, 그들의 정규적인 형태의 제목으로 검색될 수 있습니다.

Derive a Non-Persistent Value Using a Transient Attribute

Transient(임시) 속성은 동일한 엔티티에 있는 하나 이상의 저장된 속성에서 파생됩니다.

이름에서 알 수 있듯이 Transient(임시) 속성은 스토어에 유지되지 않으므로 앱은 추가 저장 공간을 사용하지 않고 저장된 속성을 기반으로 새 속성을 제공하는 데 사용할 수 있습니다.

속성을 Transient(임시)로 만들려면 Xcode Project Navigator에서 Core Data 모델을 선택하고 Core Data 엔티티로 이동한 다음 속성 목록에서 속성을 선택한 다음 Data Model Inspector에서 Transient(임시)를 선택합니다.

이 예제에서는 publishMonthID는 publishDate에서 파생된 Transient(임시) 특성입니다.

파생 기능을 구현하기 위해 이 예제는 publishDate 및 publishMonthID에 대한 사용자 지정 접근자를 제공합니다.

publishDate의 setter 메서드는 primaryPublishMonthID를 무효화하며 publishMonthID의 getter 메서드가 현재 publishDate를 기준으로 값을 다시 계산하는 것을 허용합니다.

@objc public var publishDate: Date? {
    get {
        willAccessValue(forKey: Name.publishDate)
        defer { didAccessValue(forKey: Name.publishDate) }
        return primitivePublishDate
    }
    set {
        willChangeValue(forKey: Name.publishDate)
        defer { didChangeValue(forKey: Name.publishDate) }
        primitivePublishDate = newValue
        primitivePublishMonthID = nil
    }
}

primitivePublishMonthID가 nil이면 publishMonthID의 getter 메서드가 값을 다시 계산합니다.

@objc public var publishMonthID: String? {
    willAccessValue(forKey: Name.publishMonthID)
    defer { didAccessValue(forKey: Name.publishMonthID) }
    
    guard primitivePublishMonthID == nil, let date = primitivePublishDate else {
        return primitivePublishMonthID
    }
    let calendar = Calendar(identifier: .gregorian)
    let components = calendar.dateComponents([.year, .month], from: date)
    if let year = components.year, let month = components.month {
        primitivePublishMonthID = "\\(year * 1000 + month)"
    }
    return primitivePublishMonthID
}

이 두 가지 메서드로 publishMonthID는 publishDate와 연결되며 항상 최신 상태로 유지됩니다.

publishMonthID는 Swift에서 Key-Value Observing을 사용하고 있으며, 다음 코드는 게시 날짜가 변경될 때 관찰이 트리거되도록 합니다.

class func keyPathsForValuesAffectingPublishMonthID() -> Set<String> {
    return [Name.publishDate]
}

Derive One Value From Another Using a Derived Attribute

이 샘플은 Derived 속성인 canonicalTitle을 사용하여 책 제목의 표준 형식 검색을 지원합니다.

canonicalTitle은 Xcode의 Data Model Inspector에 표시된 Derivation 필드의 값으로 다음 식을 설정하여 제목의 표준 형식으로 구성됩니다.

canonical:(title)

Derived(파생) 특성은 스토리지 공간보다 성능이 더 중요한 경우에 사용됩니다.

이 예제에서 앱은 title을 직접검색해서  CONTAINS[cd] ( where cd means case- and diacritic-insensitive )를 사용한 predicate(NSPredicate)를 사용해서 title검색에서 같은 결과를 얻습니다.

persisted(유지되는) canonicalTitle을 검색함으로써, 앱은 모든 책 제목에 대해 diacritic-insensitive(발음구별부호-민감하지 않은) 비교를 할 필요가 없기 때문에 더 빠르게 수행합니다.

Derived(파생) 특성은 사용자가 managed context(관리 컨텍스트)를 저장할 때만 업데이트됩니다.

구체적으로, canonicalTitle은 샘플 앱이 타이틀 속성을 저장하지 않고 변경해도 변경되지 않습니다.

Configure and Implement a Non-Standard Data Type

Transformable(변환 가능한) 속성은 Xcode의 Data Model Inspector의 특성 유형 목록에 없는 유형 또는 비표준 유형을 가진 개체를 저장합니다.

Transformable(변환 가능한) 속성을 구현하려면 해당 유형을 Transformable로 설정하고 Data Model Inspector에서 트랜스포머와 사용자 지정 클래스 이름을 지정하여 구성한 다음 Core Data스택을 로드하기 전에 코드에 트랜스포머를 등록합니다.

// Register the transformer at the very beginning.
// .colorToDataTransformer is a name defined with an NSValueTransformerName extension.
ValueTransformer.setValueTransformer(ColorToDataTransformer(), forName: .colorToDataTransformer)

Core Data에는transformer가 NSSecureUnarchiveFromData 또는 해당 하위 클래스여야 하며, transformedValue(:) 메서드가 Data 오브젝트를 Data Model Inspector에 지정된 사용자 지정 클래스의 인스턴스로 변환하고 reverseTransformedValue(:)이 그 반대인 사용자 지정 클래스의 인스턴스를 Data 오브젝트로 변환해야 합니다.

Store and Present a Date Type

Core Data 저장소에서 날짜 속성은 1970년 이후 초 수를 나타내는 double값입니다.

다양한 달력, 시간대 및 로케일을 사용하여 앱은 Date 값을 다른 날짜 문자열로 변환하거나 날짜 문자열을 다른 Date 값으로 변환할 수 있습니다.

날짜 문자열을 파싱할 때 올바른 달력, 표준 시간대 및 로케일로 DateFormatter을 구성하세요.

일반적으로 문자열이 현재 사용자에 의해 생성된 경우 사용자가 인식하는 달력, 시간대 및 로케일은 현재 시스템 것이 되므로 앱은 기본 DateFormatter 인스턴스를 사용할 수 있습니다.

다른 경우에는 앱이 문자열을 생성한 것과 같은 방식으로 DateFormatter를 구성합니다.

Store and Present a Decimal Type

이 예제는 Decimal 속성을 사용하여 장부 가격을 나타내며 NSDecimalNumber 유형의 변수에 매핑됩니다.

NSDecimalNumber에는 통화 값을 처리하는 편리한 메서드가 있습니다.

newBook.price = NSDecimalNumber(mantissa: value, exponent: -2, isNegative: false)

NSDecimalNumber는 또한 로케일을 염두에 두고 값을 표시하는 편리한 메서드를 제공합니다.