From 63a43a6487cbf6d4b05c6312b7c5bf7be57ee3e5 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Thu, 10 Sep 2015 07:21:53 +0900 Subject: [PATCH] WIP: documentation --- CoreStore.xcodeproj/project.pbxproj | 8 ++ .../BaseDataTransaction+Importing.swift | 86 ++++------- .../Importing Data/ImportableObject.swift | 84 +++++++++++ .../ImportableUniqueObject.swift | 136 ++++++++++++++++++ .../NSManagedObjectContext+Transaction.swift | 18 +-- CoreStore/Observing/ListMonitor.swift | 1 + CoreStore/Observing/ListObserver.swift | 9 ++ CoreStore/Observing/ObjectObserver.swift | 2 + CoreStore/Saving and Processing/Into.swift | 4 +- 9 files changed, 279 insertions(+), 69 deletions(-) create mode 100644 CoreStore/Importing Data/ImportableObject.swift create mode 100644 CoreStore/Importing Data/ImportableUniqueObject.swift diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index b161fae..8086350 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -66,6 +66,8 @@ B5E84F381AFF85470064E85B /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F341AFF85470064E85B /* NSManagedObject+Transaction.swift */; }; B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; }; B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; }; + B5F1DA8D1B9AA97D007C5CBB /* ImportableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */; settings = {ASSET_TAGS = (); }; }; + B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */; settings = {ASSET_TAGS = (); }; }; B5FAD6A91B50A4B400714891 /* NSProgress+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6A81B50A4B300714891 /* NSProgress+Convenience.swift */; }; B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AB1B51285300714891 /* MigrationManager.swift */; }; B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AD1B518DCB00714891 /* CoreStore+Migration.swift */; }; @@ -169,6 +171,8 @@ B5E84F341AFF85470064E85B /* NSManagedObject+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Transaction.swift"; sourceTree = ""; }; B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Querying.swift"; sourceTree = ""; }; B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClauseTypes.swift; sourceTree = ""; }; + B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportableObject.swift; sourceTree = ""; }; + B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportableUniqueObject.swift; sourceTree = ""; }; B5FAD6A81B50A4B300714891 /* NSProgress+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSProgress+Convenience.swift"; sourceTree = ""; }; B5FAD6AB1B51285300714891 /* MigrationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationManager.swift; sourceTree = ""; }; B5FAD6AD1B518DCB00714891 /* CoreStore+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Migration.swift"; sourceTree = ""; }; @@ -317,6 +321,8 @@ B5E834B61B7630BD001D3D50 /* Importing Data */ = { isa = PBXGroup; children = ( + B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */, + B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */, B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */, ); path = "Importing Data"; @@ -566,6 +572,7 @@ buildActionMask = 2147483647; files = ( B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */, + B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */, B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */, B5D1E22C19FA9FBC003B2874 /* NSError+CoreStore.swift in Sources */, B5E84F131AFF847B0064E85B /* Where.swift in Sources */, @@ -584,6 +591,7 @@ B5E84EE11AFF84500064E85B /* PersistentStoreResult.swift in Sources */, B5E84F251AFF84860064E85B /* ObjectObserver.swift in Sources */, B5E84F2F1AFF849C0064E85B /* NotificationObserver.swift in Sources */, + B5F1DA8D1B9AA97D007C5CBB /* ImportableObject.swift in Sources */, B5E84F381AFF85470064E85B /* NSManagedObject+Transaction.swift in Sources */, B56965241B356B820075EE4A /* MigrationResult.swift in Sources */, 2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */, diff --git a/CoreStore/Importing Data/BaseDataTransaction+Importing.swift b/CoreStore/Importing Data/BaseDataTransaction+Importing.swift index 629900a..bca3f59 100644 --- a/CoreStore/Importing Data/BaseDataTransaction+Importing.swift +++ b/CoreStore/Importing Data/BaseDataTransaction+Importing.swift @@ -27,57 +27,20 @@ import Foundation import CoreData -public protocol ImportableObject: class { - - typealias ImportSource - - static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool - - func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -} - -public extension ImportableObject { - - static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool { - - return true - } -} - - -public protocol ImportableUniqueObject: ImportableObject { - - typealias UniqueIDType: NSObject - - static var uniqueIDKeyPath: String { get } - - var uniqueIDValue: UniqueIDType { get set } - - static func uniqueIDFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? - - static func shouldUpdateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool - - func updateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -} - - -public extension ImportableUniqueObject { - - static func shouldUpdateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool { - - return true - } - - func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws { - - try self.updateFromImportSource(source, inTransaction: transaction) - } -} - +// MARK: - BaseDataTransaction public extension BaseDataTransaction { - func importObject( + // MARK: Public + + /** + Creates an `ImportableObject` by importing from the specified import source. + + - parameter into: an `Into` clause specifying the entity type + - parameter source: the object to import values from + - returns: the created `ImportableObject` instance + */ + public func importObject( into: Into, source: T.ImportSource) throws -> T? { @@ -99,7 +62,13 @@ public extension BaseDataTransaction { } } - func importObjects( + /** + Creates multiple `ImportableObject`s by importing from the specified array of import sources. + + - parameter into: an `Into` clause specifying the entity type + - parameter sourceArray: the array of objects to import values from + */ + public func importObjects( into: Into, sourceArray: [T.ImportSource]) throws { @@ -126,10 +95,17 @@ public extension BaseDataTransaction { } } - func importObjects( + /** + Creates multiple `ImportableObject`s by importing from the specified array of import sources. + + - parameter into: an `Into` clause specifying the entity type + - parameter sourceArray: the array of objects to import values from + - parameter postProcess: a closure that exposes the array of created objects + */ + public func importObjects( into: Into, sourceArray: [T.ImportSource], - postProcess: (sorted: [T]) -> Void) throws { + @noescape postProcess: (sorted: [T]) -> Void) throws { CoreStore.assert( self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(), @@ -158,7 +134,7 @@ public extension BaseDataTransaction { } } - func importUniqueObject( + public func importUniqueObject( into: Into, source: T.ImportSource) throws -> T? { @@ -195,7 +171,7 @@ public extension BaseDataTransaction { } } - func importUniqueObjects( + public func importUniqueObjects( into: Into, sourceArray: [T.ImportSource], preProcess: ((mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource])? = nil) throws { @@ -262,11 +238,11 @@ public extension BaseDataTransaction { } } - func importUniqueObjects( + public func importUniqueObjects( into: Into, sourceArray: [T.ImportSource], preProcess: ((mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource])? = nil, - postProcess: (sorted: [T]) -> Void) throws { + @noescape postProcess: (sorted: [T]) -> Void) throws { CoreStore.assert( self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(), diff --git a/CoreStore/Importing Data/ImportableObject.swift b/CoreStore/Importing Data/ImportableObject.swift new file mode 100644 index 0000000..85dd32f --- /dev/null +++ b/CoreStore/Importing Data/ImportableObject.swift @@ -0,0 +1,84 @@ +// +// ImportableObject.swift +// CoreStore +// +// Copyright (c) 2015 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - ImportableObject + +/** +`NSManagedObject` subclasses that conform to the `ImportableObject` protocol can be imported from a specified `ImportSource`. This allows transactions to create and insert instances this way: + + class MyPersonEntity: NSManagedObject, ImportableObject { + typealias ImportSource = NSDictionary + // ... + } + + CoreStore.beginAsynchronous { (transaction) -> Void in + let json: NSDictionary = // ... + let person = try! transaction.importObject( + Into(MyPersonEntity), + source: json + ) + // ... + transaction.commit() + } +*/ +public protocol ImportableObject: class { + + /** + The data type for the import source. This is most commonly an `NSDictionary` or another external source such as an `NSUserDefaults`. + */ + typealias ImportSource + + /** + Return `true` if an object should be created from `source`. Return `false` to ignore and skip `source`. The default implementation returns `true`. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + - returns: `true` if an object should be created from `source`. Return `false` to ignore. + */ + static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool + + /** + Implements the actual importing of data from `source`. Implementers should pull values from `source` and assign them to the receiver's attributes. Note that throwing from this method will cause subsequent imports that are part of the same `importObjects(:sourceArray:)` call to be cancelled. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + */ + func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws +} + + +// MARK: - ImportableObject (Default Implementations) + +public extension ImportableObject { + + static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool { + + return true + } +} diff --git a/CoreStore/Importing Data/ImportableUniqueObject.swift b/CoreStore/Importing Data/ImportableUniqueObject.swift new file mode 100644 index 0000000..65dab73 --- /dev/null +++ b/CoreStore/Importing Data/ImportableUniqueObject.swift @@ -0,0 +1,136 @@ +// +// ImportableUniqueObject.swift +// CoreStore +// +// Copyright (c) 2015 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation +import CoreData + + +// MARK: - ImportableUniqueObject + +/** +`NSManagedObject` subclasses that conform to the `ImportableUniqueObject` protocol can be imported from a specified `ImportSource`. This allows transactions to either update existing objects or create new instances this way: + + class MyPersonEntity: NSManagedObject, ImportableUniqueObject { + typealias ImportSource = NSDictionary + typealias UniqueIDType = NSString + // ... + } + + CoreStore.beginAsynchronous { (transaction) -> Void in + let json: NSDictionary = // ... + let person = try! transaction.importUniqueObject( + Into(MyPersonEntity), + source: json + ) + // ... + transaction.commit() + } +*/ +public protocol ImportableUniqueObject: ImportableObject { + + /** + The data type for the import source. This is most commonly an `NSDictionary` or another external source such as an `NSUserDefaults`. + */ + typealias ImportSource + + /** + The data type for the entity's unique ID attribute + */ + typealias UniqueIDType: NSObject + + /** + The keyPath to the entity's unique ID attribute + */ + static var uniqueIDKeyPath: String { get } + + /** + The object's unique ID value + */ + var uniqueIDValue: UniqueIDType { get set } + + /** + Return `true` if an object should be created from `source`. Return `false` to ignore and skip `source`. The default implementation returns the value returned by the `shouldUpdateFromImportSource(:inTransaction:)` implementation. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + - returns: `true` if an object should be created from `source`. Return `false` to ignore. + */ + static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool + + /** + Return `true` if an object should be updated from `source`. Return `false` to ignore and skip `source`. The default implementation returns `true`. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + - returns: `true` if an object should be updated from `source`. Return `false` to ignore. + */ + static func shouldUpdateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool + + /** + Return the unique ID as extracted from `source`. This method is called before `shouldInsertFromImportSource(...)` or `shouldUpdateFromImportSource(...)`. Return `nil` to skip importing from `source`. Note that throwing from this method will cause subsequent imports that are part of the same `importUniqueObjects(:sourceArray:)` call to be cancelled. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + - returns: the unique ID as extracted from `source`, or `nil` to skip importing from `source`. + */ + static func uniqueIDFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? + + /** + Implements the actual importing of data from `source`. This method is called just after the object is created and assigned its unique ID as returned from `uniqueIDFromImportSource(...)`. Implementers should pull values from `source` and assign them to the receiver's attributes. Note that throwing from this method will cause subsequent imports that are part of the same `importUniqueObjects(:sourceArray:)` call to be cancelled. The default implementation simply calls `updateFromImportSource(...)`. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + */ + func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws + + /** + Implements the actual importing of data from `source`. This method is called just after the existing object is fetched using its unique ID. Implementers should pull values from `source` and assign them to the receiver's attributes. Note that throwing from this method will cause subsequent imports that are part of the same `importUniqueObjects(:sourceArray:)` call to be cancelled. + + - parameter source: the object to import from + - parameter transaction: the transaction that invoked the import. Use the transaction to fetch or create related objects if needed. + */ + func updateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws +} + + +// MARK: - ImportableUniqueObject (Default Implementations) + +public extension ImportableUniqueObject { + + static func shouldInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool { + + return self.shouldUpdateFromImportSource(source, inTransaction: transaction) + } + + static func shouldUpdateFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool { + + return true + } + + func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws { + + try self.updateFromImportSource(source, inTransaction: transaction) + } +} diff --git a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift index 2a63722..17b5676 100644 --- a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift +++ b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift @@ -111,18 +111,15 @@ internal extension NSManagedObjectContext { return result } - internal func saveAsynchronouslyWithCompletion(completion: ((result: SaveResult) -> Void)?) { + internal func saveAsynchronouslyWithCompletion(completion: ((result: SaveResult) -> Void) = { _ in }) { self.performBlock { () -> Void in guard self.hasChanges else { - if let completion = completion { + GCDQueue.Main.async { - GCDQueue.Main.async { - - completion(result: SaveResult(hasChanges: false)) - } + completion(result: SaveResult(hasChanges: false)) } return } @@ -138,12 +135,9 @@ internal extension NSManagedObjectContext { saveError, "Failed to save \(typeName(NSManagedObjectContext))." ) - if let completion = completion { + GCDQueue.Main.async { - GCDQueue.Main.async { - - completion(result: SaveResult(saveError)) - } + completion(result: SaveResult(saveError)) } return } @@ -152,7 +146,7 @@ internal extension NSManagedObjectContext { parentContext.saveAsynchronouslyWithCompletion(completion) } - else if let completion = completion { + else { GCDQueue.Main.async { diff --git a/CoreStore/Observing/ListMonitor.swift b/CoreStore/Observing/ListMonitor.swift index b22c8df..d0ed98f 100644 --- a/CoreStore/Observing/ListMonitor.swift +++ b/CoreStore/Observing/ListMonitor.swift @@ -990,6 +990,7 @@ extension ListMonitor: FetchedResultsControllerHandler { ) case .Move: + CoreStore.log(.Notice, message: "\(indexPath!) - \(newIndexPath!)") NSNotificationCenter.defaultCenter().postNotificationName( ListMonitorDidMoveObjectNotification, object: self, diff --git a/CoreStore/Observing/ListObserver.swift b/CoreStore/Observing/ListObserver.swift index 6ce085c..78aeb36 100644 --- a/CoreStore/Observing/ListObserver.swift +++ b/CoreStore/Observing/ListObserver.swift @@ -74,6 +74,9 @@ public protocol ListObserver: class { func listMonitorDidRefetch(monitor: ListMonitor) } + +// MARK: - ListObserver (Default Implementations) + public extension ListObserver { /** @@ -149,6 +152,9 @@ public protocol ListObjectObserver: ListObserver { func listMonitor(monitor: ListMonitor, didMoveObject object: ListEntityType, fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) } + +// MARK: - ListObjectObserver (Default Implementations) + public extension ListObjectObserver { /** @@ -206,6 +212,9 @@ public protocol ListSectionObserver: ListObjectObserver { func listMonitor(monitor: ListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) } + +// MARK: - ListSectionObserver (Default Implementations) + public extension ListSectionObserver { /** diff --git a/CoreStore/Observing/ObjectObserver.swift b/CoreStore/Observing/ObjectObserver.swift index 1eebc09..f00b5fa 100644 --- a/CoreStore/Observing/ObjectObserver.swift +++ b/CoreStore/Observing/ObjectObserver.swift @@ -69,6 +69,8 @@ public protocol ObjectObserver: class { } +// MARK: - ObjectObserver (Default Implementations) + public extension ObjectObserver { /** diff --git a/CoreStore/Saving and Processing/Into.swift b/CoreStore/Saving and Processing/Into.swift index 08face6..f01c331 100644 --- a/CoreStore/Saving and Processing/Into.swift +++ b/CoreStore/Saving and Processing/Into.swift @@ -36,7 +36,7 @@ let person = transaction.create(Into(MyPersonEntity)) For cases where multiple `NSPersistentStore`s contain the same entity, the destination configuration's name needs to be specified as well: -let person = transaction.create(Into("Configuration1")) + let person = transaction.create(Into("Configuration1")) This helps the `NSManagedObjectContext` to determine which */ @@ -48,7 +48,7 @@ public struct Into { Initializes an `Into` clause. Sample Usage: - let person = transaction.create(Into()) + let person = transaction.create(Into()) */ public init(){