AppleDocs for Field source files

This commit is contained in:
John Estropia
2020-03-26 01:57:32 +09:00
parent b6db872be0
commit 97f2a53124
14 changed files with 408 additions and 148 deletions

View File

@@ -1888,7 +1888,7 @@ From the **File** - **Swift Packages** - **Add Package Dependency…** menu, sea
```
CoreStore
```
where `JohnEstropia` is the *Owner*. Then add to your project.
where `JohnEstropia` is the *Owner* (forks may appear as well). Then add to your project.
### Objective-C support

View File

@@ -29,37 +29,84 @@ import Foundation
// MARK: - FieldRelationshipType
/**
Values to be used for `Field.Relationship` properties.
*/
public protocol FieldRelationshipType {
/**
The destination object's type
*/
associatedtype DestinationObjectType: CoreStoreObject
/**
The Objective-C native type synthesized by Core Data
*/
associatedtype NativeValueType: AnyObject
/**
The corresponding value for this field returned from `ObjectSnapshot` properties.
*/
associatedtype SnapshotValueType
/**
The corresponding value for this field returned from `ObjectPublisher` properties.
*/
associatedtype PublishedType
/**
Used internally by CoreStore. Do not call directly.
*/
static func cs_toReturnType(from value: NativeValueType?) -> Self
/**
Used internally by CoreStore. Do not call directly.
*/
static func cs_toPublishedType(from value: SnapshotValueType, in context: NSManagedObjectContext) -> PublishedType
/**
Used internally by CoreStore. Do not call directly.
*/
static func cs_toNativeType(from value: Self) -> NativeValueType?
/**
Used internally by CoreStore. Do not call directly.
*/
static func cs_toSnapshotType(from value: PublishedType) -> SnapshotValueType
/**
Used internally by CoreStore. Do not call directly.
*/
static func cs_valueForSnapshot(from objectIDs: [DestinationObjectType.ObjectID]) -> SnapshotValueType
}
// MARK: - FieldRelationshipToOneType: FieldRelationshipType
public protocol FieldRelationshipToOneType: FieldRelationshipType {}
// MARK: - FieldRelationshipToManyType: FieldRelationshipType where Self: Sequence
public protocol FieldRelationshipToManyType: FieldRelationshipType where Self: Sequence {}
// MARK: - FieldRelationshipToManyOrderedType: FieldRelationshipToManyType
public protocol FieldRelationshipToManyOrderedType: FieldRelationshipToManyType {}
// MARK: - FieldRelationshipToManyUnorderedType: FieldRelationshipToManyType
public protocol FieldRelationshipToManyUnorderedType: FieldRelationshipToManyType {}
// MARK: - Optional: FieldRelationshipType, FieldRelationshipToOneType where Wrapped: CoreStoreObject
extension Optional: FieldRelationshipType, FieldRelationshipToOneType where Wrapped: CoreStoreObject {
// MARK: FieldRelationshipType
public typealias DestinationObjectType = Wrapped
public typealias NativeValueType = NSManagedObject
@@ -95,8 +142,12 @@ extension Optional: FieldRelationshipType, FieldRelationshipToOneType where Wrap
}
// MARK: - Array: FieldRelationshipType, FieldRelationshipToManyType, FieldRelationshipToManyOrderedType where Element: CoreStoreObject
extension Array: FieldRelationshipType, FieldRelationshipToManyType, FieldRelationshipToManyOrderedType where Element: CoreStoreObject {
// MARK: FieldRelationshipType
public typealias DestinationObjectType = Element
public typealias NativeValueType = NSOrderedSet
@@ -135,8 +186,13 @@ extension Array: FieldRelationshipType, FieldRelationshipToManyType, FieldRelati
}
}
// MARK: - Set: FieldRelationshipType, FieldRelationshipToManyType, FieldRelationshipToManyUnorderedType where Element: CoreStoreObject
extension Set: FieldRelationshipType, FieldRelationshipToManyType, FieldRelationshipToManyUnorderedType where Element: CoreStoreObject {
// MARK: FieldRelationshipType
public typealias DestinationObjectType = Element
public typealias NativeValueType = NSSet

View File

@@ -34,17 +34,12 @@ extension FieldContainer {
// MARK: - Coded
/**
The containing type for stored property values. Any type that conforms to `FieldStorableType` are supported.
The containing type for stored property values. Any type supported by the specified encoder/decoder are allowed.
```
class Animal: CoreStoreObject {
@Field.Stored("species")
var species = ""
@Field.Virtual("pluralName", customGetter: Animal.pluralName(_:))
var pluralName: String = ""
@Field.Coded("color", coder: FieldCoders.Plist.self)
var color: UIColor?
@Field.Coded("eyeColor", coder: FieldCoders.NSCoding.self)
var eyeColor: UIColor = .black
}
```
- Important: `Field` properties are required to be used as `@propertyWrapper`s. Any other declaration not using the `@Field.Stored(...) var` syntax will be ignored.
@@ -56,34 +51,18 @@ extension FieldContainer {
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual("displayName", customGetter: Person.getName(_:))
var displayName: String = ""
private static func getName(_ object: ObjectProxy<Person>) -> String {
let cachedDisplayName = object.primitiveValue(for: \.$displayName)
if !cachedDisplayName.isEmpty {
return cachedDisplayName
}
let title = object.value(for: \.$title)
let name = object.value(for: \.$name)
let displayName = "\(title) \(name)"
object.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
@Field.Coded("eyeColor", coder: FieldCoders.NSCoding.self)
var eyeColor: UIColor = .black
}
```
- parameter initial: the initial value for the property when the object is first create
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter coder: The `FieldCoderType` to be used for encoding and decoding the value
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init<Coder: FieldCoderType>(
@@ -110,6 +89,24 @@ extension FieldContainer {
)
}
/**
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Coded("eyeColor", coder: FieldCoders.NSCoding.self)
var eyeColor: UIColor = .black
}
```
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter coder: The closures to be used for encoding and decoding the value
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
wrappedValue initial: @autoclosure @escaping () -> V,
_ keyPath: KeyPathString,
@@ -376,34 +373,18 @@ extension FieldContainer.Coded where V: FieldOptionalType {
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual("displayName", customGetter: Person.getName(_:))
var displayName: String = ""
private static func getName(_ object: ObjectProxy<Person>) -> String {
let cachedDisplayName = object.primitiveValue(for: \.$displayName)
if !cachedDisplayName.isEmpty {
return cachedDisplayName
}
let title = object.value(for: \.$title)
let name = object.value(for: \.$name)
let displayName = "\(title) \(name)"
object.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
@Field.Coded("eyeColor", coder: FieldCoders.NSCoding.self)
var eyeColor: UIColor? = nil
}
```
- parameter initial: the initial value for the property when the object is first create
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter coder: The `FieldCoderType` to be used for encoding and decoding the value
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init<Coder: FieldCoderType>(
@@ -430,6 +411,24 @@ extension FieldContainer.Coded where V: FieldOptionalType {
)
}
/**
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Coded("eyeColor", coder: FieldCoders.NSCoding.self)
var eyeColor: UIColor? = nil
}
```
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter coder: The closures to be used for encoding and decoding the value
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
wrappedValue initial: @autoclosure @escaping () -> V = nil,
_ keyPath: KeyPathString,
@@ -461,37 +460,20 @@ extension FieldContainer.Coded where V: FieldOptionalType {
extension FieldContainer.Coded where V: DefaultNSSecureCodable {
/**
Initializes the metadata for the property.
Initializes the metadata for the property. This overload is for types supported by Core Data's default NSSecureCodable implementation: `NSArray`, `NSDictionary`, `NSSet`, `NSString`, `NSNumber`, `NSDate`, `NSData`, `NSURL`, `NSUUID`, and `NSNull`.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual("displayName", customGetter: Person.getName(_:))
var displayName: String = ""
private static func getName(_ object: ObjectProxy<Person>) -> String {
let cachedDisplayName = object.primitiveValue(for: \.$displayName)
if !cachedDisplayName.isEmpty {
return cachedDisplayName
}
let title = object.value(for: \.$title)
let name = object.value(for: \.$name)
let displayName = "\(title) \(name)"
object.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
@Field.Coded("customInfo")
var customInfo: NSDictionary = [:]
}
```
- parameter initial: the initial value for the property when the object is first create
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
@@ -523,6 +505,23 @@ extension FieldContainer.Coded where V: DefaultNSSecureCodable {
extension FieldContainer.Coded where V: FieldOptionalType, V.Wrapped: DefaultNSSecureCodable {
/**
Initializes the metadata for the property. This overload is for types supported by Core Data's default NSSecureCodable implementation: `NSArray`, `NSDictionary`, `NSSet`, `NSString`, `NSNumber`, `NSDate`, `NSData`, `NSURL`, `NSUUID`, and `NSNull`.
```
class Person: CoreStoreObject {
@Field.Coded("customInfo")
var customInfo: NSDictionary? = nil
}
```
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
wrappedValue initial: @autoclosure @escaping () -> V = nil,
_ keyPath: KeyPathString,

View File

@@ -33,6 +33,23 @@ extension FieldContainer {
// MARK: - Relationship
/**
The containing type for relationships. Any `CoreStoreObject` subclass can be a destination type. Inverse relationships should be declared from the destination type as well, using the `inverse:` argument for the relationship.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Dog>
}
```
- Important: `Field` properties are required to be used as `@propertyWrapper`s. Any other declaration not using the `@Field.Relationship(...) var` syntax will be ignored.
*/
@propertyWrapper
public struct Relationship<V: FieldRelationshipType>: RelationshipKeyPathStringConvertible, FieldRelationshipProtocol {
@@ -264,8 +281,32 @@ extension FieldContainer {
}
}
// MARK: - FieldContainer.Relationship where V: FieldRelationshipToOneType
extension FieldContainer.Relationship where V: FieldRelationshipToOneType {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: KeyPathString,
deleteRule: DeleteRule = .nullify,
@@ -288,6 +329,28 @@ extension FieldContainer.Relationship where V: FieldRelationshipToOneType {
)
}
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init<D>(
_ keyPath: KeyPathString,
inverse: KeyPath<V.DestinationObjectType, FieldContainer<V.DestinationObjectType>.Relationship<D>>,
@@ -312,10 +375,39 @@ extension FieldContainer.Relationship where V: FieldRelationshipToOneType {
}
}
// MARK: - FieldContainer.Relationship: ToManyRelationshipKeyPathStringConvertible where V: FieldRelationshipToManyType
extension FieldContainer.Relationship: ToManyRelationshipKeyPathStringConvertible where V: FieldRelationshipToManyType {}
// MARK: - FieldContainer.Relationship where V: FieldRelationshipToManyOrderedType
extension FieldContainer.Relationship where V: FieldRelationshipToManyOrderedType {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Array<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: KeyPathString,
minCount: Int = 0,
@@ -340,6 +432,30 @@ extension FieldContainer.Relationship where V: FieldRelationshipToManyOrderedTyp
)
}
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Array<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init<D>(
_ keyPath: KeyPathString,
minCount: Int = 0,
@@ -366,8 +482,34 @@ extension FieldContainer.Relationship where V: FieldRelationshipToManyOrderedTyp
}
}
// MARK: - FieldContainer.Relationship where V: FieldRelationshipToManyUnorderedType
extension FieldContainer.Relationship where V: FieldRelationshipToManyUnorderedType {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: KeyPathString,
minCount: Int = 0,
@@ -392,6 +534,30 @@ extension FieldContainer.Relationship where V: FieldRelationshipToManyUnorderedT
)
}
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
@Field.Relationship("master")
var master: Person?
}
class Person: CoreStoreObject {
@Field.Relationship("pets", inverse: \.$master)
var pets: Set<Dog>
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init<D>(
_ keyPath: KeyPathString,
minCount: Int = 0,

View File

@@ -37,8 +37,9 @@ extension FieldContainer {
The containing type for stored property values. Any type that conforms to `FieldStorableType` are supported.
```
class Animal: CoreStoreObject {
@Field.Stored("species")
var species = ""
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("nickname")
var nickname: String?
@@ -53,27 +54,17 @@ extension FieldContainer {
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual(
"displayName",
customGetter: { (object, field) in
return "\(object.$title.value) \(object.$name.value)"
}
)
var displayName: String = ""
}
```
- parameter initial: the initial value for the property when the object is first create
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
@@ -320,34 +311,17 @@ extension FieldContainer.Stored where V: FieldOptionalType {
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual("displayName", customGetter: Person.getName(_:))
var displayName: String = ""
private static func getName(_ object: ObjectProxy<Person>) -> String {
let cachedDisplayName = object.primitiveValue(for: \.$displayName)
if !cachedDisplayName.isEmpty {
return cachedDisplayName
}
let title = object.value(for: \.$title)
let name = object.value(for: \.$name)
let displayName = "\(title) \(name)"
object.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
@Field.Stored("nickname")
var nickname: String?
}
```
- parameter initial: the initial value for the property when the object is first create
- parameter initial: the initial value for the property when the object is first created.
- parameter keyPath: the permanent attribute name for this property.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter previousVersionKeyPath: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property's `keyPath` with a matching destination entity property's `previousVersionKeyPath` indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's `keyPath`.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(

View File

@@ -34,17 +34,20 @@ extension FieldContainer {
// MARK: - Virtual
/**
The containing type for computed property values. Any type that conforms to `FieldStorableType` are supported.
The containing type for computed property values. Because this value is not persisted to the backing store, any type is supported. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.
```
class Animal: CoreStoreObject {
@Field.Virtual(
"pluralName",
customGetter: { (object, field) in
return object.$species.value + "s"
}
)
var pluralName: String
@Field.Stored("species")
var species = ""
@Field.Virtual("pluralName", customGetter: Animal.pluralName(_:))
var pluralName: String = ""
@Field.Coded("color", coder: FieldCoders.Plist.self)
var color: UIColor?
var species: String = ""
}
```
- Important: `Field` properties are required to be used as `@propertyWrapper`s. Any other declaration not using the `@Field.Virtual(...) var` syntax will be ignored.
@@ -53,34 +56,25 @@ extension FieldContainer {
public struct Virtual<V>: AttributeKeyPathStringConvertible, FieldAttributeProtocol {
/**
Initializes the metadata for the property.
Initializes the metadata for the property. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.
```
class Person: CoreStoreObject {
@Field.Stored("title")
var title: String = "Mr."
@Field.Stored("name")
var name: String = ""
@Field.Virtual("displayName", customGetter: Person.getName(_:))
var displayName: String = ""
private static func getName(_ object: ObjectProxy<Person>) -> String {
let cachedDisplayName = object.primitiveValue(for: \.$displayName)
if !cachedDisplayName.isEmpty {
return cachedDisplayName
@Field.Virtual(
"pluralName",
customGetter: { (object, field) in
return object.$species.value + "s"
}
let title = object.value(for: \.$title)
let name = object.value(for: \.$name)
let displayName = "\(title) \(name)"
object.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
)
var pluralName: String
@Field.Stored("species")
var species: String = ""
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `ObjectProxy<O>.$property.primitiveValue` instead of `ObjectProxy<O>.$property.value`, which would unintentionally execute the same closure again recursively.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
@@ -318,8 +312,32 @@ extension FieldContainer {
}
// MARK: - FieldContainer.Virtual where V: FieldOptionalType
extension FieldContainer.Virtual where V: FieldOptionalType {
/**
Initializes the metadata for the property. `Field.Virtual` properties are not allowed to have initial values, including `nil` for optional types.
```
class Person: CoreStoreObject {
@Field.Virtual(
"pluralName",
customGetter: { (object, field) in
return object.$species.value + "s"
}
)
var pluralName: String?
@Field.Stored("species")
var species: String = ""
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `ObjectProxy<O>`, which acts as a type-safe proxy for the receiver. When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively. Do not make assumptions on the thread/queue that the closure is executed on; accessors may be called from `NSError` logs for example.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `ObjectProxy<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `ObjectProxy<O>`, make sure to use `field.primitiveValue` instead of `field.value`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: KeyPathString,
customGetter: ((_ object: ObjectProxy<O>, _ field: ObjectProxy<O>.FieldProxy<V>) -> V)? = nil,

View File

@@ -35,6 +35,7 @@ extension DynamicObject where Self: CoreStoreObject {
The containing type for value propertiess.
```
class Pet: CoreStoreObject {
@Field.Stored("species")
var species = ""
@@ -66,6 +67,7 @@ extension DynamicObject where Self: CoreStoreObject {
The containing type for value properties. Use the `Field` typealias instead for shorter syntax.
```
class Pet: CoreStoreObject {
@Field.Stored("species")
var species = ""

View File

@@ -29,10 +29,30 @@ import CoreData
// MARK: - FieldCoderType
/**
Types that implement encoding to and decoding from `Data` to be used in `Field.Coded` properties' `coder:` argument.
```
class Person: CoreStoreObject {
@Field.Coded("profile", coder: FieldCoders.Json.self)
var profile: Profile = .init()
}
```
*/
public protocol FieldCoderType {
/**
The type to encode to and decode from `Data`
*/
associatedtype FieldStoredValue
/**
Encodes the value to `Data`
*/
static func encodeToStoredData(_ fieldValue: FieldStoredValue?) -> Data?
/**
Decodes the value from `Data`
*/
static func decodeFromStoredData(_ data: Data?) -> FieldStoredValue?
}

View File

@@ -30,6 +30,9 @@ import Foundation
extension FieldCoders {
/**
A `FieldCoderType` that implements the default Core Data transformable attribute behavior, which uses a `ValueTransformer` named `.secureUnarchiveFromDataTransformerName`.
*/
public struct DefaultNSSecureCoding<T: DefaultNSSecureCodable>: FieldCoderType {
// MARK: FieldCoderType
@@ -64,6 +67,11 @@ extension FieldCoders {
}
// MARK: - DefaultNSSecureCodable
/**
Types that are supported by `FieldCoders.DefaultNSSecureCoding`
*/
public protocol DefaultNSSecureCodable: NSObject, NSSecureCoding {}
extension NSArray: DefaultNSSecureCodable {}

View File

@@ -32,6 +32,10 @@ extension FieldCoders {
// MARK: - Json
/**
A `FieldCoderType` that implements JSON encoding and decoding of `Codable` values.
- Important: Due to restrictions of `JSONEncoder`, the value will be contained in single-item array before encoding.
*/
public struct Json<V: Codable>: FieldCoderType {
// MARK: FieldCoderType

View File

@@ -32,6 +32,9 @@ extension FieldCoders {
// MARK: - NSCoding
/**
A `FieldCoderType` that implements encoding and decoding of `NSCoding` values
*/
public struct NSCoding<V: Foundation.NSObject & Foundation.NSCoding>: FieldCoderType {
// MARK: FieldCoderType

View File

@@ -32,6 +32,10 @@ extension FieldCoders {
// MARK: - Plist
/**
A `FieldCoderType` that implements Binary-Plist encoding and decoding of `Codable` values.
- Important: Due to restrictions of `JSONEncoder`, the value will be contained in single-item array before encoding.
*/
public struct Plist<V: Codable>: FieldCoderType {
// MARK: FieldCoderType

View File

@@ -28,6 +28,9 @@ import Foundation
// MARK: - FieldOptionalType
/**
Optional values to be used for `Field` properties.
*/
public protocol FieldOptionalType: ExpressibleByNilLiteral {
/**
@@ -36,7 +39,7 @@ public protocol FieldOptionalType: ExpressibleByNilLiteral {
associatedtype Wrapped
/**
The wrapped value
Used internally by CoreStore. Do not call directly.
*/
var cs_wrappedValue: Wrapped? { get }
}
@@ -46,7 +49,7 @@ public protocol FieldOptionalType: ExpressibleByNilLiteral {
extension Optional: FieldOptionalType {
// MARK: Public
// MARK: FieldOptionalType
@inlinable
public var cs_wrappedValue: Wrapped? {

View File

@@ -30,6 +30,9 @@ import CoreGraphics
// MARK: - FieldStorableType
/**
Values to be used for `Field.Stored` properties.
*/
public protocol FieldStorableType {
/**
@@ -38,18 +41,18 @@ public protocol FieldStorableType {
associatedtype FieldStoredNativeType
/**
The `NSAttributeType` for this type
The `NSAttributeType` for this type. Used internally by CoreStore. Do not call directly.
*/
static var cs_rawAttributeType: NSAttributeType { get }
/**
Creates an instance of this type from raw native value.
Creates an instance of this type from raw native value. Used internally by CoreStore. Do not call directly.
*/
@inline(__always)
static func cs_fromFieldStoredNativeType(_ value: FieldStoredNativeType) -> Self
/**
Creates `FieldStoredNativeType` value from this instance.
Creates `FieldStoredNativeType` value from this instance. Used internally by CoreStore. Do not call directly.
*/
@inline(__always)
func cs_toFieldStoredNativeType() -> Any?