diff --git a/Framework/CoreDataDandy.xcodeproj/project.pbxproj b/Framework/CoreDataDandy.xcodeproj/project.pbxproj
index d18f5f8..6fc41d2 100644
--- a/Framework/CoreDataDandy.xcodeproj/project.pbxproj
+++ b/Framework/CoreDataDandy.xcodeproj/project.pbxproj
@@ -178,6 +178,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = 985CD4CE1C617024005EB9E2;
@@ -267,6 +268,7 @@
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -307,6 +309,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
+ SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/Framework/CoreDataDandy.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Framework/CoreDataDandy.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Framework/CoreDataDandy.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Source/Core/CoreDataDandy.swift b/Source/Core/CoreDataDandy.swift
index ca6fa2e..57e7b9e 100644
--- a/Source/Core/CoreDataDandy.swift
+++ b/Source/Core/CoreDataDandy.swift
@@ -64,9 +64,9 @@ public class CoreDataDandy {
coordinator.resetManageObjectContext()
do {
- try NSFileManager.defaultManager().removeItemAtURL(PersistentStackCoordinator.persistentStoreURL)
+ try FileManager.default.removeItem(at: PersistentStackCoordinator.persistentStoreURL)
} catch {
- log(message("Failed to delete persistent store"))
+ debugPrint("Failed to delete persistent store")
}
coordinator.resetPersistentStore()
@@ -81,19 +81,19 @@ public class CoreDataDandy {
/// - parameter entityName: The name of the requested entity
///
/// - returns: A managed object if one could be inserted for the specified Entity.
- public func insert(entityName: String) -> NSManagedObject? {
- if let entityDescription = NSEntityDescription.forEntity(entityName) {
+ public func insert(_ entityName: String) -> NSManagedObject? {
+ if let entityDescription = NSEntityDescription.forEntity(name: entityName) {
// Ignore this insert if the entity is a singleton and a pre-existing insert exists.
if entityDescription.primaryKey == SINGLETON {
- if let singleton = singletonEntity(entityName) {
+ if let singleton = singletonEntity(entityName: entityName) {
return singleton
}
}
// Otherwise, insert a new managed object
- return NSManagedObject(entity: entityDescription, insertIntoManagedObjectContext: coordinator.mainContext)
+ return NSManagedObject(entity: entityDescription, insertInto: coordinator.mainContext)
}
else {
- log(message("NSEntityDescriptionNotFound for entity named " + entityName + ". No object will be returned"))
+ debugPrint("NSEntityDescriptionNotFound for entity named " + entityName + ". No object will be returned")
return nil
}
}
@@ -111,24 +111,24 @@ public class CoreDataDandy {
/// - parameter json: A dictionary to map into the returned object's attributes and relationships
///
/// - returns: A managed object if one could be created.
- public func upsert(entityName: String, from json: [String: AnyObject]) -> NSManagedObject? {
- guard let entityDescription = NSEntityDescription.forEntity(entityName) else {
- log(message("Could not retrieve NSEntityDescription or for entity named \(entityName)"))
+ public func upsert(_ entityName: String, from json: [String: AnyObject]) -> NSManagedObject? {
+ guard let entityDescription = NSEntityDescription.forEntity(name: entityName) else {
+ debugPrint("Could not retrieve NSEntityDescription or for entity named \(entityName)")
return nil
}
let isUniqueEntity = entityDescription.primaryKey != nil
if isUniqueEntity {
- if let primaryKeyValue = entityDescription.primaryKeyValueFromJSON(json) {
- return upsertUnique(entityDescription, primaryKeyValue: primaryKeyValue, from: json)
+ if let primaryKeyValue = entityDescription.primaryKeyValueFromJSON(json: json) {
+ return upsertUnique(entityDescription: entityDescription, primaryKeyValue: primaryKeyValue, from: json)
} else {
- log(message("Could not retrieve primary key from json \(json)."))
+ debugPrint("Could not retrieve primary key from json \(json).")
return nil
}
}
if let managedObject = insert(entityName) {
- return ObjectFactory.build(managedObject, from: json)
+ return ObjectFactory.build(object: managedObject, from: json)
}
return nil
@@ -141,7 +141,7 @@ public class CoreDataDandy {
/// - parameter json: An array to map into the returned objects' attributes and relationships
///
/// - returns: An array of managed objects if one could be created.
- public func batchUpsert(entityName: String, from json: [[String:AnyObject]]) -> [NSManagedObject]? {
+ public func batchUpsert(_ entityName: String, from json: [[String:AnyObject]]) -> [NSManagedObject]? {
var managedObjects = [NSManagedObject]()
for object in json {
if let managedObject = upsert(entityName, from: object) {
@@ -160,14 +160,18 @@ public class CoreDataDandy {
///
/// - parameter entityName: The name of the requested entity.
/// - parameter primaryKeyValue: The value of the unique object's primary key
- public func insertUnique(entityName: String, primaryKeyValue: AnyObject) -> NSManagedObject? {
+ public func insertUnique(_ entityName: String, primaryKeyValue: AnyObject) -> NSManagedObject? {
// Return an object if one exists. Otherwise, attempt to insert one.
- if let object = fetchUnique(entityName, primaryKeyValue: primaryKeyValue, emitResultCountWarnings: false) {
+ if let object = fetchUnique(entityName: entityName,
+ primaryKeyValue: primaryKeyValue,
+ emitResultCountWarnings: false) {
return object
- } else if let entityDescription = NSEntityDescription.forEntity(entityName),
+ } else if let entityDescription = NSEntityDescription.forEntity(name: entityName),
let primaryKey = entityDescription.primaryKey {
let object = insert(entityName)
- let convertedPrimaryKeyValue: AnyObject? = CoreDataValueConverter.convert(primaryKeyValue, forEntity: entityDescription, property: primaryKey)
+ let convertedPrimaryKeyValue: AnyObject? = CoreDataValueConverter.convert(value: primaryKeyValue,
+ forEntity: entityDescription,
+ property: primaryKey)
object?.setValue(convertedPrimaryKeyValue, forKey: primaryKey)
return object
}
@@ -184,10 +188,10 @@ public class CoreDataDandy {
/// - returns: A managed object if one could be created.
private func upsertUnique(entityDescription: NSEntityDescription, primaryKeyValue: AnyObject, from json: [String: AnyObject]) -> NSManagedObject? {
if let object = insertUnique(entityDescription.name ?? "", primaryKeyValue: primaryKeyValue) {
- ObjectFactory.build(object, from: json)
+ ObjectFactory.build(object: object, from: json)
return object
} else {
- log(message("Could not upsert managed object for entity description \(entityDescription), primary key \(primaryKeyValue), json \(json)."))
+ debugPrint("Could not upsert managed object for entity description \(entityDescription), primary key \(primaryKeyValue), json \(json).")
return nil
}
}
@@ -202,8 +206,8 @@ public class CoreDataDandy {
/// - parameter primaryKeyValue: The value of unique object's primary key.
///
/// - returns: If the fetch was successful, the fetched NSManagedObject.
- public func fetchUnique(entityName: String, primaryKeyValue: AnyObject) -> NSManagedObject? {
- return fetchUnique(entityName, primaryKeyValue: primaryKeyValue, emitResultCountWarnings: true)
+ public func fetchUnique(_ entityName: String, primaryKeyValue: AnyObject) -> NSManagedObject? {
+ return fetchUnique(entityName: entityName, primaryKeyValue: primaryKeyValue, emitResultCountWarnings: true)
}
/// A private version of `fetchUnique(_:_:) used for toggling warnings that would be of no interest
@@ -216,10 +220,10 @@ public class CoreDataDandy {
///
/// - returns: If the fetch was successful, the fetched NSManagedObject.
private func fetchUnique(entityName: String, primaryKeyValue: AnyObject, emitResultCountWarnings: Bool) -> NSManagedObject? {
- let entityDescription = NSEntityDescription.forEntity(entityName)
+ let entityDescription = NSEntityDescription.forEntity(name: entityName)
if let entityDescription = entityDescription {
if entityDescription.primaryKey == SINGLETON {
- if let singleton = singletonEntity(entityName) {
+ if let singleton = singletonEntity(entityName: entityName) {
return singleton
}
}
@@ -229,25 +233,27 @@ public class CoreDataDandy {
do {
results = try fetch(entityName, filterBy: predicate)
} catch {
- log(message("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) raised an exception. This is a serious error that should be resolved immediately."))
+ debugPrint("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) raised an exception. This is a serious error that should be resolved immediately.")
}
- if results?.count == 0 && emitResultCountWarnings {
- log(message("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) returned no results."))
- }
- else if results?.count > 1 && emitResultCountWarnings {
- log(message("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) returned multiple results. This is a serious error that should be resolved immediately."))
+ if let results = results {
+ if results.count == 0 && emitResultCountWarnings {
+ debugPrint("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) returned no results.")
+ }
+ else if results.count > 1 && emitResultCountWarnings {
+ debugPrint("Your fetch for a unique entity named \(entityName) with primary key \(primaryKeyValue) returned multiple results. This is a serious error that should be resolved immediately.")
+ }
+ return results.first
}
- return results?.first
}
else {
- log(message("Failed to produce predicate for \(entityName) with primary key \(primaryKeyValue)."))
+ debugPrint("Failed to produce predicate for \(entityName) with primary key \(primaryKeyValue).")
}
}
- log(message("A unique NSManaged for entity named \(entityName) could not be retrieved for primaryKey \(primaryKeyValue). No object will be returned"))
+ debugPrint("A unique NSManaged for entity named \(entityName) could not be retrieved for primaryKey \(primaryKeyValue). No object will be returned")
return nil
}
else {
- log(message("NSEntityDescriptionNotFound for entity named \(entityName). No object will be returned"))
+ debugPrint("NSEntityDescriptionNotFound for entity named \(entityName). No object will be returned")
return nil
}
}
@@ -258,7 +264,7 @@ public class CoreDataDandy {
///
/// - throws: If the ensuing NSManagedObjectContext's executeFetchRequest() throws, the exception will be passed.
/// - returns: If the fetch was successful, the fetched NSManagedObjects.
- public func fetch(entityName: String) throws -> [NSManagedObject]? {
+ public func fetch(_ entityName: String) throws -> [NSManagedObject]? {
return try fetch(entityName, filterBy: nil)
}
@@ -270,10 +276,10 @@ public class CoreDataDandy {
/// - throws: If the ensuing NSManagedObjectContext's executeFetchRequest() throws, the exception will be passed.
///
/// - returns: If the fetch was successful, the fetched NSManagedObjects.
- public func fetch(entityName: String, filterBy predicate: NSPredicate?) throws -> [NSManagedObject]? {
- let request = NSFetchRequest(entityName: entityName)
+ public func fetch(_ entityName: String, filterBy predicate: NSPredicate?) throws -> [NSManagedObject]? {
+ let request = NSFetchRequest(entityName: entityName)
request.predicate = predicate
- let results = try coordinator.mainContext.executeFetchRequest(request)
+ let results = try coordinator.mainContext.fetch(request)
return results as? [NSManagedObject]
}
@@ -283,34 +289,34 @@ public class CoreDataDandy {
///
/// - parameter completion: An optional closure that is invoked when the save operation complete. If the save operation
/// resulted in an error, the error is returned.
- public func save(completion:((error: NSError?) -> Void)? = nil) {
+ public func save(completion:((_ error: NSError?) -> Void)? = nil) {
/**
Note: http://www.openradar.me/21745663. Currently, there is no way to throw out of performBlock. If one arises,
this code should be refactored to throw.
*/
if !coordinator.mainContext.hasChanges && !coordinator.privateContext.hasChanges {
if let completion = completion {
- completion(error: nil)
+ completion(nil)
}
return
}
- coordinator.mainContext.performBlockAndWait({[unowned self] in
+ coordinator.mainContext.performAndWait({[unowned self] in
do {
try self.coordinator.mainContext.save()
} catch {
- log(message( "Failed to save main context."))
- completion?(error: error as NSError)
+ debugPrint("Failed to save main context.")
+ completion?(error as NSError)
return
}
- self.coordinator.privateContext.performBlock({ [unowned self] in
+ self.coordinator.privateContext.perform({ [unowned self] in
do {
try self.coordinator.privateContext.save()
- completion?(error: nil)
+ completion?(nil)
}
catch {
- log(message( "Failed to save private context."))
- completion?(error: error as NSError)
+ debugPrint("Failed to save private context.")
+ completion?(error as NSError)
}
})
})
@@ -320,10 +326,10 @@ public class CoreDataDandy {
///
/// - parameter object: The object to be deleted.
/// - parameter completion: An optional closure that is invoked when the deletion is complete.
- public func delete(object: NSManagedObject, completion: (() -> Void)? = nil) {
+ public func delete(_ object: NSManagedObject, completion: (() -> Void)? = nil) {
if let context = object.managedObjectContext {
- context.performBlock({
- context.deleteObject(object)
+ context.perform({
+ context.delete(object)
completion?()
})
}
@@ -337,25 +343,25 @@ public class CoreDataDandy {
/// - returns: The singleton for this entity if one could be found.
private func singletonEntity(entityName: String) -> NSManagedObject? {
// Validate the entity description to ensure fetch safety
- if let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: coordinator.mainContext) {
+ if let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: coordinator.mainContext) {
do {
if let results = try fetch(entityName) {
if results.count == 1 {
return results.first
} else if results.count == 0 {
- return NSManagedObject(entity: entityDescription, insertIntoManagedObjectContext: coordinator.mainContext)
+ return NSManagedObject(entity: entityDescription, insertInto: coordinator.mainContext)
} else {
- log(message("Failed to fetch unique instance of entity named " + entityName + "."))
+ debugPrint("Failed to fetch unique instance of entity named " + entityName + ".")
return nil
}
}
}
catch {
- log(message("Your singleton fetch for entity named \(entityName) raised an exception. This is a serious error that should be resolved immediately."))
+ debugPrint("Your singleton fetch for entity named \(entityName) raised an exception. This is a serious error that should be resolved immediately.")
}
}
- log(message("Failed to fetch unique instance of entity named " + entityName + "."))
+ debugPrint("Failed to fetch unique instance of entity named " + entityName + ".")
return nil
}
}
diff --git a/Source/Core/EntityMapper.swift b/Source/Core/EntityMapper.swift
index fb3dd60..9238db8 100644
--- a/Source/Core/EntityMapper.swift
+++ b/Source/Core/EntityMapper.swift
@@ -47,18 +47,18 @@ struct EntityMapper {
// Map attributes
if let attributes = entity.allAttributes {
- add(attributes, to: &map)
+ add(dictionary: attributes, to: &map)
}
// Map relationships
if let relationships = entity.allRelationships {
- add(relationships, to: &map)
+ add(dictionary: relationships, to: &map)
}
- archive(map, forEntity:entityName)
+ archive(map: map, forEntity:entityName)
return map
}
} else {
- log(message("Entity Name is nil for Entity " + entity.description + ". No mapping will be returned"))
+ debugPrint("Entity Name is nil for Entity " + entity.description + ". No mapping will be returned")
}
return nil
}
@@ -67,9 +67,11 @@ struct EntityMapper {
///
/// - parameter dictionary: A dictionary containing either NSAttributeDescriptions or NSRelationshipDescriptions
/// - parameter map: The map for reading json into an entity
- private static func add(dictionary: [String: AnyObject], inout to map: [String: PropertyDescription]) {
+ private static func add(dictionary: [String: AnyObject], to map: inout [String: PropertyDescription]) {
for (name, description) in dictionary {
- if let newMapping = mappingForUserInfo(description.userInfo) {
+ // TODO: Check this
+ let userInfo = description.userInfo as [NSObject : AnyObject]?
+ if let newMapping = mappingForUserInfo(userInfo: userInfo) {
// Do not add values specified as non-mapping to the mapping dictionary
if newMapping != NO_MAPPING {
map[newMapping] = PropertyDescription(description: description)
@@ -103,7 +105,7 @@ extension EntityMapper {
static var cachedEntityMap: [String: [String: PropertyDescription]] {
get {
if _cachedEntityMap == nil {
- if let archivedMap = NSKeyedUnarchiver.unarchiveObjectWithFile(self.entityMapFilePath) as? [String: [String: PropertyDescription]] {
+ if let archivedMap = NSKeyedUnarchiver.unarchiveObject(withFile: self.entityMapFilePath) as? [String: [String: PropertyDescription]] {
_cachedEntityMap = archivedMap
} else {
_cachedEntityMap = [String: [String: PropertyDescription]]()
@@ -119,9 +121,8 @@ extension EntityMapper {
/// - returns: The file path where the entityMap is archived.
private static var entityMapFilePath: String = {
- let pathArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
- let documentPath = pathArray.first!
- return NSString(string: documentPath).stringByAppendingPathComponent(CACHED_MAPPING_LOCATION)
+ let path = NSString(string:PersistentStackCoordinator.applicationDocumentsDirectory.relativePath)
+ return path.appendingPathComponent(CACHED_MAPPING_LOCATION)
}()
/// Archives an entity's mapping. Note, this mapping, will be saved to the `cachedEntityMap` at the key
@@ -140,12 +141,12 @@ extension EntityMapper {
/// where the cached entity mappings may be invalidated..
static func clearCache() {
_cachedEntityMap = nil
- if NSFileManager.defaultManager().fileExistsAtPath(entityMapFilePath) {
+ if FileManager.default.fileExists(atPath: entityMapFilePath) {
do {
- try NSFileManager.defaultManager().removeItemAtPath(entityMapFilePath)
+ try FileManager.default.removeItem(atPath: entityMapFilePath)
} catch {
- log(message("Failure to remove entity map from cache"))
+ debugPrint("Failure to remove entity map from cache")
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/Core/Logger.swift b/Source/Core/Logger.swift
index f52e947..789178d 100644
--- a/Source/Core/Logger.swift
+++ b/Source/Core/Logger.swift
@@ -27,15 +27,15 @@
import Foundation
-
+/*
// MARK: - Warnings -
func log(@autoclosure message: () -> String, filename: String = #file, function: String = #function, line: Int = #line) {
#if DEBUG
NSLog("[\(NSString(string: filename).lastPathComponent):\(line)] \(function) - %@", message())
#endif
}
-
-func message(message: String, with error: NSError? = nil) -> String {
+*/
+func message(_ message: String, with error: NSError? = nil) -> String {
#if DEBUG
var errorDescription = ""
if let error = error {
@@ -46,4 +46,4 @@ func message(message: String, with error: NSError? = nil) -> String {
#else
return ""
#endif
-}
\ No newline at end of file
+}
diff --git a/Source/Core/ObjectFactory.swift b/Source/Core/ObjectFactory.swift
index 4d28531..826a522 100644
--- a/Source/Core/ObjectFactory.swift
+++ b/Source/Core/ObjectFactory.swift
@@ -47,18 +47,18 @@ public struct ObjectFactory {
public static func make(entity: NSEntityDescription, from json: [String: AnyObject]) -> NSManagedObject? {
// Find primary key
if let name = entity.name,
- let primaryKeyValue = entity.primaryKeyValueFromJSON(json) {
+ let primaryKeyValue = entity.primaryKeyValueFromJSON(json: json) {
// Attempt to fetch or create unique object for primaryKey
let object = Dandy.insertUnique(name, primaryKeyValue: primaryKeyValue)
if var object = object {
- object = build(object, from: json)
+ object = build(object: object, from: json)
finalizeMapping(of: object, from: json)
} else {
- log(message("A unique object could not be generated for entity \(entity.name) from json \n\(json)."))
+ debugPrint("A unique object could not be generated for entity \(entity.name) from json \n\(json).")
}
return object
}
- log(message("A unique object could not be generated for entity \(entity.name) from json \n\(json)."))
+ debugPrint("A unique object could not be generated for entity \(entity.name) from json \n\(json).")
return nil
}
@@ -70,18 +70,18 @@ public struct ObjectFactory {
///
/// - returns: The object passed in with newly mapped values where mapping was possible.
public static func build(object: NSManagedObject, from json: [String: AnyObject]) -> NSManagedObject {
- if let map = EntityMapper.map(object.entity) {
+ if let map = EntityMapper.map(entity: object.entity) {
// Begin mapping values from json to object properties
for (key, description) in map {
- if let value: AnyObject = valueAt(key, of: json) {
+ if let value: AnyObject = valueAt(keypath: key, of: json) {
// A valid mapping was found for an attribute of a known type
- if description.type == .Attribute,
+ if description.type == .attribute,
let type = description.attributeType {
- object.setValue(CoreDataValueConverter.convert(value, toType: type), forKey: description.name)
+ object.setValue(CoreDataValueConverter.convert(value: value, toType: type), forKey: description.name)
}
// A valid mapping was found for a relationship of a known type
- else if description.type == .Relationship {
- make(description, to: object, from: value)
+ else if description.type == .relationship {
+ make(relationship: description, to: object, from: value)
}
}
}
@@ -103,29 +103,29 @@ public struct ObjectFactory {
static func make(relationship: PropertyDescription, to object: NSManagedObject, from json: AnyObject) -> NSManagedObject {
if let relatedEntity = relationship.destinationEntity {
// A dictionary was passed for a toOne relationship
- if let json = json as? [String: AnyObject] where !relationship.toMany {
- if let relation = make(relatedEntity, from: json) {
+ if let json = json as? [String: AnyObject], !relationship.toMany {
+ if let relation = make(entity: relatedEntity, from: json) {
object.setValue(relation, forKey: relationship.name)
} else {
- log(message("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(json)."))
+ debugPrint("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(json).")
}
return object
}
// An array was passed for a toMany relationship
- else if let json = json as? [[String: AnyObject]] where relationship.toMany {
+ else if let json = json as? [[String: AnyObject]], relationship.toMany {
var relations = [NSManagedObject]()
for child in json {
- if let relation = make(relatedEntity, from: child) {
+ if let relation = make(entity: relatedEntity, from: child) {
relations.append(relation)
} else {
- log(message("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(child)."))
+ debugPrint("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(child).")
}
}
object.setValue(relationship.ordered ? NSOrderedSet(array: relations): NSSet(array: relations), forKey: relationship.name)
return object
}
}
- log(message("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(json)."))
+ debugPrint("A relationship named \(relationship.name) could not be established for object \(object) from json \n\(json).")
return object
}
@@ -140,4 +140,4 @@ public struct ObjectFactory {
object.finalizeMapping(of: json)
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/Core/PersistentStackCoordinator.swift b/Source/Core/PersistentStackCoordinator.swift
index a55de66..1a36943 100644
--- a/Source/Core/PersistentStackCoordinator.swift
+++ b/Source/Core/PersistentStackCoordinator.swift
@@ -41,9 +41,14 @@ public class PersistentStackCoordinator {
// MARK: - Lazy stack initialization -
/// The .xcdatamodel to read from.
+// lazy var managedObjectModel: NSManagedObjectModel = {
+// let modelURL = Bundle.main.url(forResource: self.managedObjectModelName, withExtension: "momd")!
+// return NSManagedObjectModel(contentsOf: modelURL)!
+// }()
+
lazy var managedObjectModel: NSManagedObjectModel = {
- let modelURL = NSBundle(forClass: self.dynamicType).URLForResource(self.managedObjectModelName, withExtension: "momd")!
- return NSManagedObjectModel(contentsOfURL: modelURL)!
+ let modelURL = Bundle(for: type(of: self)).url(forResource: self.managedObjectModelName, withExtension: "momd")!
+ return NSManagedObjectModel(contentsOf: modelURL)!
}()
/// The persistent store coordinator, which manages disk operations.
@@ -56,52 +61,68 @@ public class PersistentStackCoordinator {
/// The primary managed object context. Note the inclusion of the parent context, which takes disk operations off
/// the main thread.
public lazy var mainContext: NSManagedObjectContext = { [unowned self] in
- var mainContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
- mainContext.mergePolicy = NSMergePolicy(mergeType: NSMergePolicyType.MergeByPropertyObjectTrumpMergePolicyType)
+ var mainContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+ mainContext.mergePolicy = NSMergePolicy(merge: NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType)
self.connectPrivateContextToPersistentStoreCoordinator()
- mainContext.parentContext = self.privateContext
+ mainContext.parent = self.privateContext
return mainContext
}()
/// Connects the private context with its PSC on the correct thread, waits for the connection to take place,
/// then announces its completion via the initializationCompletion closure.
func connectPrivateContextToPersistentStoreCoordinator() {
- self.privateContext.performBlockAndWait({ [unowned self] in
+ print(self.privateContext)
+ self.privateContext.performAndWait({ [unowned self] in
+ print(self.persistentStoreCoordinator)
self.privateContext.persistentStoreCoordinator = self.persistentStoreCoordinator
if let completion = self.persistentStoreConnectionCompletion {
- dispatch_async(dispatch_get_main_queue(), {
+ DispatchQueue.main.async {
completion()
- })
+ }
}
})
}
/// A context that escorts disk operations off the main thread.
lazy var privateContext: NSManagedObjectContext = { [unowned self] in
- var privateContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
- privateContext.mergePolicy = NSMergePolicy(mergeType: NSMergePolicyType.MergeByPropertyObjectTrumpMergePolicyType)
+ var privateContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+ privateContext.mergePolicy = NSMergePolicy(merge: NSMergePolicyType.mergeByPropertyObjectTrumpMergePolicyType)
return privateContext
}()
// MARK: - Convenience accessors -
/// - returns: The path to the Documents directory of a given device. This is where the sqlite file will be saved, and is a
/// useful value for debugging purposes.
- static var applicationDocumentsDirectory: NSURL = {
- let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
- return urls[urls.count - 1]
- }()
+// static var applicationDocumentsDirectory: URL = {
+// let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
+// return urls[urls.count - 1]
+// }()
+
+
+ static var applicationDocumentsDirectory: URL = {
+ let docURL = FileManager.default.urls(for: .documentDirectory, in:.userDomainMask).first!
+ let path = docURL.relativePath
+ if !FileManager.default.fileExists(atPath: path) {
+ do {
+ try FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
+ } catch {
+ print(error.localizedDescription);
+ }
+ }
+ return docURL
+ }()
/// - returns: The path to the sqlite file that stores the application's data.
- static var persistentStoreURL: NSURL = {
- return applicationDocumentsDirectory.URLByAppendingPathComponent("Model.sqlite")
+ static var persistentStoreURL: URL = {
+ return applicationDocumentsDirectory.appendingPathComponent("Model.sqlite")
}()
// MARK: - Stack clearing -
/// Clear the managed object contexts.
func resetManageObjectContext() {
- mainContext.performBlockAndWait({[unowned self] in
+ mainContext.performAndWait({[unowned self] in
self.mainContext.reset()
- self.privateContext.performBlockAndWait({
+ self.privateContext.performAndWait({
self.privateContext.reset()
})
})
@@ -121,32 +142,35 @@ extension NSPersistentStoreCoordinator {
func resetPersistentStore() {
for store in persistentStores {
do {
- try removePersistentStore(store)
+ try remove(store)
} catch {
- log(message("Failure to remove persistent store"))
+ debugPrint("Failure to remove persistent store")
}
}
do {
- let options = [NSMigratePersistentStoresAutomaticallyOption: NSNumber(bool: true), NSInferMappingModelAutomaticallyOption: NSNumber(bool: true)]
- try addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil,
- URL: PersistentStackCoordinator.persistentStoreURL,
+ // this prints out a directory that doesn't exist
+ let options = [NSMigratePersistentStoresAutomaticallyOption: NSNumber(value: true), NSInferMappingModelAutomaticallyOption: NSNumber(value: true)]
+ try addPersistentStore(
+ ofType: NSSQLiteStoreType,
+ configurationName: nil,
+ at: PersistentStackCoordinator.persistentStoreURL as URL,
options: options)
} catch {
- var dict = [String: AnyObject]()
+ var dict = [String: Any]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = "There was an error creating or loading the application's saved data."
dict[NSUnderlyingErrorKey] = error as NSError
let error = NSError(domain: DandyErrorDomain, code: 9999, userInfo: dict)
- log(message("Failure to add persistent store", with: error))
+ debugPrint("Failure to add persistent store ‼️ ERROR: \(error.description)")
do {
- try NSFileManager.defaultManager().removeItemAtURL(PersistentStackCoordinator.persistentStoreURL)
+ try FileManager.default.removeItem(at: PersistentStackCoordinator.persistentStoreURL)
} catch {
- log(message("Failure to remove cached sqlite file"))
+ debugPrint("Failure to remove cached sqlite file")
}
EntityMapper.clearCache()
- #if !TEST
- abort()
- #endif
+// #if !TEST
+// abort()
+// #endif
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/Core/PropertyDescription.swift b/Source/Core/PropertyDescription.swift
index af8212e..862682c 100644
--- a/Source/Core/PropertyDescription.swift
+++ b/Source/Core/PropertyDescription.swift
@@ -33,11 +33,24 @@ import CoreData
/// - Attribute: Marks a property description corresponding to an attribute.
/// - Relationship: Marks a property description corresponding to an relationship.
enum PropertyType: Int {
- case Unknown = 0
- case Attribute
- case Relationship
+ case unknown = 0
+ case attribute
+ case relationship
+}
+class MyObj: NSObject, NSCoding {
+ func encode(with coder: NSCoder) {
+ print("encode")
+ }
+
+ override init(){
+ print("my init")
+ }
+ required init?(coder: NSCoder) {
+ print("init")
+ }
+
+
}
-
/// `PropertyDescription` provides a convenient means of accessing information necessary to map json into an
/// NSManagedObject. It encapsulates values found in `NSAttributeDescriptions` and `NSRelationshipDescriptions`, such as
/// an attribute's type or if a relationship is ordered or not.
@@ -46,7 +59,7 @@ final class PropertyDescription : NSObject {
var name = String()
/// The property type: .Unknown, .Attribute, or .Relationship.
- var type = PropertyType.Unknown
+ var type = PropertyType.unknown
/// The type of an attribute.
var attributeType: NSAttributeType?
@@ -73,14 +86,14 @@ final class PropertyDescription : NSObject {
self.init(relationshipDescription: description)
} else {
self.init()
- log(message("Unknown property type for description: \(description)"))
+ debugPrint("Unknown property type for description: \(description)")
}
}
/// An initializer that builds a `PropertyDescription` by extracting relevant values from an `NSAttributeDescription`.
private init(attributeDescription: NSAttributeDescription) {
name = attributeDescription.name
- type = PropertyType.Attribute
+ type = PropertyType.attribute
attributeType = attributeDescription.attributeType
super.init()
}
@@ -88,41 +101,41 @@ final class PropertyDescription : NSObject {
/// An initializer that builds a `PropertyDescription` by extracting relevant values from an `NSRelationshipDescription`.
private init(relationshipDescription: NSRelationshipDescription) {
name = relationshipDescription.name
- type = PropertyType.Relationship
+ type = PropertyType.relationship
destinationEntity = relationshipDescription.destinationEntity
- ordered = relationshipDescription.ordered
- toMany = relationshipDescription.toMany
+ ordered = relationshipDescription.isOrdered
+ toMany = relationshipDescription.isToMany
super.init()
}
}
// MARK: - -
-extension PropertyDescription : NSCoding {
- convenience init?(coder aDecoder: NSCoder) {
+extension PropertyDescription: NSCoding {
+ convenience init?(coder: NSCoder) {
self.init()
- if let n = aDecoder.decodeObjectForKey("name") as? String {
+ if let n = coder.decodeObject(forKey: "name") as? String {
name = n
}
- type = PropertyType(rawValue: aDecoder.decodeIntegerForKey("type"))!
- attributeType = NSAttributeType(rawValue: UInt(aDecoder.decodeIntegerForKey("attributeType")))!
- ordered = aDecoder.decodeBoolForKey("ordered")
- toMany = aDecoder.decodeBoolForKey("toMany")
+ type = PropertyType(rawValue: coder.decodeInteger(forKey: "type"))!
+ attributeType = NSAttributeType(rawValue: UInt(coder.decodeInteger(forKey: "attributeType")))!
+ ordered = coder.decodeBool(forKey: "ordered")
+ toMany = coder.decodeBool(forKey: "toMany")
}
-
- @objc func encodeWithCoder(aCoder: NSCoder) {
- aCoder.encodeObject(name, forKey:"name")
- aCoder.encodeInteger(type.rawValue, forKey:"type")
+
+ @objc func encode(with coder: NSCoder) {
+ coder.encode(name, forKey:"name")
+ coder.encode(type.rawValue, forKey:"type")
if let attributeType = attributeType {
- aCoder.encodeInteger(Int(attributeType.rawValue), forKey:"attributeType")
+ coder.encode(Int(attributeType.rawValue), forKey:"attributeType")
}
if let destinationEntity = destinationEntity {
- aCoder.encodeObject(destinationEntity, forKey:"destinationEntity")
+ coder.encode(destinationEntity, forKey:"destinationEntity")
}
- aCoder.encodeBool(ordered, forKey: "ordered")
- aCoder.encodeBool(toMany, forKey: "toMany")
+ coder.encode(ordered, forKey: "ordered")
+ coder.encode(toMany, forKey: "toMany")
}
- override var hashValue: Int {
+ override var hash: Int {
get {
return "\(name)_\(type)_\(attributeType)_\(destinationEntity)_\(ordered)_\(toMany)".hashValue
}
@@ -133,11 +146,30 @@ extension PropertyDescription : NSCoding {
extension PropertyDescription {
/// Compares the hashValue of two `PropertyDescription` objects. `PropertyDescription` objects are never considered
/// equal to other types.
- override func isEqual(object: AnyObject?) -> Bool {
+ override class func isEqual(_ object: Any?) -> Bool {
if let object = object as? PropertyDescription {
- return hashValue == object.hashValue
+ return hash() == object.hashValue
} else {
return false
}
}
-}
\ No newline at end of file
+
+ class func == (lhs: PropertyDescription, rhs: PropertyDescription) -> Bool {
+ return lhs.name == rhs.name
+ }
+
+}
+
+extension Dictionary where Key == String, Value == PropertyDescription {
+ static func == (lhs: [String: PropertyDescription], rhs: [String: PropertyDescription]) -> Bool {
+ guard lhs.keys.count == rhs.keys.count else { return false }
+ return lhs.keys.filter({ lhs[$0]?.name != rhs[$0]?.name }).isEmpty
+ }
+}
+
+// TODO: SL check
+
+func == (lhs: [Key: Value?], rhs: [Key: Value?]) -> Bool {
+ guard let lhs = lhs as? [Key: Value], let rhs = rhs as? [Key: Value] else { return false }
+ return NSDictionary(dictionary: lhs).isEqual(to: rhs)
+}
diff --git a/Source/Core/Serializer.swift b/Source/Core/Serializer.swift
index 66f1f27..e8c7f12 100644
--- a/Source/Core/Serializer.swift
+++ b/Source/Core/Serializer.swift
@@ -57,24 +57,79 @@ public struct Serializer {
///
/// - returns: A json representation of this object and its relationships if one could be produced. Otherwise, nil.
public static func serialize(object: NSManagedObject, including relationships: [String]? = nil) -> [String: AnyObject]? {
- var json = [String: AnyObject]()
- let map = EntityMapper.map(object.entity)
+ guard let map = EntityMapper.map(entity: object.entity) else {
+ debugPrint("Failed to serialize object \(object) including relationships \(String(describing: relationships))")
+ return nil
+ }
+ var json = [String: Any]()
+ for (property, description) in map {
+ switch description.type {
+ case .attribute:
+ json[property] = object.value(forKey: description.name) as AnyObject?
+ default:
+ if let relationships = relationships,
+ relationships.contains(where: { $0.range(of: description.name) != nil }) {
+ if let nestedRelationships = nestedSerializationTargets(for: description.name, including: relationships) {
+ serializeNestedRelationships(property, description, object, nestedRelationships, &json)
+ } else {
+ if let relationship = object.value(forKey: description.name) as? NSManagedObject {
+ json[property] = serialize(object: relationship, including: nil) as AnyObject
+ } else {
+ json[property] = [:] // Assume nils to intend empty objects
+ }
+ }
+ }
+ }
+ }
+
+ if json.isEmpty {
+ debugPrint("Failed to serialize object \(object) including relationships \(String(describing: relationships))")
+ return nil
+ }
+
+ return json as [String : AnyObject]
+ }
+
+ static private func serializeNestedRelationships(_ property: String,
+ _ description: PropertyDescription,
+ _ object: NSManagedObject,
+ _ nestedRelationships: [String],
+ _ json: inout [String: Any]) {
+ // Map relationships and recurse into nested relationships
+ if description.toMany {
+ let objects = object.value(forKey: description.name) as AnyObject
+ let relatedObjectsUnwrapped = description.ordered ? objects.array: objects.allObjects
+ guard let relatedObjects = relatedObjectsUnwrapped as? [NSManagedObject] else { json[property] = [[:]]; return }
+ if !relatedObjects.isEmpty {
+ json[property] = serialize(objects: relatedObjects, including: nestedRelationships)
+ } else {
+ json[property] = [[:]]
+ }
+ } else {
+ guard let relationship = object.value(forKey: description.name) as? NSManagedObject else { json[property] = [:]; return }
+ json[property] = serialize(object: relationship, including: nestedRelationships) as AnyObject
+ }
+ }
+
+ public static func serialize_(object: NSManagedObject, including relationships: [String]? = nil) -> [String: AnyObject]? {
+ var json = [String: Any]()
+ let map = EntityMapper.map(entity: object.entity)
if let map = map {
for (property, description) in map {
// Map attributes, ensuring mapping conversion
- if description.type == .Attribute {
- json[property] = object.valueForKey(description.name)
+ if description.type == .attribute {
+ json[property] = object.value(forKey: description.name) as AnyObject?
}
- else if let relationships = relationships
- where (relationships.contains(description.name)
- || nestedSerializationTargets(for: description.name, including: relationships)?.count > 0) {
+ else if let relationships = relationships,
+ let targets = nestedSerializationTargets(for: description.name, including: relationships), (relationships.contains(description.name) || targets.count > 0) {
let nestedRelationships = nestedSerializationTargets(for: description.name, including: relationships)
// Map relationships and recurse into nested relationships
if description.toMany {
- let relatedObjects = description.ordered ? object.valueForKey(description.name)?.array: object.valueForKey(description.name)?.allObjects
+ let objects = (object.value(forKey: description.name) as AnyObject)
+ let relatedObjects = description.ordered ? objects.array: objects.allObjects
if let relatedObjects = relatedObjects as? [NSManagedObject] {
if relatedObjects.count > 0 {
- json[property] = serialize(relatedObjects, including: nestedRelationships)
+ json[property] = serialize(objects: relatedObjects, including: nestedRelationships)
}
else {
json[property] = [[:]]
@@ -86,8 +141,8 @@ public struct Serializer {
}
}
else {
- if let relationship = object.valueForKey(description.name) as? NSManagedObject {
- json[property] = serialize(relationship, including: nestedRelationships) as? AnyObject
+ if let relationship = object.value(forKey: description.name) as? NSManagedObject {
+ json[property] = serialize(object: relationship, including: nestedRelationships) as AnyObject
}
// Assume nils to intend empty objects
else {
@@ -98,12 +153,11 @@ public struct Serializer {
}
}
if json.count == 0 {
- log(message("Failed to serialize object \(object) including relationships \(relationships)"))
+ debugPrint("Failed to serialize object \(object) including relationships \(relationships)")
return nil
}
- return json
+ return json as [String : AnyObject]
}
-
/// Recursively invokes other class methods to produce a json array, including relationships.
///
/// - parameter objects: An array of `NSManagedObjects` to serialize
@@ -113,7 +167,7 @@ public struct Serializer {
public static func serialize(objects: [NSManagedObject], including relationships: [String]? = nil) -> [[String: AnyObject]]? {
var json = [[String: AnyObject]]()
for object in objects {
- if let relationshipJSON = serialize(object, including: relationships) {
+ if let relationshipJSON = serialize(object: object, including: relationships) {
json.append(relationshipJSON)
}
}
@@ -130,9 +184,16 @@ public struct Serializer {
/// - returns: An array of nested relationships targeted for serialization.
static func nestedSerializationTargets(for relationship: String, including nestedRelationships: [String]?) -> [String]? {
if let nestedRelationships = nestedRelationships {
- let keypaths = nestedRelationships.filter({$0.rangeOfString(relationship) != nil && $0.rangeOfString(".") != nil})
+
+ var keypaths: [String] = []
+ if nestedRelationships.count > 1 {
+ keypaths = nestedRelationships.filter({$0.range(of: relationship) != nil && $0.range(of: ".") != nil })
+ } else {
+ keypaths = nestedRelationships.filter({$0.range(of: relationship) != nil })
+ }
+
// Eliminate the relationship name and the period, recursing one level deeper.
- let nestedTargets = keypaths.map({$0.stringByReplacingOccurrencesOfString(relationship + ".", withString: "")})
+ let nestedTargets = keypaths.map({$0.replacingOccurrences(of: relationship + ".", with: "")})
return nestedTargets.count > 0 ? nestedTargets: nil
}
return nil
diff --git a/Source/Extensions/Dictionary+Dandy.swift b/Source/Extensions/Dictionary+Dandy.swift
index 0ad6235..76c7cc1 100644
--- a/Source/Extensions/Dictionary+Dandy.swift
+++ b/Source/Extensions/Dictionary+Dandy.swift
@@ -40,7 +40,7 @@ public extension Dictionary {
/// Functions similarly to `NSDictionary's` valueForKeyPath.
func valueAt(keypath: String, of dictionary: [String: AnyObject]) -> AnyObject? {
- let keys = keypath.componentsSeparatedByString(".")
+ let keys = keypath.components(separatedBy: ".")
var copy = dictionary
var possibleValue: AnyObject?
for key in keys {
@@ -50,4 +50,4 @@ func valueAt(keypath: String, of dictionary: [String: AnyObject]) -> AnyObject?
}
}
return possibleValue
-}
\ No newline at end of file
+}
diff --git a/Source/Extensions/NSEntityDescription+Dandy.swift b/Source/Extensions/NSEntityDescription+Dandy.swift
index 14abbee..a34c72c 100644
--- a/Source/Extensions/NSEntityDescription+Dandy.swift
+++ b/Source/Extensions/NSEntityDescription+Dandy.swift
@@ -30,23 +30,25 @@ import CoreData
// MARK: - NSEntityDescription+UserInfo -
extension NSEntityDescription {
/// Recursively collects all userInfo values from potential superentities
- var allUserInfo: [NSObject: AnyObject]? {
+ var allUserInfo: [String: AnyObject]? {
get {
- return collectedEntityValuesFromDictionaryClosure({return $0.userInfo as? [String: AnyObject]})
+ return collectedEntityValuesFromDictionaryClosure(dictionaryClosure: {
+ return $0.userInfo as? [String: AnyObject]})
}
}
/// Recursively collects all attribute values from potential superentities
var allAttributes: [String: NSAttributeDescription]? {
get {
- return collectedEntityValuesFromDictionaryClosure({return $0.attributesByName}) as? [String: NSAttributeDescription]
+ return collectedEntityValuesFromDictionaryClosure(dictionaryClosure: {
+ return $0.attributesByName}) as? [String: NSAttributeDescription]
}
}
/// Recursively collects all relationship values from potential superentities
var allRelationships: [String: NSRelationshipDescription]? {
get {
- return collectedEntityValuesFromDictionaryClosure({return $0.relationshipsByName}) as? [String: NSRelationshipDescription]
+ return collectedEntityValuesFromDictionaryClosure(dictionaryClosure: {return $0.relationshipsByName}) as? [String: NSRelationshipDescription]
}
}
@@ -55,7 +57,9 @@ extension NSEntityDescription {
var uniqueConstraint: String? {
get {
if #available(iOS 9.0, *) {
- if let constraint = uniquenessConstraints.first?.first?.name {
+ // TODO: Check this
+// if let constraint = uniquenessConstraints.first?.first.debugDescription {
+ if let constraint = uniquenessConstraints.last?.first as? String {
return constraint
}
else if let superEntity = superentity {
@@ -78,7 +82,7 @@ extension NSEntityDescription {
// This approach ensures children override parent values.
for entity in entityHierarchy {
if let newValues = dictionaryClosure(entity) {
- values.addEntriesFrom(newValues)
+ values.addEntriesFrom(dictionary: newValues)
}
}
return values
@@ -91,7 +95,7 @@ extension NSEntityDescription {
var entities = [NSEntityDescription]()
var entity: NSEntityDescription? = self
while let currentEntity = entity {
- entities.insert(currentEntity, atIndex: 0)
+ entities.insert(currentEntity, at: 0)
entity = entity?.superentity
}
return entities
@@ -102,7 +106,7 @@ extension NSEntityDescription {
// MARK: - NSEntityDescription+Construction -
extension NSEntityDescription {
class func forEntity(name: String) -> NSEntityDescription? {
- return NSEntityDescription.entityForName(name, inManagedObjectContext: Dandy.coordinator.mainContext)
+ return NSEntityDescription.entity(forEntityName: name, in: Dandy.coordinator.mainContext)
}
}
@@ -131,7 +135,7 @@ extension NSEntityDescription {
/// - parameter json: JSON form which a primaryKey will be extracted
func primaryKeyValueFromJSON(json: [String: AnyObject]) -> AnyObject? {
if let primaryKey = primaryKey,
- let entityMap = EntityMapper.map(self) {
+ let entityMap = EntityMapper.map(entity: self) {
let filteredMap = entityMap.filter({ $1.name == primaryKey }).map({ $0.0 })
// If the primary key has an alternate mapping, return the value from the alternate mapping.
// Otherwise, return the json value matching the name of the primary key.
@@ -149,9 +153,11 @@ extension NSEntityDescription {
/// - returns: A predicate that may be used to fetch unique objects
func primaryKeyPredicate(for primaryKeyValue: AnyObject) -> NSPredicate? {
if let primaryKey = primaryKey,
- let value: AnyObject = CoreDataValueConverter.convert(primaryKeyValue, forEntity: self, property: primaryKey) {
+ let value: AnyObject = CoreDataValueConverter.convert(value: primaryKeyValue,
+ forEntity: self,
+ property: primaryKey) {
return NSPredicate(format: "%K = %@", argumentArray: [primaryKey, value])
}
return nil
}
-}
\ No newline at end of file
+}
diff --git a/Source/Value Conversion/ConvertibleType.swift b/Source/Value Conversion/ConvertibleType.swift
index ce4d63f..2460c13 100644
--- a/Source/Value Conversion/ConvertibleType.swift
+++ b/Source/Value Conversion/ConvertibleType.swift
@@ -61,37 +61,37 @@ extension NSDate : DateConvertible, NumericConvertible, StringConvertible {
return self
}
func convertToDecimal() -> NSDecimalNumber? {
- return NSDecimalNumber(double: self.timeIntervalSince1970)
+ return NSDecimalNumber(value: self.timeIntervalSince1970)
}
func convertToDouble() -> NSNumber? {
- return NSNumber(double: self.timeIntervalSince1970)
+ return NSNumber(value: self.timeIntervalSince1970)
}
func convertToFloat() -> NSNumber? {
- return NSNumber(float: Float(self.timeIntervalSince1970))
+ return NSNumber(value: Float(self.timeIntervalSince1970))
}
func convertToInt() -> NSNumber? {
- return NSNumber(integer: Int(round(self.timeIntervalSince1970)))
+ return NSNumber(value: Int(round(self.timeIntervalSince1970)))
}
func convertToString() -> NSString? {
- return CoreDataValueConverter.dateFormatter.stringFromDate(self)
+ return CoreDataValueConverter.dateFormatter.string(from: self as Date) as? NSString
}
}
-// MARK: - NSData -
+// MARK: - Data -
extension NSData : DataConvertible, StringConvertible {
func convertToData() -> NSData? {
return self
}
func convertToString() -> NSString? {
- return NSString(data: self, encoding: NSUTF8StringEncoding)
+ return String(data: self as Data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) as NSString?
}
}
// MARK: - NSNumber -
-extension NSNumber : ConvertibleType {
+extension NSNumber: ConvertibleType {
func convertToBoolean() -> NSNumber? {
- if self.integerValue == 0 {
- return NSNumber(bool: false)
- } else if self.integerValue >= 1 {
- return NSNumber(bool: true)
+ if self.intValue == 0 {
+ return NSNumber(value: false)
+ } else if self.intValue >= 1 {
+ return NSNumber(value: true)
}
return nil
}
@@ -99,54 +99,54 @@ extension NSNumber : ConvertibleType {
return NSDate(timeIntervalSince1970: self.doubleValue)
}
func convertToData() -> NSData? {
- return self.stringValue.dataUsingEncoding(NSUTF8StringEncoding)
+ return self.stringValue.data(using: String.Encoding.utf8) as NSData?
}
func convertToDecimal() -> NSDecimalNumber? {
- return NSDecimalNumber(double: self.doubleValue)
+ return NSDecimalNumber(value: self.doubleValue)
}
func convertToDouble() -> NSNumber? {
- return NSNumber(double: self.doubleValue)
+ return NSNumber(value: self.doubleValue)
}
func convertToFloat() -> NSNumber? {
- return NSNumber(float: self.floatValue)
+ return NSNumber(value: self.floatValue)
}
func convertToInt() -> NSNumber? {
- return NSNumber(integer: self.integerValue)
+ return NSNumber(value: self.intValue)
}
func convertToString() -> NSString? {
- return self.stringValue
+ return self.stringValue as NSString
}
}
// MARK: - NSString -
extension NSString : ConvertibleType {
func convertToBoolean() -> NSNumber? {
- let lowercaseValue = self.lowercaseString
+ let lowercaseValue = self.lowercased
if lowercaseValue == "yes" || lowercaseValue == "true" || lowercaseValue == "1" {
- return NSNumber(bool: true)
+ return NSNumber(value: true)
} else if lowercaseValue == "no" || lowercaseValue == "false" || lowercaseValue == "0" {
- return NSNumber(bool: false)
+ return NSNumber(value: false)
}
return nil
}
func convertToDate() -> NSDate? {
- return CoreDataValueConverter.dateFormatter.dateFromString(self as String)
+ return CoreDataValueConverter.dateFormatter.date(from: self as String) as NSDate?
}
func convertToData() -> NSData? {
- return self.dataUsingEncoding(NSUTF8StringEncoding)
+ return self.data(using: String.Encoding.utf8.rawValue) as NSData?
}
func convertToDecimal() -> NSDecimalNumber? {
- return NSDecimalNumber(double: self.doubleValue)
+ return NSDecimalNumber(value: self.doubleValue)
}
func convertToDouble() -> NSNumber? {
- return NSNumber(double: self.doubleValue)
+ return NSNumber(value: self.doubleValue)
}
func convertToFloat() -> NSNumber? {
- return NSNumber(float: self.floatValue)
+ return NSNumber(value: self.floatValue)
}
func convertToInt() -> NSNumber? {
- return NSNumber(integer: self.integerValue)
+ return NSNumber(value: self.integerValue)
}
func convertToString() -> NSString? {
return self
}
-}
\ No newline at end of file
+}
diff --git a/Source/Value Conversion/CoreDataValueConverter.swift b/Source/Value Conversion/CoreDataValueConverter.swift
index f1255bc..3fd2683 100644
--- a/Source/Value Conversion/CoreDataValueConverter.swift
+++ b/Source/Value Conversion/CoreDataValueConverter.swift
@@ -37,20 +37,20 @@ import CoreData
public struct CoreDataValueConverter {
/// A shared dateFormatter for regularly converting strings of a known pattern
/// to dates and vice-versa.
- public static let dateFormatter = NSDateFormatter()
+ public static let dateFormatter = DateFormatter()
/// Maps `NSAttributeTypes` to their corresponding type converters.
private static let typeConverters: [NSAttributeType: ValueConverter] = [
- .Integer16AttributeType: IntConverter(),
- .Integer32AttributeType: IntConverter(),
- .Integer64AttributeType: IntConverter(),
- .DecimalAttributeType: DecimalConverter(),
- .DoubleAttributeType: DoubleConverter(),
- .FloatAttributeType: FloatConverter(),
- .StringAttributeType: StringConverter(),
- .BooleanAttributeType: BooleanConverter(),
- .DateAttributeType: DateConverter(),
- .BinaryDataAttributeType: DataConverter()
+ .integer16AttributeType: IntConverter(),
+ .integer32AttributeType: IntConverter(),
+ .integer64AttributeType: IntConverter(),
+ .decimalAttributeType: DecimalConverter(),
+ .doubleAttributeType: DoubleConverter(),
+ .floatAttributeType: FloatConverter(),
+ .stringAttributeType: StringConverter(),
+ .booleanAttributeType: BooleanConverter(),
+ .dateAttributeType: DateConverter(),
+ .binaryDataAttributeType: DataConverter()
]
/// Attempts to convert a given value to a type matching the specified entity property type. For instance,
/// if "3" is passed but the specified entity's property is defined as an NSNumber, @3 will be returned.
@@ -65,7 +65,7 @@ public struct CoreDataValueConverter {
public static func convert(value: AnyObject, forEntity entity: NSEntityDescription, property: String) -> AnyObject? {
let attributeDescription = entity.propertiesByName[property] as? NSAttributeDescription
if let attributeDescription = attributeDescription {
- return convert(value, toType: attributeDescription.attributeType)
+ return convert(value: value, toType: attributeDescription.attributeType)
}
return nil
}
@@ -78,8 +78,8 @@ public struct CoreDataValueConverter {
/// - returns: If the conversion was successful, the converted value. Otherwise, nil.
public static func convert(value: AnyObject, toType type: NSAttributeType) -> AnyObject? {
if let converter = typeConverters[type] {
- return converter.convert(value)
+ return converter.convert(value: value)
}
return nil
}
-}
\ No newline at end of file
+}
diff --git a/Source/Value Conversion/ValueConverter.swift b/Source/Value Conversion/ValueConverter.swift
index 7adafd5..132da6b 100644
--- a/Source/Value Conversion/ValueConverter.swift
+++ b/Source/Value Conversion/ValueConverter.swift
@@ -47,41 +47,41 @@ extension ValueConverter {
struct BooleanConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: BooleanConvertible.self) { $0.convertToBoolean() }
+ return convert(value: value, to: BooleanConvertible.self) { $0.convertToBoolean() }
}
}
struct DateConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: DateConvertible.self) { $0.convertToDate() }
+ return convert(value: value, to: DateConvertible.self) { $0.convertToDate() }
}
}
struct DataConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: DataConvertible.self) { $0.convertToData() }
+ return convert(value: value, to: DataConvertible.self) { $0.convertToData() }
}
}
struct DoubleConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: DoubleConvertible.self) { $0.convertToDouble() }
+ return convert(value: value, to: DoubleConvertible.self) { $0.convertToDouble() }
}
}
struct DecimalConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: DecimalConvertible.self) { $0.convertToDecimal() }
+ return convert(value: value, to: DecimalConvertible.self) { $0.convertToDecimal() }
}
}
struct FloatConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: FloatConvertible.self) { $0.convertToFloat() }
+ return convert(value: value, to: FloatConvertible.self) { $0.convertToFloat() }
}
}
struct IntConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: IntConvertible.self) { $0.convertToInt() }
+ return convert(value: value, to: IntConvertible.self) { $0.convertToInt() }
}
}
struct StringConverter: ValueConverter {
func convert(value: AnyObject) -> AnyObject? {
- return convert(value, to: StringConvertible.self) { $0.convertToString() }
+ return convert(value: value, to: StringConvertible.self) { $0.convertToString() }
}
-}
\ No newline at end of file
+}
diff --git a/Tests/CoreDataDandyTests.xcodeproj/project.pbxproj b/Tests/CoreDataDandyTests.xcodeproj/project.pbxproj
index e7aa5aa..dfe73ba 100644
--- a/Tests/CoreDataDandyTests.xcodeproj/project.pbxproj
+++ b/Tests/CoreDataDandyTests.xcodeproj/project.pbxproj
@@ -175,6 +175,7 @@
TargetAttributes = {
988F4A631B3632EE00E71046 = {
CreatedOnToolsVersion = 6.3.2;
+ DevelopmentTeam = EUR8GE96BE;
};
};
};
@@ -183,6 +184,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
+ English,
en,
);
mainGroup = 988F4A591B3632DC00E71046;
@@ -242,6 +244,7 @@
ONLY_ACTIVE_ARCH = YES;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
+ SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -252,6 +255,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
+ SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -272,8 +276,10 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = EUR8GE96BE;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = NO;
FRAMEWORK_SEARCH_PATHS = "";
@@ -324,8 +330,10 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = EUR8GE96BE;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = NO;
diff --git a/Tests/CoreDataDandyTests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Tests/CoreDataDandyTests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/Tests/CoreDataDandyTests.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/Tests/CoreDataDandyTests/CoreDataDandyTests.swift b/Tests/CoreDataDandyTests/CoreDataDandyTests.swift
index 494f04e..d8069f2 100644
--- a/Tests/CoreDataDandyTests/CoreDataDandyTests.swift
+++ b/Tests/CoreDataDandyTests/CoreDataDandyTests.swift
@@ -32,8 +32,8 @@ class CoreDataDandyTests: XCTestCase {
override func setUp() {
CoreDataDandy.wake(with: "DandyModel")
- CoreDataValueConverter.dateFormatter.dateStyle = .LongStyle
- CoreDataValueConverter.dateFormatter.timeStyle = .ShortStyle
+ CoreDataValueConverter.dateFormatter.dateStyle = .long
+ CoreDataValueConverter.dateFormatter.timeStyle = .short
super.setUp()
}
override func tearDown() {
@@ -45,7 +45,7 @@ class CoreDataDandyTests: XCTestCase {
When the clean up completes, no data should remain.
*/
func testCleanUp() {
- Dandy.insert("Dandy")
+ Dandy.insert("Dandy") // "Failed to initialize the application's saved data"
Dandy.save()
let initialResultsCount = try! Dandy.fetch("Dandy")?.count
Dandy.tearDown()
@@ -58,16 +58,16 @@ class CoreDataDandyTests: XCTestCase {
After a save, the size of the persistent store should increase
*/
func testSave() {
- let expectation = self.expectationWithDescription("save")
+ let expectation = self.expectation(description: "save")
do {
- let unsavedData = try NSFileManager.defaultManager().attributesOfItemAtPath(PersistentStackCoordinator.persistentStoreURL.path!)["NSFileSize"] as! Int
+ let unsavedData = try FileManager.default.attributesOfItem(atPath: PersistentStackCoordinator.persistentStoreURL.path)[("NSFileSize" as AnyObject) as! FileAttributeKey] as! Int
for i in 0...100000 {
let dandy = Dandy.insert("Dandy")
dandy?.setValue("\(i)", forKey: "dandyID")
}
- Dandy.save({ (error) in
+ Dandy.save(completion: { (error) in
do {
- let savedData = try NSFileManager.defaultManager().attributesOfItemAtPath(PersistentStackCoordinator.persistentStoreURL.path!)["NSFileSize"] as! Int
+ let savedData = try FileManager.default.attributesOfItem(atPath: PersistentStackCoordinator.persistentStoreURL.path)[("NSFileSize" as AnyObject) as! FileAttributeKey] as! Int
XCTAssert(savedData > unsavedData, "Pass")
expectation.fulfill()
} catch {
@@ -79,7 +79,7 @@ class CoreDataDandyTests: XCTestCase {
XCTAssert(false, "Failure to retrieive file attributes.")
expectation.fulfill()
}
- self.waitForExpectationsWithTimeout(20, handler: { (let error) -> Void in })
+ self.waitForExpectations(timeout: 20, handler: { (error) -> Void in })
}
// MARK: - Object insertions, deletions, and fetches -
@@ -120,19 +120,19 @@ class CoreDataDandyTests: XCTestCase {
it alone.
*/
func testUniqueObjectMaintenance() {
- let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE")
+ let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE" as AnyObject)
dandy?.setValue("An author, let's say", forKey: "bio")
- let repeatedDandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE")
+ let repeatedDandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE" as AnyObject)
let dandies = try! Dandy.fetch("Dandy")?.count
- XCTAssert(dandies == 1 && (repeatedDandy!.valueForKey("bio") as! String == "An author, let's say"), "Pass")
+ XCTAssert(dandies == 1 && (repeatedDandy!.value(forKey: "bio") as! String == "An author, let's say"), "Pass")
}
/**
Objects should be fetchable via typical NSPredicate configured NSFetchRequests.
*/
func testPredicateFetch() {
- let wilde = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE")!
- wilde.setValue("An author, let's say", forKey: "bio")
- let byron = Dandy.insertUnique("Dandy", primaryKeyValue: "BYRON")!
+ let wilde = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE" as AnyObject)
+ wilde?.setValue("An author, let's say" as String, forKey: "bio")
+ guard let byron = Dandy.insertUnique("Dandy", primaryKeyValue: "BYRON" as AnyObject) else { return }
byron.setValue("A poet, let's say", forKey: "bio")
let dandies = try! Dandy.fetch("Dandy")?.count
let byrons = try! Dandy.fetch("Dandy", filterBy: NSPredicate(format: "bio == %@", "A poet, let's say"))?.count
@@ -143,52 +143,52 @@ class CoreDataDandyTests: XCTestCase {
resolve correctly..
*/
func testPrimaryKeyTypeConversion() {
- let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: 1)
+ let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: 1 as AnyObject)
dandy?.setValue("A poet, let's say", forKey: "bio")
- let repeatedDandy = Dandy.insertUnique("Dandy", primaryKeyValue: "1")
+ let repeatedDandy = Dandy.insertUnique("Dandy", primaryKeyValue: "1" as AnyObject)
let dandies = try! Dandy.fetch("Dandy")?.count
- XCTAssert(dandies == 1 && (repeatedDandy!.valueForKey("bio") as! String == "A poet, let's say"), "Pass")
+ XCTAssert(dandies == 1 && (repeatedDandy!.value(forKey: "bio") as! String == "A poet, let's say"), "Pass")
}
/**
Mistaken use of a primaryKey identifying function for singleton objects should not lead to unexpected
behavior.
*/
func testSingletonsIgnorePrimaryKey() {
- let space = Dandy.insertUnique("Space", primaryKeyValue: "name")
+ let space = Dandy.insertUnique("Space", primaryKeyValue: "name" as AnyObject)
space?.setValue("The Gogol Empire, let's say", forKey: "name")
- let repeatedSpace = Dandy.insertUnique("Space", primaryKeyValue: "void")
+ let repeatedSpace = Dandy.insertUnique("Space", primaryKeyValue: "void" as AnyObject)
let spaces = try! Dandy.fetch("Space")?.count
- XCTAssert(spaces == 1 && (repeatedSpace!.valueForKey("name") as! String == "The Gogol Empire, let's say"), "Pass")
+ XCTAssert(spaces == 1 && (repeatedSpace!.value(forKey: "name") as! String == "The Gogol Empire, let's say"), "Pass")
}
/**
The convenience function for fetching objects by primary key should return a unique object that has been inserted.
*/
func testUniqueObjectFetch() {
- let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE")
+ let dandy = Dandy.insertUnique("Dandy", primaryKeyValue: "WILDE" as AnyObject)
dandy?.setValue("An author, let's say", forKey: "bio")
- let fetchedDandy = Dandy.fetchUnique("Dandy", primaryKeyValue: "WILDE")!
- XCTAssert((fetchedDandy.valueForKey("bio") as! String == "An author, let's say"), "Pass")
+ let fetchedDandy = Dandy.fetchUnique("Dandy", primaryKeyValue: "WILDE" as AnyObject)!
+ XCTAssert((fetchedDandy.value(forKey: "bio") as! String == "An author, let's say"), "Pass")
}
/**
If a primary key is not specified for an object, the fetch should fail and emit a warning.
*/
func testUnspecifiedPrimaryKeyValueUniqueObjectFetch() {
- let plebian = Dandy.insertUnique("Plebian", primaryKeyValue: "plebianID")
+ let plebian = Dandy.insertUnique("Plebian", primaryKeyValue: "plebianID" as AnyObject)
XCTAssert(plebian == nil, "Pass")
}
/**
A deleted object should not be represented in the database
*/
func testObjectDeletion() {
- let space = Dandy.insertUnique("Space", primaryKeyValue: "name")
+ let space = Dandy.insertUnique("Space", primaryKeyValue: "name" as AnyObject)
let previousSpaceCount = try! Dandy.fetch("Space")?.count
- let expectation = self.expectationWithDescription("Object deletion")
+ let expectation = self.expectation(description: "Object deletion")
Dandy.delete(space!) {
let newSpaceCount = try! Dandy.fetch("Space")?.count
XCTAssert(previousSpaceCount == 1 && newSpaceCount == 0, "Pass")
expectation.fulfill()
}
- self.waitForExpectationsWithTimeout(0.5, handler: { (let error) -> Void in })
+ self.waitForExpectations(timeout: 0.5, handler: { ( error) -> Void in })
}
// MARK: - Persistent Stack -
@@ -205,7 +205,7 @@ class CoreDataDandyTests: XCTestCase {
*/
func testPersistentStackManagerObjectContextConstruction() {
let persistentStackCoordinator = PersistentStackCoordinator(managedObjectModelName: "DandyModel")
- XCTAssert(persistentStackCoordinator.mainContext.parentContext === persistentStackCoordinator.privateContext, "Pass")
+ XCTAssert(persistentStackCoordinator.mainContext.parent === persistentStackCoordinator.privateContext, "Pass")
}
/**
The privateContext should share a reference to the `DandyStackCoordinator's` persistentStoreCoordinator.
@@ -229,13 +229,13 @@ class CoreDataDandyTests: XCTestCase {
When initialization completes, the completion closure should execute.
*/
func testPersistentStackManagerConnectionClosureExectution() {
- let expectation = self.expectationWithDescription("initialization")
+ let expectation = self.expectation(description: "initialization")
let persistentStackCoordinator = PersistentStackCoordinator(managedObjectModelName: "DandyModel", persistentStoreConnectionCompletion: {
XCTAssert(true, "Pass.")
expectation.fulfill()
})
persistentStackCoordinator.connectPrivateContextToPersistentStoreCoordinator()
- self.waitForExpectationsWithTimeout(5, handler: { (let error) -> Void in })
+ self.waitForExpectations(timeout: 5, handler: { ( error) -> Void in })
}
// MARK: - Value conversions -
@@ -243,51 +243,52 @@ class CoreDataDandyTests: XCTestCase {
Conversions to undefined types should not occur
*/
func testUndefinedTypeConversion() {
- let result: AnyObject? = CoreDataValueConverter.convert("For us, life is five minutes of introspection", toType: .UndefinedAttributeType)
+ let result: AnyObject? = CoreDataValueConverter.convert(value: "For us, life is five minutes of introspection" as AnyObject, toType: .undefinedAttributeType)
XCTAssert(result == nil, "Pass")
}
/**
Test non-conforming protocol type conversion
*/
func testNonConformingProtocolTypeConversion() {
- let result: AnyObject? = CoreDataValueConverter.convert(["life", "is", "five", "minutes", "of", "introspection"], toType: .StringAttributeType)
+ let value = ["life", "is", "five", "minutes", "of", "introspection"] as AnyObject
+ let result: AnyObject? = CoreDataValueConverter.convert(value: value , toType: .stringAttributeType)
XCTAssert(result == nil, "Pass")
}
/**
A type convertes to the same type should undergo no changes
*/
func testSameTypeConversion() {
- let string: AnyObject? = CoreDataValueConverter.convert("For us, life is five minutes of introspection", toType: .StringAttributeType)
+ let string: AnyObject? = CoreDataValueConverter.convert(value: "For us, life is five minutes of introspection" as AnyObject, toType: .stringAttributeType)
XCTAssert(string is String, "Pass")
- let number: AnyObject? = CoreDataValueConverter.convert(1, toType: .Integer64AttributeType)
+ let number: AnyObject? = CoreDataValueConverter.convert(value: 1 as AnyObject, toType: .integer64AttributeType)
XCTAssert(number is NSNumber, "Pass")
- let decimal: AnyObject? = CoreDataValueConverter.convert(NSDecimalNumber(integer: 1), toType: .DecimalAttributeType)
+ let decimal: AnyObject? = CoreDataValueConverter.convert(value: NSDecimalNumber(value: 1), toType: .decimalAttributeType)
XCTAssert(decimal is NSDecimalNumber, "Pass")
- let date: AnyObject? = CoreDataValueConverter.convert(NSDate(), toType: .DateAttributeType)
+ let date: AnyObject? = CoreDataValueConverter.convert(value:NSDate(), toType: .dateAttributeType)
XCTAssert(date is NSDate, "Pass")
- let encodedString = "suave".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
- let data: AnyObject? = CoreDataValueConverter.convert(encodedString!, toType: .BinaryDataAttributeType)
+ let encodedString = "suave".data(using: String.Encoding.utf8, allowLossyConversion: true)
+ let data: AnyObject? = CoreDataValueConverter.convert(value: encodedString! as AnyObject, toType: .binaryDataAttributeType)
XCTAssert(data is NSData, "Pass")
}
/**
NSData objects should be convertible to Strings.
*/
func testDataToStringConversion() {
- let expectation: NSString = "testing string"
- let input: NSData? = expectation.dataUsingEncoding(NSUTF8StringEncoding)
- let result = CoreDataValueConverter.convert(input!, toType: .StringAttributeType) as? NSString
+ let expectation: String = "testing string"
+ let input: Data? = expectation.data(using: String.Encoding.utf8)
+ let result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .stringAttributeType) as? String
XCTAssert(result == expectation, "")
}
/**
Numbers should be convertible to Strings.
*/
func testNumberToStringConversion() {
- let input = 123455
- let result = CoreDataValueConverter.convert(input, toType: .StringAttributeType) as? String
+ let input = 123455 as AnyObject
+ let result = CoreDataValueConverter.convert(value: input, toType: .stringAttributeType) as? String
XCTAssert(result == "123455", "")
}
/**
@@ -295,15 +296,15 @@ class CoreDataDandyTests: XCTestCase {
*/
func testNumberToDecimalConversion() {
let expectation = Double(7.070000171661375488)
- let result = CoreDataValueConverter.convert(NSNumber(double: expectation), toType: .DecimalAttributeType) as? NSDecimalNumber
- XCTAssert(result == NSDecimalNumber(double: expectation), "Pass")
+ let result = CoreDataValueConverter.convert(value: NSNumber(value: expectation), toType: .decimalAttributeType) as? NSDecimalNumber
+ XCTAssert(result == NSDecimalNumber(value: expectation), "Pass")
}
/**
Numbers should be convertible to Doubles
*/
func testNumberToDoubleConversion() {
let expectation = Double(7.07)
- let result = CoreDataValueConverter.convert(NSNumber(double: expectation), toType: .DoubleAttributeType) as? Double
+ let result = CoreDataValueConverter.convert(value: NSNumber(value: expectation), toType: .doubleAttributeType) as? Double
XCTAssert(result == expectation, "Pass")
}
/**
@@ -311,25 +312,25 @@ class CoreDataDandyTests: XCTestCase {
*/
func testNumberToFloatConversion() {
let expectation = Float(7.07)
- let result = CoreDataValueConverter.convert(NSNumber(float: expectation), toType: .FloatAttributeType) as? Float
+ let result = CoreDataValueConverter.convert(value: NSNumber(value: expectation), toType: .floatAttributeType) as? Float
XCTAssert(result == expectation, "Pass")
}
/**
Numbers should be convertible to NSData
*/
func testNumberToDataConversion() {
- let input = NSNumber(float: 7.07)
- let expectation = NSNumber(float: 7.07).stringValue.dataUsingEncoding(NSUTF8StringEncoding)
- let result = CoreDataValueConverter.convert(input, toType: .BinaryDataAttributeType) as? NSData
+ let input = NSNumber(value: 7.07)
+ let expectation = NSNumber(value: 7.07).stringValue.data(using: String.Encoding.utf8)
+ let result = CoreDataValueConverter.convert(value: input, toType: .binaryDataAttributeType) as? Data
XCTAssert(result == expectation, "Pass")
}
/**
Numbers should be convertible to NSDates.
*/
func testNumberToDateConversion() {
- let now = NSDate()
+ let now = Date()
let expectation = Double(now.timeIntervalSince1970)
- let result = CoreDataValueConverter.convert(expectation, toType: .DateAttributeType) as? NSDate
+ let result = CoreDataValueConverter.convert(value: expectation as AnyObject, toType: .dateAttributeType) as? Date
let resultAsDouble = Double(result!.timeIntervalSince1970)
XCTAssert(resultAsDouble == expectation, "")
}
@@ -338,64 +339,67 @@ class CoreDataDandyTests: XCTestCase {
*/
func testNumberToBooleanConversion() {
var input = -1
- var result = CoreDataValueConverter.convert(input, toType: .BooleanAttributeType) as? NSNumber
+ var result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == nil, "")
input = 1
- result = CoreDataValueConverter.convert(input, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == true, "")
input = 0
- result = CoreDataValueConverter.convert(input, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == false, "")
input = 99
- result = CoreDataValueConverter.convert(input, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result == true, "Pass")
}
/**
NSDates should be convertible to Strings.
*/
func testDateToStringConversion() {
- let now = NSDate()
- let expectation = CoreDataValueConverter.dateFormatter.stringFromDate(now)
- let result = CoreDataValueConverter.convert(now, toType: .StringAttributeType) as? String
+ let now = Date()
+ let expectation = CoreDataValueConverter.dateFormatter.string(from: now)
+ let result = CoreDataValueConverter.convert(value: now as AnyObject, toType: .stringAttributeType) as? String
XCTAssert(result == expectation, "")
}
/**
NSDates should be convertible to Decimals.
*/
func testDateToDecimalConversion() {
- let now = NSDate()
- let expectation = NSDecimalNumber(double: now.timeIntervalSinceDate(NSDate(timeIntervalSince1970: 0)))
- let result = CoreDataValueConverter.convert(now, toType: .DecimalAttributeType) as! NSDecimalNumber
+ let now = Date()
+ let timeIntervalSinceDouble = Double(now.timeIntervalSince(Date(timeIntervalSince1970: 0)))
+ let expectation = NSDecimalNumber(value: timeIntervalSinceDouble)
+ let result = CoreDataValueConverter.convert(value: now as AnyObject, toType: .decimalAttributeType) as! NSDecimalNumber
XCTAssert(result.floatValue - expectation.floatValue < 5, "")
}
/**
NSDates should be convertible to Doubles.
*/
func testDateToDoubleConversion() {
- let now = NSDate()
- let expectation = NSNumber(double: now.timeIntervalSinceDate(NSDate(timeIntervalSince1970: 0)))
- let result = CoreDataValueConverter.convert(now, toType: .DoubleAttributeType) as! NSNumber
+ let now = Date()
+ let expectation = NSNumber(value: now.timeIntervalSince(Date(timeIntervalSince1970: 0)))
+ let result = CoreDataValueConverter.convert(value: now as AnyObject, toType: .doubleAttributeType) as! NSNumber
XCTAssert(result.floatValue - expectation.floatValue < 5, "")
}
/**
NSDates should be convertible to Floats.
*/
func testDateToFloatConversion() {
- let now = NSDate()
- let expectation = NSNumber(float: Float(now.timeIntervalSinceDate(NSDate(timeIntervalSince1970: 0))))
- let result = CoreDataValueConverter.convert(now, toType: .FloatAttributeType) as! NSNumber
+ let now = Date()
+ let timeIntervalFloat = Float(now.timeIntervalSince(Date(timeIntervalSince1970: 0)))
+ let expectation = NSNumber(value: timeIntervalFloat)
+ let result = CoreDataValueConverter.convert(value: now as AnyObject, toType: .floatAttributeType) as! NSNumber
XCTAssert(result.floatValue - expectation.floatValue < 5, "")
}
/**
NSDates should be convertible to Ints.
*/
func testDateToIntConversion() {
- let now = NSDate()
- let expectation = NSNumber(integer: Int(now.timeIntervalSinceDate(NSDate(timeIntervalSince1970: 0))))
- let result = CoreDataValueConverter.convert(now, toType: .Integer32AttributeType) as! NSNumber
+ let now = Date()
+ let timeIntervalInteger = Int(now.timeIntervalSince(Date(timeIntervalSince1970: 0)))
+ let expectation = NSNumber(value: timeIntervalInteger)
+ let result = CoreDataValueConverter.convert(value: now as AnyObject, toType: .integer32AttributeType) as! NSNumber
XCTAssert(result.floatValue - expectation.floatValue < 5, "")
}
/**
@@ -405,32 +409,32 @@ class CoreDataDandyTests: XCTestCase {
var testString = "Yes"
var result: NSNumber?
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == true, "")
testString = "trUe"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == true, "")
testString = "1"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == true, "")
testString = "NO"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == false, "")
testString = "false"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == false, "")
testString = "0"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result?.boolValue == false, "")
testString = "undefined"
- result = CoreDataValueConverter.convert(testString, toType: .BooleanAttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: testString as AnyObject, toType: .booleanAttributeType) as? NSNumber
XCTAssert(result == nil, "")
}
/**
@@ -438,23 +442,23 @@ class CoreDataDandyTests: XCTestCase {
*/
func testStringToIntConversion() {
var input = "123"
- var result = CoreDataValueConverter.convert(input, toType: .Integer64AttributeType) as? NSNumber
+ var result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .integer64AttributeType)
XCTAssert(result?.integerValue == 123, "")
input = "456wordsdontmatter123"
- result = CoreDataValueConverter.convert(input, toType: .Integer64AttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .integer64AttributeType) as? NSNumber
XCTAssert(result?.integerValue == 456, "")
input = "nothingHereMatters"
- result = CoreDataValueConverter.convert(input, toType: .Integer64AttributeType) as? NSNumber
+ result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .integer64AttributeType) as? NSNumber
XCTAssert(result?.integerValue == 0, "")
}
/**
NSStrings should be convertible to NSDecimalNumbers
*/
func testStringToDecimalConversion() {
- let expectation = NSDecimalNumber(float: 7.070000171661375488)
- let result = CoreDataValueConverter.convert("7.070000171661375488", toType: .DecimalAttributeType) as? NSDecimalNumber
+ let expectation = NSDecimalNumber(floatLiteral: 7.070000171661375488)
+ let result = CoreDataValueConverter.convert(value:"7.070000171661375488" as AnyObject, toType: .decimalAttributeType) as? NSDecimalNumber
XCTAssert(result == expectation, "Pass")
}
/**
@@ -462,7 +466,7 @@ class CoreDataDandyTests: XCTestCase {
*/
func testStringToDoubleConversion() {
let expectation = Double(7.07)
- let result = CoreDataValueConverter.convert("7.07", toType: .DoubleAttributeType) as? Double
+ let result = CoreDataValueConverter.convert(value: "7.07" as AnyObject, toType: .doubleAttributeType) as? Double
XCTAssert(result == expectation, "Pass")
}
/**
@@ -470,7 +474,7 @@ class CoreDataDandyTests: XCTestCase {
*/
func testStringToFloatConversion() {
let expectation = Float(7.07)
- let result = CoreDataValueConverter.convert("7.07", toType: .FloatAttributeType) as? Float
+ let result = CoreDataValueConverter.convert(value:"7.07" as AnyObject, toType: .floatAttributeType) as? Float
XCTAssert(result == expectation, "Pass")
}
/**
@@ -478,30 +482,32 @@ class CoreDataDandyTests: XCTestCase {
*/
func testStringToDataConversion() {
let input = "Long long Time ago"
- let expectedResult = input.dataUsingEncoding(NSUTF8StringEncoding)!
- let result = CoreDataValueConverter.convert(input, toType: .BinaryDataAttributeType) as? NSData
- XCTAssert(result!.isEqualToData(expectedResult) == true, "")
+ let expectedResult = input.data(using: String.Encoding.utf8)
+ let result = CoreDataValueConverter.convert(value: input as AnyObject, toType: .binaryDataAttributeType)
+ if let result = result {
+ XCTAssert(result.isEqual(expectedResult!) == true, "")
+ }
}
/**
Strings should be convertible to NSDates.
*/
func testStringToDateConversion() {
- let now = NSDate()
- let nowAsString = CoreDataValueConverter.dateFormatter.stringFromDate(now)
- let result = CoreDataValueConverter.convert(nowAsString, toType: .DateAttributeType) as? NSDate
- let resultAsString = CoreDataValueConverter.dateFormatter.stringFromDate(result!)
+ let now = Date()
+ let nowAsString = CoreDataValueConverter.dateFormatter.string(from: now)
+ let result: Date = CoreDataValueConverter.convert(value: nowAsString as AnyObject, toType: .dateAttributeType) as! Date
+ let resultAsString = CoreDataValueConverter.dateFormatter.string(from: result)
XCTAssert(resultAsString == nowAsString, "")
}
// MARK: - Mapping -
func testEntityDescriptionFromString() {
- let expected = NSEntityDescription.entityForName("Dandy", inManagedObjectContext: Dandy.coordinator.mainContext)
- let result = NSEntityDescription.forEntity("Dandy")!
+ let expected = NSEntityDescription.entity(forEntityName: "Dandy", in: Dandy.coordinator.mainContext)
+ let result = NSEntityDescription.forEntity(name: "Dandy")!
XCTAssert(expected == result, "Pass")
}
func testPrimaryKeyIdentification() {
let expected = "dandyID"
- let dandy = NSEntityDescription.forEntity("Dandy")!
+ let dandy = NSEntityDescription.forEntity(name: "Dandy")!
let result = dandy.primaryKey!
XCTAssert(expected == result, "Pass")
}
@@ -540,7 +546,7 @@ class CoreDataDandyTests: XCTestCase {
contain a value from its parent, Gossip.
*/
func testUserInfoHierarchyCollection() {
- let slanderDescription = NSEntityDescription.forEntity("Slander")!
+ let slanderDescription = NSEntityDescription.forEntity(name: "Slander")!
let userInfo = slanderDescription.allUserInfo!
XCTAssert((userInfo["testValue"] as! String) == "testKey", "Pass")
}
@@ -549,7 +555,7 @@ class CoreDataDandyTests: XCTestCase {
override its parent's, Gossip.
*/
func testUserInfoOverride() {
- let slanderDescription = NSEntityDescription.forEntity("Slander")!
+ let slanderDescription = NSEntityDescription.forEntity(name: "Slander")!
let userInfo = slanderDescription.allUserInfo!
XCTAssert((userInfo[PRIMARY_KEY] as! String) == "statement", "Pass")
}
@@ -557,13 +563,13 @@ class CoreDataDandyTests: XCTestCase {
Entity descriptions with no specified mapping should read into mapping dictionaries with all "same name" mapping
*/
func testSameNameMap() {
- let entity = NSEntityDescription.forEntity("Material")!
+ let entity = NSEntityDescription.forEntity(name: "Material")!
let expectedMap = [
"name": PropertyDescription(description: entity.allAttributes!["name"]!),
"origin": PropertyDescription(description: entity.allAttributes!["origin"]!),
"hats": PropertyDescription(description: entity.allRelationships!["hats"]!)
]
- let result = EntityMapper.map(entity)
+ let result = EntityMapper.map(entity: entity)
XCTAssert(result! == expectedMap, "Pass")
}
/**
@@ -571,14 +577,14 @@ class CoreDataDandyTests: XCTestCase {
as such.
*/
func testNOMappingKeywordResponse() {
- let entity = NSEntityDescription.forEntity("Gossip")!
+ let entity = NSEntityDescription.forEntity(name: "Gossip")!
let expectedMap = [
"details": PropertyDescription(description: entity.allAttributes!["details"]!),
"topic": PropertyDescription(description: entity.allAttributes!["topic"]!),
// "secret": "unmapped"
"purveyor": PropertyDescription(description: entity.allRelationships!["purveyor"]!)
]
- let result = EntityMapper.map(entity)!
+ let result = EntityMapper.map(entity: entity)!
XCTAssert(result == expectedMap, "Pass")
}
/**
@@ -586,12 +592,12 @@ class CoreDataDandyTests: XCTestCase {
to map from "state."
*/
func testAlternateKeypathMappingResponse() {
- let entity = NSEntityDescription.forEntity("Space")!
+ let entity = NSEntityDescription.forEntity(name: "Space")!
let expectedMap = [
"name": PropertyDescription(description: entity.allAttributes!["name"]!),
"state": PropertyDescription(description: entity.allAttributes!["spaceState"]!)
]
- let result = EntityMapper.map(entity)!
+ let result = EntityMapper.map(entity: entity)!
XCTAssert(result == expectedMap, "Pass")
}
@@ -600,10 +606,10 @@ class CoreDataDandyTests: XCTestCase {
Comparisons of property descriptions should evaluate correctly.
*/
func testPropertyDescriptionComparison() {
- let entity = NSEntityDescription.forEntity("Space")!
- let name = PropertyDescription(description: entity.allAttributes!["name"]!)
- let secondName = PropertyDescription(description: entity.allAttributes!["name"]!)
- let state = PropertyDescription(description: entity.allAttributes!["spaceState"]!)
+ let entity = NSEntityDescription.forEntity(name: "Space")!
+ let name = PropertyDescription(description: entity.allAttributes!["name"]!).name
+ let secondName = PropertyDescription(description: entity.allAttributes!["name"]!).name
+ let state = PropertyDescription(description: entity.allAttributes!["spaceState"]!).name
XCTAssert(name == secondName, "Pass")
XCTAssert(name != state, "Pass")
XCTAssert(name != "STRING", "Pass")
@@ -614,14 +620,20 @@ class CoreDataDandyTests: XCTestCase {
func testPropertyDescriptionInitialization() {
let _ = PropertyDescription()
- let entity = NSEntityDescription.forEntity("Space")!
+ let path = PersistentStackCoordinator.applicationDocumentsDirectory.relativePath
+ let entity = NSEntityDescription.forEntity(name: "Space")!
let propertyDescription = PropertyDescription(description: entity.allAttributes!["name"]!)
- let pathArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
- let documentPath = pathArray.first!
- let archivePath = NSString(string: documentPath).stringByAppendingPathComponent("SPACE_NAME")
- NSKeyedArchiver.archiveRootObject(propertyDescription, toFile: archivePath)
- let unarchivedPropertyDescription = NSKeyedUnarchiver.unarchiveObjectWithFile(archivePath) as! PropertyDescription
- XCTAssert(unarchivedPropertyDescription == propertyDescription, "Pass")
+ let archivePath = path + "/SPACE_NAME"
+
+ let data = NSKeyedArchiver.archivedData(withRootObject: propertyDescription)
+ let didCreateFile = FileManager.default.createFile(atPath: archivePath, contents: data, attributes: [:])
+
+ if let data = FileManager.default.contents(atPath: archivePath) {
+ if let unarchivedPropertyDescription = NSKeyedUnarchiver.unarchiveObject(with: data) as? PropertyDescription {
+ print(unarchivedPropertyDescription)
+ XCTAssert(unarchivedPropertyDescription == propertyDescription, "Pass")
+ }
+ }
}
// MARK: - Map caching -
@@ -630,8 +642,8 @@ class CoreDataDandyTests: XCTestCase {
*/
func testMapCaching() {
let entityName = "Material"
- if let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: Dandy.coordinator.mainContext) {
- EntityMapper.map(entityDescription)
+ if let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: Dandy.coordinator.mainContext) {
+ EntityMapper.map(entity: entityDescription)
let entityCacheMap = EntityMapper.cachedEntityMap[entityName]!
XCTAssert(entityCacheMap.count > 0, "")
}
@@ -641,8 +653,8 @@ class CoreDataDandyTests: XCTestCase {
*/
func testMapCacheCleanUp() {
let entityName = "Material"
- if let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: Dandy.coordinator.mainContext) {
- EntityMapper.map(entityDescription)
+ if let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: Dandy.coordinator.mainContext) {
+ EntityMapper.map(entity: entityDescription)
let initialCacheCount = EntityMapper.cachedEntityMap.count
EntityMapper.clearCache()
let finalCacheCount = EntityMapper.cachedEntityMap.count
@@ -653,19 +665,19 @@ class CoreDataDandyTests: XCTestCase {
The creation of a new map should be performant
*/
func testPerformanceOfNewMapCreation() {
- self.measureBlock {
- let entityDescription = NSEntityDescription.entityForName("Material", inManagedObjectContext: Dandy.coordinator.mainContext)
- EntityMapper.map(entityDescription!)
+ self.measure {
+ let entityDescription = NSEntityDescription.entity(forEntityName: "Material", in: Dandy.coordinator.mainContext)
+ EntityMapper.map(entity: entityDescription!)
}
}
/**
The fetching of a cached map should be performant, and more performant than the creation of a new map
*/
func testPerformanceOfCachedMapRetrieval() {
- let entityDescription = NSEntityDescription.entityForName("Material", inManagedObjectContext: Dandy.coordinator.mainContext)!
- EntityMapper.map(entityDescription)
- self.measureBlock {
- EntityMapper.map(entityDescription)
+ let entityDescription = NSEntityDescription.entity(forEntityName: "Material", in: Dandy.coordinator.mainContext)!
+ EntityMapper.map(entity: entityDescription)
+ self.measure {
+ EntityMapper.map(entity: entityDescription)
}
}
@@ -676,9 +688,9 @@ class CoreDataDandyTests: XCTestCase {
func testAttributeBuilding() {
let space = Dandy.insert("Space")!
let json = ["name": "nebulous", "state": "moderately cool"]
- ObjectFactory.build(space, from: json)
- XCTAssert(space.valueForKey("name") as! String == "nebulous" &&
- space.valueForKey("spaceState") as! String == "moderately cool",
+ ObjectFactory.build(object: space, from: json as [String : AnyObject])
+ XCTAssert(space.value(forKey: "name") as! String == "nebulous" &&
+ space.value(forKey: "spaceState") as! String == "moderately cool",
"Pass")
}
/**
@@ -693,13 +705,13 @@ class CoreDataDandyTests: XCTestCase {
"id": 1,
"name": "Lord Byron",
]
- ]
- ObjectFactory.build(gossip, from: json)
- let byron = gossip.valueForKey("purveyor") as! NSManagedObject
- XCTAssert(gossip.valueForKey("details") as! String == "At Bo Peep, unusually cool towards Isabella Brown." &&
- gossip.valueForKey("topic") as! String == "John Keats" &&
- byron.valueForKey("dandyID") as! String == "1" &&
- byron.valueForKey("name") as! String == "Lord Byron",
+ ] as [String : Any]
+ ObjectFactory.build(object: gossip, from: json as [String : AnyObject])
+ let byron = gossip.value(forKey: "purveyor") as! NSManagedObject
+ XCTAssert(gossip.value(forKey: "details") as! String == "At Bo Peep, unusually cool towards Isabella Brown." &&
+ gossip.value(forKey: "topic") as! String == "John Keats" &&
+ byron.value(forKey: "dandyID") as! String == "1" &&
+ byron.value(forKey: "name") as! String == "Lord Byron",
"Pass")
}
/**
@@ -722,19 +734,19 @@ class CoreDataDandyTests: XCTestCase {
]
]]
]
- ]
- ObjectFactory.build(gossip, from: json)
- let byron = gossip.valueForKey("purveyor") as! NSManagedObject
- let bowler = byron.valueForKey("hats")!.anyObject() as! NSManagedObject
- let felt = bowler.valueForKey("primaryMaterial") as! NSManagedObject
- XCTAssert(gossip.valueForKey("details") as! String == "At Bo Peep, unusually cool towards Isabella Brown." &&
- gossip.valueForKey("topic") as! String == "John Keats" &&
- byron.valueForKey("dandyID") as! String == "1" &&
- byron.valueForKey("name") as! String == "Lord Byron" &&
- bowler.valueForKey("name") as! String == "bowler" &&
- bowler.valueForKey("styleDescription") as! String == "billycock" &&
- felt.valueForKey("name") as! String == "felt" &&
- felt.valueForKey("origin") as! String == "Rome",
+ ] as [String : Any]
+ ObjectFactory.build(object: gossip, from: json as [String : AnyObject])
+ let byron = gossip.value(forKey: "purveyor") as! NSManagedObject
+ let bowler = (byron.value(forKey: "hats")! as AnyObject).anyObject() as! NSManagedObject
+ let felt = bowler.value(forKey: "primaryMaterial") as! NSManagedObject
+ XCTAssert(gossip.value(forKey: "details") as! String == "At Bo Peep, unusually cool towards Isabella Brown." &&
+ gossip.value(forKey: "topic") as! String == "John Keats" &&
+ byron.value(forKey: "dandyID") as! String == "1" &&
+ byron.value(forKey: "name") as! String == "Lord Byron" &&
+ bowler.value(forKey: "name") as! String == "bowler" &&
+ bowler.value(forKey: "styleDescription") as! String == "billycock" &&
+ felt.value(forKey: "name") as! String == "felt" &&
+ felt.value(forKey: "origin") as! String == "Rome",
"Pass")
}
/**
@@ -751,11 +763,11 @@ class CoreDataDandyTests: XCTestCase {
]
]
] as [String: AnyObject]
- ObjectFactory.build(dandy, from: json)
- let balzac = dandy.valueForKey("predecessor") as! NSManagedObject
- XCTAssert(balzac.valueForKey("dandyID") as! String == "BALZ" &&
- balzac.valueForKey("name") as! String == "Honoré de Balzac" &&
- (balzac.valueForKey("successor") as! NSManagedObject).valueForKey("dandyID") as! String == dandy.valueForKey("dandyID") as! String,
+ ObjectFactory.build(object: dandy, from: json)
+ let balzac = dandy.value(forKey: "predecessor") as! NSManagedObject
+ XCTAssert(balzac.value(forKey: "dandyID") as! String == "BALZ" &&
+ balzac.value(forKey: "name") as! String == "Honoré de Balzac" &&
+ (balzac.value(forKey: "successor") as! NSManagedObject).value(forKey: "dandyID") as! String == dandy.value(forKey: "dandyID") as! String,
"Pass")
}
/**
@@ -764,9 +776,9 @@ class CoreDataDandyTests: XCTestCase {
func testIgnoreUnkeyedAttributesWhenBuilding() {
let space = Dandy.insert("Space")!
space.setValue("exceptionally relaxed", forKey: "spaceState")
- let json = ["name": "nebulous"]
- ObjectFactory.build(space, from: json)
- XCTAssert(space.valueForKey("spaceState") as! String == "exceptionally relaxed", "Pass")
+ let json = ["name": "nebulous"] as [String : AnyObject]
+ ObjectFactory.build(object: space, from: json)
+ XCTAssert(space.value(forKey: "spaceState") as! String == "exceptionally relaxed", "Pass")
}
/**
Property values on an object should be overwritten if new values are specified.
@@ -775,8 +787,8 @@ class CoreDataDandyTests: XCTestCase {
let space = Dandy.insert("Space")!
space.setValue("exceptionally relaxed", forKey: "spaceState")
let json = ["state": "significant excitement"]
- ObjectFactory.build(space, from: json)
- XCTAssert(space.valueForKey("spaceState") as! String == "significant excitement", "Pass")
+ ObjectFactory.build(object: space, from: json as [String : AnyObject])
+ XCTAssert(space.value(forKey: "spaceState") as! String == "significant excitement", "Pass")
}
/**
If a single json object is passed when attempting to build a toMany relationship, it should be
@@ -791,9 +803,9 @@ class CoreDataDandyTests: XCTestCase {
"name": "felt",
"origin": "Rome"
]
- ]
- ObjectFactory.make(PropertyDescription(description: dandy.entity.allRelationships!["hats"]!), to: dandy, from: json)
- XCTAssert((dandy.valueForKey("hats") as! NSSet).count == 0, "Pass")
+ ] as [String: AnyObject]
+ ObjectFactory.make(relationship: PropertyDescription(description: dandy.entity.allRelationships!["hats"]! as AnyObject), to: dandy, from: json as AnyObject)
+ XCTAssert((dandy.value(forKey: "hats") as! NSSet).count == 0, "Pass")
}
/**
If a json array is passed when attempting to build a toOne relationship, it should be
@@ -812,8 +824,8 @@ class CoreDataDandyTests: XCTestCase {
"id": "3",
"name": "Andre 3000"]
]
- ObjectFactory.make(PropertyDescription(description: gossip.entity.allRelationships!["purveyor"]!), to: gossip, from: json)
- XCTAssert(gossip.valueForKey("purveyor") == nil, "Pass")
+ ObjectFactory.make(relationship: PropertyDescription(description: gossip.entity.allRelationships!["purveyor"]!), to: gossip, from: json as AnyObject)
+ XCTAssert(gossip.value(forKey: "purveyor") == nil, "Pass")
}
/**
NSOrderedSets should be created for ordered relationships. NSSets should be created for
@@ -832,8 +844,9 @@ class CoreDataDandyTests: XCTestCase {
"id": "3",
"name": "Andre 3000"]
]
- ObjectFactory.make(PropertyDescription(description: hat.entity.allRelationships!["dandies"]!), to: hat, from: json)
- XCTAssert(hat.valueForKey("dandies") is NSOrderedSet && (hat.valueForKey("dandies") as! NSOrderedSet).count == 3, "Pass")
+ let relationship = PropertyDescription(description: hat.entity.allRelationships!["dandies"]!)
+ ObjectFactory.make(relationship: relationship, to: hat, from: json as AnyObject)
+ XCTAssert(hat.value(forKey: "dandies") is NSOrderedSet && (hat.value(forKey: "dandies") as! NSOrderedSet).count == 3, "Pass")
}
// MARK: - Object factory via CoreDataDandy -
@@ -842,8 +855,8 @@ class CoreDataDandyTests: XCTestCase {
*/
func testSimpleObjectConstructionFromJSON() {
let json = ["name": "Passerby"]
- let plebian = Dandy.upsert("Plebian", from: json)!
- XCTAssert(plebian.valueForKey("name") as! String == "Passerby")
+ let plebian = Dandy.upsert("Plebian", from: json as [String : AnyObject])!
+ XCTAssert(plebian.value(forKey: "name") as! String == "Passerby")
}
/**
json lacking a primary key should be rejected. A nil value should be returned and a warning
@@ -851,7 +864,7 @@ class CoreDataDandyTests: XCTestCase {
*/
func testUniqueObjectConstructionFromJSON() {
let json = ["name": "Lord Byron"]
- let byron = Dandy.upsert("Dandy", from: json)
+ let byron = Dandy.upsert("Dandy", from: json as [String : AnyObject])
XCTAssert(byron == nil, "Pass")
}
@@ -860,8 +873,8 @@ class CoreDataDandyTests: XCTestCase {
emitted.
*/
func testRejectionOfJSONWithoutPrimaryKeyForUniqueObject() {
- let json = ["name": "Lord Byron"]
- let byron = Dandy.upsert("Dandy", from: json)
+ let json: [String: String] = ["name": "Lord Byron"]
+ let byron = Dandy.upsert("Dandy", from: json as [String : AnyObject])
XCTAssert(byron == nil, "Pass")
}
@@ -871,13 +884,14 @@ class CoreDataDandyTests: XCTestCase {
func testObjectArrayConstruction() {
var json = [[String: AnyObject]]()
for i in 0...9 {
- json.append(["id": String(i), "name": "Morty"])
+ // TODO: Stavro - check this
+ json.append(["id": String(i) as AnyObject, "name": "Morty" as AnyObject])
}
let dandies = Dandy.batchUpsert("Dandy", from: json)!
let countIsCorrect = dandies.count == 10
var dandiesAreCorrect = true
for i in 0...9 {
- let matchingDandies = (dandies.filter{$0.valueForKey("dandyID")! as! String == String(i)})
+ let matchingDandies = (dandies.filter{$0.value(forKey: "dandyID")! as! String == String(i)})
if matchingDandies.count != 1 {
dandiesAreCorrect = false
break
@@ -898,7 +912,7 @@ class CoreDataDandyTests: XCTestCase {
"id": "1",
"content": input
]
- let conclusion = ObjectFactory.make(NSEntityDescription.forEntity("Conclusion")!, from: json) as! Conclusion
+ let conclusion: Conclusion = ObjectFactory.make(entity: NSEntityDescription.forEntity(name: "Conclusion")!, from: json as [String : AnyObject]) as! Conclusion
XCTAssert(conclusion.content == expected, "Pass")
}
@@ -914,7 +928,7 @@ class CoreDataDandyTests: XCTestCase {
"name": "bowler",
"style": "billycock"
]
- let result = Serializer.serialize(hat) as! [String: String]
+ let result = Serializer.serialize(object: hat) as! [String: String]
XCTAssert(result == expected, "Pass")
}
/**
@@ -925,7 +939,7 @@ class CoreDataDandyTests: XCTestCase {
hat.setValue("bowler", forKey: "name")
hat.setValue(nil, forKey: "styleDescription")
let expected = ["name": "bowler"]
- let result = Serializer.serialize(hat) as! [String: String]
+ let result = Serializer.serialize(object: hat) as! [String: String]
XCTAssert(result == expected, "Pass")
}
/**
@@ -959,11 +973,14 @@ class CoreDataDandyTests: XCTestCase {
func testToOneRelationshipSerialization() {
let hat = Dandy.insert("Hat")!
hat.setValue("bowler", forKey: "name")
- hat.setValue("billycock", forKey: "styleDescription")
+ hat.setValue("billycock", forKey: "styleDescription")
+
let felt = Dandy.insert("Material")!
felt.setValue("felt", forKey: "name")
felt.setValue("Rome", forKey: "origin")
+
hat.setValue(felt, forKey: "primaryMaterial")
+
let expected = [
"name": "bowler",
"style": "billycock",
@@ -971,9 +988,10 @@ class CoreDataDandyTests: XCTestCase {
"name": "felt",
"origin": "Rome"
]
- ]
- let result = Serializer.serialize(hat, including:["primaryMaterial"])!
- XCTAssert(json(result, isEqualJSON: expected), "Pass")
+ ] as [String: Any]
+ let result = Serializer.serialize(object: hat, including:["primaryMaterial"])!
+
+ XCTAssert(json(lhs: result, isEqualJSON: expected), "Pass")
}
/**
An array of NSManagedObject should be serializable into json.
@@ -982,12 +1000,15 @@ class CoreDataDandyTests: XCTestCase {
let byron = Dandy.insert("Dandy")!
byron.setValue("Lord Byron", forKey: "name")
byron.setValue("1", forKey: "dandyID")
+
let wilde = Dandy.insert("Dandy")!
wilde.setValue("Oscar Wilde", forKey: "name")
wilde.setValue("2", forKey: "dandyID")
+
let andre = Dandy.insert("Dandy")!
andre.setValue("Andre 3000", forKey: "name")
andre.setValue("3", forKey: "dandyID")
+
let expected = [
[
"id": "1",
@@ -999,7 +1020,7 @@ class CoreDataDandyTests: XCTestCase {
"id": "3",
"name": "Andre 3000"]
]
- let result = Serializer.serialize([byron, wilde, andre])!
+ let result = Serializer.serialize(objects: [byron, wilde, andre])! as? [[String: String]]
XCTAssert(result == expected, "Pass")
}
/**
@@ -1009,13 +1030,17 @@ class CoreDataDandyTests: XCTestCase {
let byron = Dandy.insert("Dandy")!
byron.setValue("Lord Byron", forKey: "name")
byron.setValue("1", forKey: "dandyID")
+
let bowler = Dandy.insert("Hat")!
bowler.setValue("bowler", forKey: "name")
bowler.setValue("billycock", forKey: "styleDescription")
+
let tyrolean = Dandy.insert("Hat")!
tyrolean.setValue("tyrolean", forKey: "name")
tyrolean.setValue("alpine", forKey: "styleDescription")
+
byron.setValue(NSSet(objects: bowler, tyrolean), forKey: "hats")
+
let expected = [
"id": "1",
"name": "Lord Byron",
@@ -1025,10 +1050,11 @@ class CoreDataDandyTests: XCTestCase {
["name": "tyrolean",
"style": "alpine"]
]
- ]
- var result = Serializer.serialize(byron, including:["hats"])!
- result["hats"] = (result["hats"] as! NSArray).sortedArrayUsingDescriptors([NSSortDescriptor(key: "name", ascending: true)])
- XCTAssert(json(result, isEqualJSON:expected), "Pass")
+ ] as [String: AnyObject]
+ var result = Serializer.serialize(object: byron, including:["hats"])!
+ let descriptors = [NSSortDescriptor(key: "name", ascending: true)]
+ result["hats"] = (result["hats"] as? NSArray)?.sortedArray(using: descriptors) as AnyObject
+ XCTAssert(json(lhs: result, isEqualJSON:expected), "Pass")
}
/**
An object's attributes and relationship tree should be serializaable into json.
@@ -1037,14 +1063,17 @@ class CoreDataDandyTests: XCTestCase {
let gossip = Dandy.insert("Gossip")!
gossip.setValue("At Bo Peep, unusually cool towards Isabella Brown.", forKey: "details")
gossip.setValue("John Keats", forKey: "topic")
+
let byron = Dandy.insert("Dandy")!
byron.setValue("Lord Byron", forKey: "name")
byron.setValue("1", forKey: "dandyID")
+
let bowler = Dandy.insert("Hat")!
bowler.setValue("bowler", forKey: "name")
bowler.setValue("billycock", forKey: "styleDescription")
byron.setValue(NSSet(object: bowler), forKey: "hats")
gossip.setValue(byron, forKey: "purveyor")
+
let expected = [
"details": "At Bo Peep, unusually cool towards Isabella Brown.",
"topic": "John Keats",
@@ -1056,11 +1085,13 @@ class CoreDataDandyTests: XCTestCase {
"style": "billycock",
]]
]
- ]
- let result = Serializer.serialize(gossip, including: ["purveyor.hats"]) as! [String: NSObject]
+ ] as [String: AnyObject]
+ let result = Serializer.serialize(object: gossip, including: ["purveyor.hats"]) as! [String: AnyObject]
+
XCTAssert(result == expected, "Pass")
}
+
// MARK: - Extension tests -
/**
Entries from one dictionary should add correctly to another dictionary of the same type
@@ -1068,22 +1099,22 @@ class CoreDataDandyTests: XCTestCase {
func testDictionaryEntryAddition() {
var balzac = ["name": "Honoré de Balzac"]
let profession = ["profession": "author"]
- balzac.addEntriesFrom(profession)
+ balzac.addEntriesFrom(dictionary: profession)
XCTAssert(balzac["name"] == "Honoré de Balzac" && balzac["profession"] == "author", "Pass")
}
/**
Values in a dictionary should be accessible via keypath
*/
func testValueForKeyPathExtraction() {
- let hats = [[
+ let hats = [
"name": "bowler",
"style": "billycock",
"material": [
"name": "felt",
"origin": "Rome"
]
- ]]
-
+ ] as [String: AnyObject]
+
let gossip = [
"details": "At Bo Peep, unusually cool towards Isabella Brown.",
"topic": "John Keats",
@@ -1092,8 +1123,8 @@ class CoreDataDandyTests: XCTestCase {
"name": "Lord Byron",
"hats": hats
]
- ]
- let value = valueAt("purveyor.hats", of: gossip) as! [[String: AnyObject]]
+ ] as [String: AnyObject]
+ let value = valueAt(keypath: "purveyor.hats", of: gossip) as! [String: AnyObject]
XCTAssert(value == hats, "Pass")
}
@@ -1110,7 +1141,7 @@ class CoreDataDandyTests: XCTestCase {
XCTAssert(log == "(CoreDataDandy) warning: " + warning + " Error:\n" + error.description, "Pass")
}
- func json(lhs: [String: AnyObject], isEqualJSON rhs: [String: AnyObject]) -> Bool {
+ func json(lhs: [String: Any], isEqualJSON rhs: [String: Any]) -> Bool {
// Dictionaries of unequal counts are not equal
if lhs.count != rhs.count { return false }
// Dictionaries that are equal must share all keys and paired values
@@ -1132,4 +1163,4 @@ class CoreDataDandyTests: XCTestCase {
}
return true
}
-}
\ No newline at end of file
+}