updated documentation (fixes #198)

This commit is contained in:
John Rommel Estropia
2017-10-11 07:50:24 +09:00
parent 50e50c0613
commit b4117eeb02
14 changed files with 99 additions and 269 deletions

View File

@@ -1675,7 +1675,7 @@ To use these syntax sugars, include *CoreStoreBridge.h* in your Objective-C sour
Starting CoreStore 4.0, we can now create persisted objects without depending on *.xcdatamodeld* Core Data files. The new `CoreStoreObject` subclass replaces `NSManagedObject`, and specially-typed properties declared on these classes will be synthesized as Core Data attributes.
```swift
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
}
class Dog: Animal {
@@ -1684,14 +1684,14 @@ class Dog: Animal {
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
The property names to be saved to Core Data is specified as the `keyPath` argument. This lets us refactor our Swift code without affecting the underlying database. For example:
```swift
class Person: CoreStoreObject {
private let _name = Value.Required<String>("name")
private let _name = Value.Required<String>("name", initial: "")
// ...
}
```

View File

@@ -47,12 +47,6 @@ public enum LogLevel {
*/
public protocol CoreStoreLogger {
/**
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false` if not implemented.
*/
// TODO: test before release (rolled back)
// var enableObjectConcurrencyDebugging: Bool { get set }
/**
Handles log messages sent by the `CoreStore` framework.
@@ -100,13 +94,6 @@ public protocol CoreStoreLogger {
extension CoreStoreLogger {
// TODO: test before release (rolled back)
// public var enableObjectConcurrencyDebugging: Bool {
//
// get { return false }
// set {}
// }
public func abort(_ message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
Swift.fatalError(message, file: fileName, line: UInt(lineNumber))

View File

@@ -33,13 +33,13 @@ import Foundation
The `CoreStoreObject` is an abstract class for creating CoreStore-managed objects that are more type-safe and more convenient than `NSManagedObject` subclasses. The model entities for `CoreStoreObject` subclasses are inferred from the Swift declaration themselves; no .xcdatamodeld files are needed. To declare persisted attributes and relationships for the `CoreStoreObject` subclass, declare properties of type `Value.Required<T>`, `Value.Optional<T>` for values, or `Relationship.ToOne<T>`, `Relationship.ToManyOrdered<T>`, `Relationship.ToManyUnordered<T>` for relationships.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
}
```
@@ -141,6 +141,9 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
public extension DynamicObject where Self: CoreStoreObject {
/**
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.
*/
public func partialObject() -> PartialObject<Self> {
CoreStore.assert(

View File

@@ -33,13 +33,13 @@ import Foundation
The `CoreStoreSchema` describes models written for `CoreStoreObject` Swift class declarations for a particular model version. `CoreStoreObject` entities for a model version should be added to `CoreStoreSchema` instance.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
}
@@ -66,13 +66,13 @@ public final class CoreStoreSchema: DynamicSchema {
Initializes a `CoreStoreSchema`. Using this initializer only if the entities don't need to be assigned to particular "Configurations". To use multiple configurations (for example, to separate entities in different `StorageInterface`s), use the `init(modelVersion:entitiesByConfiguration:versionLock:)` initializer.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
}
@@ -112,12 +112,12 @@ public final class CoreStoreSchema: DynamicSchema {
Initializes a `CoreStoreSchema`. Using this initializer if multiple "Configurations" (for example, to separate entities in different `StorageInterface`s) are needed. To add an entity only to the default configuration, assign an empty set to its configurations list. Note that regardless of the set configurations, all entities will be added to the default configuration.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
}
CoreStore.defaultStack = DataStack(

View File

@@ -105,9 +105,6 @@ public final class DataStack: Equatable {
*/
public required init(schemaHistory: SchemaHistory) {
// TODO: test before release (rolled back)
// _ = DataStack.isGloballyInitialized
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: schemaHistory.rawModel)
self.rootSavingContext = NSManagedObjectContext.rootSavingContextForCoordinator(self.coordinator)
self.mainContext = NSManagedObjectContext.mainContextForRootContext(self.rootSavingContext)
@@ -585,13 +582,6 @@ public final class DataStack: Equatable {
// MARK: Private
// TODO: test before release (rolled back)
// private static let isGloballyInitialized: Bool = {
//
// NSManagedObject.cs_swizzleMethodsForLogging()
// return true
// }()
private var persistentStoresByFinalConfiguration = [String: NSPersistentStore]()
private var finalConfigurationsByEntityIdentifier = [EntityIdentifier: Set<String>]()

View File

@@ -33,12 +33,6 @@ import Foundation
*/
public final class DefaultLogger: CoreStoreLogger {
/**
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false`.
*/
// TODO: test before release (rolled back)
// public var enableObjectConcurrencyDebugging: Bool = false
/**
Creates a `DefaultLogger`.
*/

View File

@@ -34,13 +34,13 @@ import ObjectiveC
The `Entity<O>` contains `NSEntityDescription` metadata for `CoreStoreObject` subclasses. Pass the `Entity` instances to `CoreStoreSchema` initializer.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
}

View File

@@ -425,8 +425,6 @@ public final class ICloudStore: CloudStorage {
*/
public func cs_eraseStorageAndWait(soureModel: NSManagedObjectModel) throws {
// TODO: check if attached to persistent store
let cacheFileURL = self.cacheFileURL
try autoreleasepool {

View File

@@ -66,212 +66,4 @@ internal extension NSManagedObject {
}
return nil
}
// TODO: test before release (rolled back)
// @nonobjc
// internal static func cs_swizzleMethodsForLogging() {
//
// struct Static {
//
// static let isSwizzled = Static.swizzle()
//
// private static func swizzle() -> Bool {
//
// NSManagedObject.cs_swizzle(
// original: #selector(NSManagedObject.willAccessValue(forKey:)),
// proxy: #selector(NSManagedObject.cs_willAccessValue(forKey:))
// )
// NSManagedObject.cs_swizzle(
// original: #selector(NSManagedObject.willChangeValue(forKey:)),
// proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:))
// )
// NSManagedObject.cs_swizzle(
// original: #selector(NSManagedObject.willChangeValue(forKey:withSetMutation:using:)),
// proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:withSetMutation:using:))
// )
// return true
// }
// }
// assert(Static.isSwizzled)
// }
//
// @nonobjc
// private static func cs_swizzle(original originalSelector: Selector, proxy swizzledSelector: Selector) {
//
// let originalMethod = class_getInstanceMethod(NSManagedObject.self, originalSelector)
// let swizzledMethod = class_getInstanceMethod(NSManagedObject.self, swizzledSelector)
// let didAddMethod = class_addMethod(
// NSManagedObject.self,
// originalSelector,
// method_getImplementation(swizzledMethod),
// method_getTypeEncoding(swizzledMethod)
// )
// if didAddMethod {
//
// class_replaceMethod(
// NSManagedObject.self,
// swizzledSelector,
// method_getImplementation(originalMethod),
// method_getTypeEncoding(originalMethod)
// )
// }
// else {
//
// method_exchangeImplementations(originalMethod, swizzledMethod)
// }
// }
//
// private dynamic func cs_willAccessValue(forKey key: String?) {
//
// self.cs_willAccessValue(forKey: key)
//
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
//
// return
// }
//
// guard let context = self.managedObjectContext else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
// )
// return
// }
// if context.isTransactionContext {
//
// guard let transaction = context.parentTransaction else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
// )
// return
// }
// CoreStore.assert(
// transaction.isRunningInAllowedQueue(),
// "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
// )
// return
// }
// if context.isDataStackContext {
//
// guard context.parentStack != nil else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
// return
// }
// CoreStore.assert(
// Thread.isMainThread,
// "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside the main thread."
// )
// return
// }
// }
//
// private dynamic func cs_willChangeValue(forKey key: String?) {
//
// self.cs_willChangeValue(forKey: key)
//
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
//
// return
// }
//
// guard let context = self.managedObjectContext else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
// )
// return
// }
// if context.isTransactionContext {
//
// guard let transaction = context.parentTransaction else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
// )
// return
// }
// CoreStore.assert(
// transaction.isRunningInAllowedQueue(),
// "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
// )
// return
// }
// if context.isDataStackContext {
//
// guard context.parentStack != nil else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
// return
// }
// CoreStore.assert(
// Thread.isMainThread,
// "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside the main thread."
// )
// return
// }
// }
//
// private dynamic func cs_willChangeValue(forKey inKey: String, withSetMutation inMutationKind: NSKeyValueSetMutationKind, using inObjects: Set<AnyHashable>) {
//
// self.cs_willChangeValue(
// forKey: inKey,
// withSetMutation: inMutationKind,
// using: inObjects
// )
//
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
//
// return
// }
//
// guard let context = self.managedObjectContext else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
// )
// return
// }
// if context.isTransactionContext {
//
// guard let transaction = context.parentTransaction else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
// )
// return
// }
// CoreStore.assert(
// transaction.isRunningInAllowedQueue(),
// "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
// )
// return
// }
// if context.isDataStackContext {
//
// guard context.parentStack != nil else {
//
// CoreStore.log(
// .warning,
// message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
// return
// }
// CoreStore.assert(
// Thread.isMainThread,
// "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside the main thread."
// )
// return
// }
// }
}

View File

@@ -34,6 +34,9 @@ import Foundation
*/
public struct PartialObject<O: CoreStoreObject> {
/**
Returns a the actual `CoreStoreObject` instance for the receiver.
*/
public func completeObject() -> O {
return O.cs_fromRaw(object: self.rawObject)
@@ -42,6 +45,9 @@ public struct PartialObject<O: CoreStoreObject> {
// MARK: Value.Required accessors/mutators
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
@@ -49,6 +55,9 @@ public struct PartialObject<O: CoreStoreObject> {
)!
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setValue(
@@ -57,6 +66,11 @@ public struct PartialObject<O: CoreStoreObject> {
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
@@ -64,6 +78,11 @@ public struct PartialObject<O: CoreStoreObject> {
)!
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
@@ -75,12 +94,18 @@ public struct PartialObject<O: CoreStoreObject> {
// MARK: Value.Optional utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.value(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setValue(
@@ -89,12 +114,22 @@ public struct PartialObject<O: CoreStoreObject> {
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(
@@ -106,11 +141,17 @@ public struct PartialObject<O: CoreStoreObject> {
// MARK: Transformable.Required utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.value(forKey: property(O.meta).keyPath)! as! V
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setValue(
@@ -119,11 +160,21 @@ public struct PartialObject<O: CoreStoreObject> {
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath)! as! V
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
@@ -135,11 +186,17 @@ public struct PartialObject<O: CoreStoreObject> {
// MARK: Transformable.Optional utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.value(forKey: property(O.meta).keyPath) as! V?
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setValue(
@@ -148,11 +205,21 @@ public struct PartialObject<O: CoreStoreObject> {
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V?
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(

View File

@@ -226,8 +226,6 @@ public final class SQLiteStore: LocalStorage {
*/
public func cs_eraseStorageAndWait(metadata: [String: Any], soureModelHint: NSManagedObjectModel?) throws {
// TODO: check if attached to persistent store
func deleteFiles(storeURL: URL, extraFiles: [String] = []) throws {
let fileManager = FileManager.default

View File

@@ -35,9 +35,9 @@ public extension DynamicObject where Self: CoreStoreObject {
The containing type for transformable properties. `Transformable` properties support types that conforms to `NSCoding & NSCopying`.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Transformable` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
@@ -52,7 +52,7 @@ public extension DynamicObject where Self: CoreStoreObject {
The containing type for transformable properties. Use the `DynamicObject.Transformable` typealias instead for shorter syntax.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -66,7 +66,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
The containing type for transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -79,7 +79,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
Initializes the metadata for the property.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let color = Transformable.Required<UIColor>(
"color",
initial: UIColor.clear,
@@ -292,7 +292,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
The containing type for optional transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -305,7 +305,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
Initializes the metadata for the property.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let color = Transformable.Optional<UIColor>(
"color",
isTransient: true,

View File

@@ -35,7 +35,7 @@ public extension DynamicObject where Self: CoreStoreObject {
The containing type for value propertiess. `Value` properties support any type that conforms to `ImportableAttributeType`.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -52,7 +52,7 @@ public extension DynamicObject where Self: CoreStoreObject {
The containing type for value properties. Use the `DynamicObject.Value` typealias instead for shorter syntax.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -66,7 +66,7 @@ public enum ValueContainer<O: CoreStoreObject> {
The containing type for required value properties. Any type that conforms to `ImportableAttributeType` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
@@ -80,9 +80,10 @@ public enum ValueContainer<O: CoreStoreObject> {
```
class Person: CoreStoreObject {
let title = Value.Required<String>("title", initial: "Mr.")
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let displayName = Value.Required<String>(
"displayName",
initial: "",
isTransient: true,
customGetter: Person.getName(_:)
)
@@ -289,7 +290,7 @@ public enum ValueContainer<O: CoreStoreObject> {
The containing type for optional value properties. Any type that conforms to `ImportableAttributeType` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}

View File

@@ -32,12 +32,12 @@ import Foundation
The `VersionLock` contains the version hashes for entities. This is then passed to the `CoreStoreSchema`, which contains all entities for the store. An assertion will be raised if any `Entity` doesn't match the version hash.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species")
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let name = Value.Required<String>("name")
let name = Value.Required<String>("name", initial: "")
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
}