# ImportableUniqueObject

    public protocol ImportableUniqueObject : ImportableObject, Hashable

`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 Person: NSManagedObject, ImportableObject {
        typealias ImportSource = NSDictionary
        typealias UniqueIDType = NSString
        // ...
    }

    dataStack.perform(
        asynchronous: { (transaction) -> Void in
            let json: NSDictionary = // ...
            let person = try transaction.importUniqueObject(
                Into<Person>(),
                source: json
            )
            // ...
        },
        completion: { (result) in
            // ...
        }
    )

- `UniqueIDType`

  The data type for the entity’s unique ID attribute

  #### Declaration

  Swift

      associatedtype UniqueIDType : ImportableAttributeType

- `uniqueIDKeyPath`

  The keyPath to the entity’s unique ID attribute

  #### Declaration

  Swift

      static var uniqueIDKeyPath: String { get }

- `uniqueIDValue`

  The object’s unique ID value. The default implementation returns the value of the attribute pertained to by `uniqueIDKeyPath`

  Important

  It is the developer’s responsibility to ensure that the attribute value pertained by `uniqueIDKeyPath` is not `nil` during the call to `uniqueIDValue`.

  #### Declaration

  Swift

      var uniqueIDValue: UniqueIDType { get set }

- `shouldInsert(from:in:)`

  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 `shouldUpdate(from:in:)` implementation.

  #### Declaration

  Swift

      static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool

  #### Parameters

  `source` | the object to import from
  `transaction` | the transaction that invoked the import. Use the transaction to fetch or create related objects if needed.

  #### Return Value

  `true` if an object should be created from `source`. Return `false` to ignore.

- `shouldUpdate(from:in:)` Default implementation

  Return `true` if an object should be updated from `source`. Return `false` to ignore and skip `source`. The default implementation returns `true`.

  #### Default Implementation

  #### Declaration

  Swift

      static func shouldUpdate(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool

  #### Parameters

  `source` | the object to import from
  `transaction` | the transaction that invoked the import. Use the transaction to fetch or create related objects if needed.

  #### Return Value

  `true` if an object should be updated from `source`. Return `false` to ignore.

- `uniqueID(from:in:)`

  Return the unique ID as extracted from `source`. This method is called before `shouldInsert(from:in:)` or `shouldUpdate(from:in:)`. 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.

  #### Declaration

  Swift

      static func uniqueID(from source: ImportSource, in transaction: BaseDataTransaction) throws -> UniqueIDType?

  #### Parameters

  `source` | the object to import from
  `transaction` | the transaction that invoked the import. Use the transaction to fetch or create related objects if needed.

  #### Return Value

  the unique ID as extracted from `source`, or `nil` to skip importing from `source`.

- `didInsert(from:in:)`

  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 `uniqueID(from:in:)`. 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 `update(from:in:)`.

  #### Declaration

  Swift

      func didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws

  #### Parameters

  `source` | the object to import from
  `transaction` | the transaction that invoked the import. Use the transaction to fetch or create related objects if needed.

- `update(from:in:)`

  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.

  #### Declaration

  Swift

      func update(from source: ImportSource, in transaction: BaseDataTransaction) throws

  #### Parameters

  `source` | the object to import from
  `transaction` | the transaction that invoked the import. Use the transaction to fetch or create related objects if needed.