diff --git a/README.md b/README.md index 7284f6e..38c4ab5 100644 --- a/README.md +++ b/README.md @@ -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("species") + let species = Value.Required("species", initial: "") } class Dog: Animal { @@ -1684,14 +1684,14 @@ class Dog: Animal { } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pets = Relationship.ToManyUnordered("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("name") + private let _name = Value.Required("name", initial: "") // ... } ``` diff --git a/Sources/CoreStoreLogger.swift b/Sources/CoreStoreLogger.swift index 1f6832f..57e1714 100644 --- a/Sources/CoreStoreLogger.swift +++ b/Sources/CoreStoreLogger.swift @@ -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)) diff --git a/Sources/CoreStoreObject.swift b/Sources/CoreStoreObject.swift index 2ec6c4c..ec2aa7b 100644 --- a/Sources/CoreStoreObject.swift +++ b/Sources/CoreStoreObject.swift @@ -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`, `Value.Optional` for values, or `Relationship.ToOne`, `Relationship.ToManyOrdered`, `Relationship.ToManyUnordered` for relationships. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let master = Relationship.ToOne("master") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pet = Relationship.ToOne("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 { CoreStore.assert( diff --git a/Sources/CoreStoreSchema.swift b/Sources/CoreStoreSchema.swift index c685d6b..82a0713 100644 --- a/Sources/CoreStoreSchema.swift +++ b/Sources/CoreStoreSchema.swift @@ -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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let master = Relationship.ToOne("master") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pet = Relationship.ToOne("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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let master = Relationship.ToOne("master") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pet = Relationship.ToOne("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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") } CoreStore.defaultStack = DataStack( diff --git a/Sources/DataStack.swift b/Sources/DataStack.swift index 726ffb6..7187306 100644 --- a/Sources/DataStack.swift +++ b/Sources/DataStack.swift @@ -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]() diff --git a/Sources/DefaultLogger.swift b/Sources/DefaultLogger.swift index 380fdf5..fcfc486 100644 --- a/Sources/DefaultLogger.swift +++ b/Sources/DefaultLogger.swift @@ -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`. */ diff --git a/Sources/Entity.swift b/Sources/Entity.swift index bb6fc26..33da35f 100644 --- a/Sources/Entity.swift +++ b/Sources/Entity.swift @@ -34,13 +34,13 @@ import ObjectiveC The `Entity` contains `NSEntityDescription` metadata for `CoreStoreObject` subclasses. Pass the `Entity` instances to `CoreStoreSchema` initializer. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let master = Relationship.ToOne("master") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pet = Relationship.ToOne("pet", inverse: { $0.master }) } diff --git a/Sources/ICloudStore.swift b/Sources/ICloudStore.swift index ba96b6b..edf42f5 100644 --- a/Sources/ICloudStore.swift +++ b/Sources/ICloudStore.swift @@ -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 { diff --git a/Sources/NSManagedObject+Logging.swift b/Sources/NSManagedObject+Logging.swift index 2db850f..47847dd 100644 --- a/Sources/NSManagedObject+Logging.swift +++ b/Sources/NSManagedObject+Logging.swift @@ -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) { -// -// 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 -// } -// } } diff --git a/Sources/PartialObject.swift b/Sources/PartialObject.swift index 54c1742..eaabcca 100644 --- a/Sources/PartialObject.swift +++ b/Sources/PartialObject.swift @@ -34,6 +34,9 @@ import Foundation */ public struct PartialObject { + /** + 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 { // MARK: Value.Required accessors/mutators + /** + Returns the value for the property identified by a given key. + */ public func value(for property: (O) -> ValueContainer.Required) -> V { return V.cs_fromQueryableNativeType( @@ -49,6 +55,9 @@ public struct PartialObject { )! } + /** + Sets the property of the receiver specified by a given key to a given value. + */ public func setValue(_ value: V, for property: (O) -> ValueContainer.Required) { self.rawObject.setValue( @@ -57,6 +66,11 @@ public struct PartialObject { ) } + /** + Returns the value for the specified property from the managed object’s 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 receiver’s private storage. + */ public func primitiveValue(for property: (O) -> ValueContainer.Required) -> V { return V.cs_fromQueryableNativeType( @@ -64,6 +78,11 @@ public struct PartialObject { )! } + /** + Sets in the object's private internal storage the value of a given property. + + Sets in the receiver’s private internal storage the value of the property specified by key to value. + */ public func setPrimitiveValue(_ value: V, for property: (O) -> ValueContainer.Required) { self.rawObject.setPrimitiveValue( @@ -75,12 +94,18 @@ public struct PartialObject { // MARK: Value.Optional utilities + /** + Returns the value for the property identified by a given key. + */ public func value(for property: (O) -> ValueContainer.Optional) -> 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(_ value: V?, for property: (O) -> ValueContainer.Optional) { self.rawObject.setValue( @@ -89,12 +114,22 @@ public struct PartialObject { ) } + /** + Returns the value for the specified property from the managed object’s 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 receiver’s private storage. + */ public func primitiveValue(for property: (O) -> ValueContainer.Optional) -> 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 receiver’s private internal storage the value of the property specified by key to value. + */ public func setPrimitiveValue(_ value: V?, for property: (O) -> ValueContainer.Optional) { self.rawObject.setPrimitiveValue( @@ -106,11 +141,17 @@ public struct PartialObject { // MARK: Transformable.Required utilities + /** + Returns the value for the property identified by a given key. + */ public func value(for property: (O) -> TransformableContainer.Required) -> 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(_ value: V, for property: (O) -> TransformableContainer.Required) { self.rawObject.setValue( @@ -119,11 +160,21 @@ public struct PartialObject { ) } + /** + Returns the value for the specified property from the managed object’s 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 receiver’s private storage. + */ public func primitiveValue(for property: (O) -> TransformableContainer.Required) -> 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 receiver’s private internal storage the value of the property specified by key to value. + */ public func setPrimitiveValue(_ value: V, for property: (O) -> TransformableContainer.Required) { self.rawObject.setPrimitiveValue( @@ -135,11 +186,17 @@ public struct PartialObject { // MARK: Transformable.Optional utilities + /** + Returns the value for the property identified by a given key. + */ public func value(for property: (O) -> TransformableContainer.Optional) -> 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(_ value: V?, for property: (O) -> TransformableContainer.Optional) { self.rawObject.setValue( @@ -148,11 +205,21 @@ public struct PartialObject { ) } + /** + Returns the value for the specified property from the managed object’s 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 receiver’s private storage. + */ public func primitiveValue(for property: (O) -> TransformableContainer.Optional) -> 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 receiver’s private internal storage the value of the property specified by key to value. + */ public func setPrimitiveValue(_ value: V?, for property: (O) -> TransformableContainer.Optional) { self.rawObject.setPrimitiveValue( diff --git a/Sources/SQLiteStore.swift b/Sources/SQLiteStore.swift index b50c29f..be95dfb 100644 --- a/Sources/SQLiteStore.swift +++ b/Sources/SQLiteStore.swift @@ -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 diff --git a/Sources/Transformable.swift b/Sources/Transformable.swift index 167cc78..a771331 100644 --- a/Sources/Transformable.swift +++ b/Sources/Transformable.swift @@ -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("species") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("color") + let species = Value.Required("species", initial: "") + let nickname = Value.Optional("nickname") + let color = Transformable.Optional("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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } @@ -66,7 +66,7 @@ public enum TransformableContainer { The containing type for transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } @@ -79,7 +79,7 @@ public enum TransformableContainer { Initializes the metadata for the property. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let color = Transformable.Required( "color", initial: UIColor.clear, @@ -292,7 +292,7 @@ public enum TransformableContainer { The containing type for optional transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } @@ -305,7 +305,7 @@ public enum TransformableContainer { Initializes the metadata for the property. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let color = Transformable.Optional( "color", isTransient: true, diff --git a/Sources/Value.swift b/Sources/Value.swift index 223ef45..e3d725b 100644 --- a/Sources/Value.swift +++ b/Sources/Value.swift @@ -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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } @@ -66,7 +66,7 @@ public enum ValueContainer { The containing type for required value properties. Any type that conforms to `ImportableAttributeType` are supported. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } @@ -80,9 +80,10 @@ public enum ValueContainer { ``` class Person: CoreStoreObject { let title = Value.Required("title", initial: "Mr.") - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let displayName = Value.Required( "displayName", + initial: "", isTransient: true, customGetter: Person.getName(_:) ) @@ -289,7 +290,7 @@ public enum ValueContainer { The containing type for optional value properties. Any type that conforms to `ImportableAttributeType` are supported. ``` class Animal: CoreStoreObject { - let species = Value.Required("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let color = Transformable.Optional("color") } diff --git a/Sources/VersionLock.swift b/Sources/VersionLock.swift index 38fff5c..4316004 100644 --- a/Sources/VersionLock.swift +++ b/Sources/VersionLock.swift @@ -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("species") + let species = Value.Required("species", initial: "") let nickname = Value.Optional("nickname") let master = Relationship.ToOne("master") } class Person: CoreStoreObject { - let name = Value.Required("name") + let name = Value.Required("name", initial: "") let pet = Relationship.ToOne("pet", inverse: { $0.master }) }