From 78b9f8b8e12be68d6ad75a5b9bb66dbedd835a7b Mon Sep 17 00:00:00 2001 From: Elvis Nunez Date: Sun, 7 Mar 2021 12:13:45 +0100 Subject: [PATCH] A bunch of changes aiming to make Sync safer --- Project.xcodeproj/project.pbxproj | 10 - README.md | 4 +- Source/DataStack/DataStack.swift | 112 ++++---- Source/Sync/Sync+DataStack.swift | 40 +-- Source/Sync/Sync+ObjC.swift | 74 ----- Source/Sync/Sync.swift | 27 +- Tests/DataFilter/DataFilterTests.swift | 48 ++-- Tests/DataStack/Tests.swift | 20 +- Tests/Sync/Helpers/Helper.swift | 4 +- .../NSManagedObjectContext+SyncTests.swift | 4 +- Tests/Sync/SyncTests.swift | 258 +++++++++--------- 11 files changed, 279 insertions(+), 322 deletions(-) delete mode 100644 Source/Sync/Sync+ObjC.swift diff --git a/Project.xcodeproj/project.pbxproj b/Project.xcodeproj/project.pbxproj index 2b241a0a..290bad23 100644 --- a/Project.xcodeproj/project.pbxproj +++ b/Project.xcodeproj/project.pbxproj @@ -502,10 +502,6 @@ 14F6277A1E7AE6E1001C2EA0 /* DataStack.swift in Headers */ = {isa = PBXBuildFile; fileRef = 1467388B1E7ADBA700913C8E /* DataStack.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 1AFF18CB1FE1F08900C4BC3D /* 457-products.json in Resources */ = {isa = PBXBuildFile; fileRef = 1AFF18C91FE1F08800C4BC3D /* 457-products.json */; }; 1AFF18CC1FE1F08900C4BC3D /* 457-subcategories.json in Resources */ = {isa = PBXBuildFile; fileRef = 1AFF18CA1FE1F08800C4BC3D /* 457-subcategories.json */; }; - 25A89F821F00ED7E008ADD4B /* Sync+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47FF6201F0002A3004A923A /* Sync+ObjC.swift */; }; - 25A89F831F00ED7E008ADD4B /* Sync+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47FF6201F0002A3004A923A /* Sync+ObjC.swift */; }; - 25A89F841F00ED7F008ADD4B /* Sync+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47FF6201F0002A3004A923A /* Sync+ObjC.swift */; }; - 25A89F851F00ED7F008ADD4B /* Sync+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47FF6201F0002A3004A923A /* Sync+ObjC.swift */; }; 445851BB1E87BAF50025434E /* DictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4458519C1E87BAF50025434E /* DictionaryTests.swift */; }; 445851BC1E87BAF50025434E /* DictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4458519C1E87BAF50025434E /* DictionaryTests.swift */; }; 445851BD1E87BAF50025434E /* DictionaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4458519C1E87BAF50025434E /* DictionaryTests.swift */; }; @@ -1092,7 +1088,6 @@ CC9494171F379BE1002167B4 /* 373.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = 373.json; sourceTree = ""; }; CCF94956203AE72700C64B80 /* 480.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = 480.xcdatamodel; sourceTree = ""; }; CCF9495A203AF4AF00C64B80 /* 480.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = 480.json; sourceTree = ""; }; - E47FF6201F0002A3004A923A /* Sync+ObjC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Sync+ObjC.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1585,7 +1580,6 @@ 14549A0A1E7C2E1000A77F2E /* Sync+Helpers.swift */, 14D5255E1E7C1EC30063909F /* Sync+NSManagedObjectContext.swift */, 142CD2AC1DEF3A01002FDABE /* Sync+NSPersistentContainer.swift */, - E47FF6201F0002A3004A923A /* Sync+ObjC.swift */, ); path = Sync; sourceTree = ""; @@ -2321,7 +2315,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 25A89F821F00ED7E008ADD4B /* Sync+ObjC.swift in Sources */, 14241EA01DBC3A6F0042ED81 /* NSArray+Sync.swift in Sources */, 44B212F81E87BD5D00C81949 /* NSPropertyDescription+Sync.m in Sources */, 14241EA11DBC3A6F0042ED81 /* NSEntityDescription+Sync.swift in Sources */, @@ -2349,7 +2342,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 25A89F851F00ED7F008ADD4B /* Sync+ObjC.swift in Sources */, 14241EA81DBC3A770042ED81 /* NSArray+Sync.swift in Sources */, 44B212FB1E87BD5D00C81949 /* NSPropertyDescription+Sync.m in Sources */, 14241EA91DBC3A770042ED81 /* NSEntityDescription+Sync.swift in Sources */, @@ -2377,7 +2369,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 25A89F831F00ED7E008ADD4B /* Sync+ObjC.swift in Sources */, 14241EB01DBC3A7F0042ED81 /* NSArray+Sync.swift in Sources */, 44B212F91E87BD5D00C81949 /* NSPropertyDescription+Sync.m in Sources */, 14241EB11DBC3A7F0042ED81 /* NSEntityDescription+Sync.swift in Sources */, @@ -2405,7 +2396,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 25A89F841F00ED7F008ADD4B /* Sync+ObjC.swift in Sources */, 14241EB81DBC3A880042ED81 /* NSArray+Sync.swift in Sources */, 44B212FA1E87BD5D00C81949 /* NSPropertyDescription+Sync.m in Sources */, 14241EB91DBC3A880042ED81 /* NSEntityDescription+Sync.swift in Sources */, diff --git a/README.md b/README.md index 745b25a5..947b3855 100755 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Syncing JSON to Core Data is a repetitive tasks that often demands adding a lot DataStack is a wrapper on top of the Core Data boilerplate, it encapsulates dealing with NSPersistentStoreCoordinator and NSManageObjectContexts. ```swift -self.dataStack = DataStack(modelName: "DataModel") +self.dataStack = try! DataStack(modelName: "DataModel") ``` [You can find here more ways of initializing your DataStack](https://github.com/3lvis/Sync/blob/6723c1f9a07014024e0f8f2923d1930789cabb72/Source/DataStack/DataStack.swift#L77-L196). @@ -134,7 +134,7 @@ https://github.com/3lvis/StoryboardDemo Replace your Core Data stack with an instance of [DataStack](https://github.com/3lvis/Sync/blob/master/docs/DataStack.md). ```swift -self.dataStack = DataStack(modelName: "Demo") +self.dataStack = try! DataStack(modelName: "Demo") ``` ### Primary key diff --git a/Source/DataStack/DataStack.swift b/Source/DataStack/DataStack.swift index a68de61c..22686c9f 100755 --- a/Source/DataStack/DataStack.swift +++ b/Source/DataStack/DataStack.swift @@ -14,7 +14,15 @@ import CoreData } } -@objc public class DataStack: NSObject { +public enum DataStackError: Error { + case persistentStoreCoordinatorCreationErrorForInMemoryStore(_ error: NSError) + case couldNotCopyPreloadedData(_ error: NSError) + case persistentStoreCoordinatorCreationErrorForSQLite(_ error: NSError) + case persistentStoreCoordinatorRemovalError(_ error: NSError) + case excludingSQLiteFromBackgroundError(_ error: NSError) +} + +public class DataStack { private var storeType = DataStackStoreType.sqLite private var storeName: String? @@ -35,17 +43,7 @@ import CoreData The context for the main queue. Please do not use this to mutate data, use `performInNewBackgroundContext` instead. */ - @objc public lazy var mainContext: NSManagedObjectContext = { - let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) - context.undoManager = nil - context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy - context.persistentStoreCoordinator = self.persistentStoreCoordinator - - NotificationCenter.default.addObserver(self, selector: #selector(DataStack.mainContextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: context) - - return context - }() - + @objc public var mainContext: NSManagedObjectContext! /** The context for the main queue. Please do not use this to mutate data, use `performBackgroundTask` instead. @@ -63,12 +61,7 @@ import CoreData return context }() - @objc public private(set) lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { - let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.model) - try! persistentStoreCoordinator.addPersistentStore(storeType: self.storeType, bundle: self.modelBundle, modelName: self.modelName, storeName: self.storeName, containerURL: self.containerURL) - - return persistentStoreCoordinator - }() + @objc public private(set) var persistentStoreCoordinator: NSPersistentStoreCoordinator! private lazy var disposablePersistentStoreCoordinator: NSPersistentStoreCoordinator = { let model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) @@ -82,39 +75,62 @@ import CoreData Initializes a DataStack using the bundle name as the model name, so if your target is called ModernApp, it will look for a ModernApp.xcdatamodeld. */ - @objc public override init() { + public init() throws { let bundle = Bundle.main if let bundleName = bundle.infoDictionary?["CFBundleName"] as? String { self.modelName = bundleName } self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - super.init() + // MainContext + let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) + context.undoManager = nil + context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy + context.persistentStoreCoordinator = self.persistentStoreCoordinator + + self.mainContext = context + NotificationCenter.default.addObserver(self, selector: #selector(DataStack.mainContextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: context) } /** Initializes a DataStack using the provided model name. - parameter modelName: The name of your Core Data model (xcdatamodeld). */ - @objc public init(modelName: String) { + public init(modelName: String) throws { self.modelName = modelName self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - - super.init() + + try setup() } + func setup() throws { + // MainContext + let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) + context.undoManager = nil + context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy + + let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.model) + try persistentStoreCoordinator.addPersistentStore(storeType: self.storeType, bundle: self.modelBundle, modelName: self.modelName, storeName: self.storeName, containerURL: self.containerURL) + self.persistentStoreCoordinator = persistentStoreCoordinator + + context.persistentStoreCoordinator = self.persistentStoreCoordinator + + self.mainContext = context + NotificationCenter.default.addObserver(self, selector: #selector(DataStack.mainContextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: context) + } + /** Initializes a DataStack using the provided model name, bundle and storeType. - parameter modelName: The name of your Core Data model (xcdatamodeld). - parameter storeType: The store type to be used, you have .InMemory and .SQLite, the first one is memory based and doesn't save to disk, while the second one creates a .sqlite file and stores things there. */ - @objc public init(modelName: String, storeType: DataStackStoreType) { + public init(modelName: String, storeType: DataStackStoreType) throws { self.modelName = modelName self.storeType = storeType self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - super.init() + try setup() } /** @@ -126,13 +142,13 @@ import CoreData - parameter storeType: The store type to be used, you have .InMemory and .SQLite, the first one is memory based and doesn't save to disk, while the second one creates a .sqlite file and stores things there. */ - @objc public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType) { + public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType) throws { self.modelName = modelName self.modelBundle = bundle self.storeType = storeType self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - - super.init() + + try setup() } /** @@ -147,14 +163,14 @@ import CoreData name is AwesomeApp then the .sqlite file will be named AwesomeApp.sqlite, this attribute allows your to change that. */ - @objc public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType, storeName: String) { + public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType, storeName: String) throws { self.modelName = modelName self.modelBundle = bundle self.storeType = storeType self.storeName = storeName self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - - super.init() + + try setup() } /** @@ -170,15 +186,15 @@ import CoreData change that. - parameter containerURL: The container URL for the sqlite file when a store type of SQLite is used. */ - @objc public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType, storeName: String, containerURL: URL) { + public init(modelName: String, bundle: Bundle, storeType: DataStackStoreType, storeName: String, containerURL: URL) throws { self.modelName = modelName self.modelBundle = bundle self.storeType = storeType self.storeName = storeName self.containerURL = containerURL self.model = NSManagedObjectModel(bundle: self.modelBundle, name: self.modelName) - - super.init() + + try setup() } /** @@ -187,7 +203,7 @@ import CoreData - parameter storeType: The store type to be used, you have .InMemory and .SQLite, the first one is memory based and doesn't save to disk, while the second one creates a .sqlite file and stores things there. */ - @objc public init(model: NSManagedObjectModel, storeType: DataStackStoreType) { + public init(model: NSManagedObjectModel, storeType: DataStackStoreType) throws { self.model = model self.storeType = storeType @@ -195,8 +211,8 @@ import CoreData if let bundleName = bundle.infoDictionary?["CFBundleName"] as? String { self.storeName = bundleName } - - super.init() + + try setup() } deinit { @@ -235,10 +251,12 @@ import CoreData /** Returns a background context perfect for data mutability operations. Make sure to never use it on the main thread. Use `performBlock` or `performBlockAndWait` to use it. */ - @objc public func newBackgroundContext() -> NSManagedObjectContext { + @objc public func newBackgroundContext() throws -> NSManagedObjectContext { let context = NSManagedObjectContext(concurrencyType: DataStack.backgroundConcurrencyType()) context.name = backgroundContextName + context.persistentStoreCoordinator = self.persistentStoreCoordinator + context.undoManager = nil context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy @@ -251,8 +269,8 @@ import CoreData Returns a background context perfect for data mutability operations. - parameter operation: The block that contains the created background context. */ - @objc public func performInNewBackgroundContext(_ operation: @escaping (_ backgroundContext: NSManagedObjectContext) -> Void) { - let context = self.newBackgroundContext() + public func performInNewBackgroundContext(_ operation: @escaping (_ backgroundContext: NSManagedObjectContext) -> Void) throws { + let context = try self.newBackgroundContext() let contextBlock: @convention(block) () -> Void = { operation(context) } @@ -264,8 +282,8 @@ import CoreData Returns a background context perfect for data mutability operations. - parameter operation: The block that contains the created background context. */ - @objc public func performBackgroundTask(operation: @escaping (_ backgroundContext: NSManagedObjectContext) -> Void) { - self.performInNewBackgroundContext(operation) + @objc public func performBackgroundTask(operation: @escaping (_ backgroundContext: NSManagedObjectContext) -> Void) throws { + try self.performInNewBackgroundContext(operation) } func saveMainThread(completion: ((_ error: NSError?) -> Void)?) { @@ -415,7 +433,7 @@ extension NSPersistentStoreCoordinator { do { try self.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil) } catch let error as NSError { - throw NSError(info: "There was an error creating the persistentStoreCoordinator for in memory store", previousError: error) + throw DataStackError.persistentStoreCoordinatorCreationErrorForInMemoryStore(error) } break @@ -431,7 +449,7 @@ extension NSPersistentStoreCoordinator { do { try FileManager.default.copyItem(at: preloadURL, to: storeURL) } catch let error as NSError { - throw NSError(info: "Oops, could not copy preloaded data", previousError: error) + throw DataStackError.couldNotCopyPreloadedData(error) } } } @@ -445,10 +463,10 @@ extension NSPersistentStoreCoordinator { do { try self.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: options) } catch let addPersistentError as NSError { - throw NSError(info: "There was an error creating the persistentStoreCoordinator", previousError: addPersistentError) + throw DataStackError.persistentStoreCoordinatorCreationErrorForSQLite(addPersistentError) } } catch let removingError as NSError { - throw NSError(info: "There was an error removing the persistentStoreCoordinator", previousError: removingError) + throw DataStackError.persistentStoreCoordinatorRemovalError(removingError) } } @@ -457,7 +475,7 @@ extension NSPersistentStoreCoordinator { do { try (storeURL as NSURL).setResourceValue(true, forKey: .isExcludedFromBackupKey) } catch let excludingError as NSError { - throw NSError(info: "Excluding SQLite file from backup caused an error", previousError: excludingError) + throw DataStackError.excludingSQLiteFromBackgroundError(excludingError) } } diff --git a/Source/Sync/Sync+DataStack.swift b/Source/Sync/Sync+DataStack.swift index 5c1b8693..0e5fb022 100644 --- a/Source/Sync/Sync+DataStack.swift +++ b/Source/Sync/Sync+DataStack.swift @@ -8,8 +8,8 @@ public extension DataStack { /// - changes: The array of dictionaries used in the sync process. /// - entityName: The name of the entity to be synced. /// - completion: The completion block, it returns an error if something in the Sync process goes wrong. - func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, completion: ((_ error: NSError?) -> Void)?) { - Sync.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: self, operations: .all, completion: completion) + func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, completion: ((_ error: NSError?) -> Void)?) throws { + try Sync.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: self, operations: .all, completion: completion) } /// Syncs the entity using the received array of dictionaries, maps one-to-many, many-to-many and one-to-one relationships. @@ -22,8 +22,8 @@ public extension DataStack { /// - entityName: The name of the entity to be synced. /// - operations: The type of operations to be applied to the data, Insert, Update, Delete or any possible combination. /// - completion: The completion block, it returns an error if something in the Sync process goes wrong. - func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) { - Sync.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: self, operations: operations, completion: completion) + func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) throws { + try Sync.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: self, operations: operations, completion: completion) } /// Syncs the entity using the received array of dictionaries, maps one-to-many, many-to-many and one-to-one relationships. @@ -36,8 +36,8 @@ public extension DataStack { /// - entityName: The name of the entity to be synced. /// - predicate: The predicate used to filter out changes, if you want to exclude some local items to be taken in account in the Sync process, you just need to provide this predicate. /// - completion: The completion block, it returns an error if something in the Sync process goes wrong. - func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, completion: ((_ error: NSError?) -> Void)?) { - self.performInNewBackgroundContext { backgroundContext in + func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, completion: ((_ error: NSError?) -> Void)?) throws { + try self.performInNewBackgroundContext { backgroundContext in Sync.changes(changes, inEntityNamed: entityName, predicate: predicate, parent: nil, parentRelationship: nil, inContext: backgroundContext, operations: .all, completion: completion) } } @@ -53,8 +53,8 @@ public extension DataStack { /// - predicate: The predicate used to filter out changes, if you want to exclude some local items to be taken in account in the Sync process, you just need to provide this predicate. /// - operations: The type of operations to be applied to the data, Insert, Update, Delete or any possible combination. /// - completion: The completion block, it returns an error if something in the Sync process goes wrong. - func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) { - self.performInNewBackgroundContext { backgroundContext in + func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) throws { + try self.performInNewBackgroundContext { backgroundContext in Sync.changes(changes, inEntityNamed: entityName, predicate: predicate, parent: nil, parentRelationship: nil, inContext: backgroundContext, operations: operations, completion: completion) } } @@ -71,8 +71,8 @@ public extension DataStack { /// an Album has many photos, if this photos don't incldue the album's JSON object, syncing the photos JSON requires /// you to send the parent album to do the proper mapping. /// - completion: The completion block, it returns an error if something in the Sync process goes wrong. - func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, parent: NSManagedObject, completion: ((_ error: NSError?) -> Void)?) { - self.performInNewBackgroundContext { backgroundContext in + func sync(_ changes: [[String: Any]], inEntityNamed entityName: String, parent: NSManagedObject, completion: ((_ error: NSError?) -> Void)?) throws { + try self.performInNewBackgroundContext { backgroundContext in let safeParent = parent.sync_copyInContext(backgroundContext) guard let entity = NSEntityDescription.entity(forEntityName: entityName, in: backgroundContext) else { fatalError("Couldn't find entity named: \(entityName)") } let relationships = entity.relationships(forDestination: parent.entity) @@ -153,8 +153,8 @@ public extension Sync { - parameter dataStack: The DataStack instance. - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. */ - class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) { - self.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: dataStack, operations: .all, completion: completion) + class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) throws { + try self.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: dataStack, operations: .all, completion: completion) } /** @@ -168,8 +168,8 @@ public extension Sync { - parameter operations: The type of operations to be applied to the data, Insert, Update, Delete or any possible combination. - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. */ - class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, dataStack: DataStack, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) { - self.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: dataStack, operations: operations, completion: completion) + class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, dataStack: DataStack, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) throws { + try self.changes(changes, inEntityNamed: entityName, predicate: nil, dataStack: dataStack, operations: operations, completion: completion) } /** @@ -184,8 +184,8 @@ public extension Sync { - parameter dataStack: The DataStack instance. - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. */ - class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) { - dataStack.performInNewBackgroundContext { backgroundContext in + class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) throws { + try dataStack.performInNewBackgroundContext { backgroundContext in self.changes(changes, inEntityNamed: entityName, predicate: predicate, parent: nil, parentRelationship: nil, inContext: backgroundContext, operations: .all, completion: completion) } } @@ -203,8 +203,8 @@ public extension Sync { - parameter operations: The type of operations to be applied to the data, Insert, Update, Delete or any possible combination. - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. */ - class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, dataStack: DataStack, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) { - dataStack.performInNewBackgroundContext { backgroundContext in + class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, dataStack: DataStack, operations: Sync.OperationOptions, completion: ((_ error: NSError?) -> Void)?) throws { + try dataStack.performInNewBackgroundContext { backgroundContext in self.changes(changes, inEntityNamed: entityName, predicate: predicate, parent: nil, parentRelationship: nil, inContext: backgroundContext, operations: operations, completion: completion) } } @@ -222,8 +222,8 @@ public extension Sync { - parameter dataStack: The DataStack instance. - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. */ - class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, parent: NSManagedObject, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) { - dataStack.performInNewBackgroundContext { backgroundContext in + class func changes(_ changes: [[String: Any]], inEntityNamed entityName: String, parent: NSManagedObject, dataStack: DataStack, completion: ((_ error: NSError?) -> Void)?) throws { + try dataStack.performInNewBackgroundContext { backgroundContext in let safeParent = parent.sync_copyInContext(backgroundContext) guard let entity = NSEntityDescription.entity(forEntityName: entityName, in: backgroundContext) else { fatalError("Couldn't find entity named: \(entityName)") } let relationships = entity.relationships(forDestination: parent.entity) diff --git a/Source/Sync/Sync+ObjC.swift b/Source/Sync/Sync+ObjC.swift deleted file mode 100644 index d074e2d0..00000000 --- a/Source/Sync/Sync+ObjC.swift +++ /dev/null @@ -1,74 +0,0 @@ -/** - The enum for Objective-C, equals to Sync.OperationOptions in Swift. - Objective-C does not support array of enum as parameter, thus we have listed all possible combinations in this enum. - */ -@objc public enum CompatibleOperationOptions: Int { - case insert = 0 - case update = 1 - case delete = 2 - case insertUpdate = 3 - case insertDelete = 4 - case updateDelete = 5 - case all = 6 - - /** - Transfer Objective-C enum to Sync.OperationOptions in Swift - */ - var operationOptions: Sync.OperationOptions { - switch self { - case .insert: - return [.insert] - case .update: - return [.update] - case .delete: - return [.delete] - case .insertUpdate: - return [.insert, .update] - case .insertDelete: - return [.insert, .delete] - case .updateDelete: - return [.update, .delete] - case .all: - return [.all] - } - } -} - -public extension Sync { - - /** - Added support for Objective-C. - Syncs the entity using the received array of dictionaries, maps one-to-many, many-to-many and one-to-one relationships. - It also syncs relationships where only the id is present, for example if your model is: Company -> Employee, - and your employee has a company_id, it will try to sync using that ID instead of requiring you to provide the - entire company object inside the employees dictionary. - - parameter changes: The array of dictionaries used in the sync process. - - parameter entityName: The name of the entity to be synced. - - parameter dataStack: The DataStack instance. - - parameter operations: The type of operations to be applied to the data, it should be a value of CompatibleOperationOptions. - - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. - */ - class func compatibleChanges(_ changes: [[String: Any]], inEntityNamed entityName: String, dataStack: DataStack, operations: CompatibleOperationOptions, completion: ((_ error: NSError?) -> Void)?) { - self.changes(changes, inEntityNamed: entityName, dataStack: dataStack, operations: operations.operationOptions, completion: completion) - } - - /** - Added support for Objective-C. - Syncs the entity using the received array of dictionaries, maps one-to-many, many-to-many and one-to-one relationships. - It also syncs relationships where only the id is present, for example if your model is: Company -> Employee, - and your employee has a company_id, it will try to sync using that ID instead of requiring you to provide the - entire company object inside the employees dictionary. - - parameter changes: The array of dictionaries used in the sync process. - - parameter entityName: The name of the entity to be synced. - - parameter predicate: The predicate used to filter out changes, if you want to exclude some local items to be taken in - account in the Sync process, you just need to provide this predicate. - - parameter dataStack: The DataStack instance. - - parameter operations: The type of operations to be applied to the data, it should be a value of CompatibleOperationOptions. - - parameter completion: The completion block, it returns an error if something in the Sync process goes wrong. - */ - class func compatibleChanges(_ changes: [[String: Any]], inEntityNamed entityName: String, predicate: NSPredicate?, dataStack: DataStack, operations: CompatibleOperationOptions, completion: ((_ error: NSError?) -> Void)?) { - dataStack.performInNewBackgroundContext { backgroundContext in - self.changes(changes, inEntityNamed: entityName, predicate: predicate, dataStack: dataStack, operations: operations.operationOptions, completion: completion) - } - } -} diff --git a/Source/Sync/Sync.swift b/Source/Sync/Sync.swift index b8ab9828..f937a276 100644 --- a/Source/Sync/Sync.swift +++ b/Source/Sync/Sync.swift @@ -114,8 +114,31 @@ public protocol SyncDelegate: class { self.perform(using: context) } } else { - self.dataStack.performInNewBackgroundContext { backgroundContext in - self.perform(using: backgroundContext) + // Error handling inside NSOperations is rather difficult, + // if you have any suggestions on how to handle this + // please let me know. + do { + try self.dataStack.performInNewBackgroundContext { backgroundContext in + self.perform(using: backgroundContext) + } + } catch DataStackError.persistentStoreCoordinatorCreationErrorForInMemoryStore(let error) { + print("Failed DataStackError.persistentStoreCoordinatorCreationErrorForInMemoryStore \(error)") + cancel() + } catch DataStackError.couldNotCopyPreloadedData(let error) { + print("Failed DataStackError.couldNotCopyPreloadedData \(error)") + cancel() + } catch DataStackError.persistentStoreCoordinatorCreationErrorForSQLite(let error) { + print("Failed DataStackError.persistentStoreCoordinatorCreationErrorForSQLite \(error)") + cancel() + } catch DataStackError.persistentStoreCoordinatorRemovalError(let error) { + print("Failed DataStackError.persistentStoreCoordinatorRemovalError \(error)") + cancel() + } catch DataStackError.excludingSQLiteFromBackgroundError(let error) { + print("Failed DataStackError.excludingSQLiteFromBackgroundError \(error)") + cancel() + } catch let otherError as NSError { + print("Failed with another error \(otherError)") + cancel() } } } diff --git a/Tests/DataFilter/DataFilterTests.swift b/Tests/DataFilter/DataFilterTests.swift index 10e9a32d..5486fc1f 100755 --- a/Tests/DataFilter/DataFilterTests.swift +++ b/Tests/DataFilter/DataFilterTests.swift @@ -34,7 +34,7 @@ class DataFilterTests: XCTestCase { } func testUsersCount() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) self.createUsers(context: dataStack.mainContext) let request = NSFetchRequest(entityName: "User") @@ -50,8 +50,8 @@ class DataFilterTests: XCTestCase { - Deleted: 4 */ func testMapChangesA() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -79,8 +79,8 @@ class DataFilterTests: XCTestCase { - Deleted: 4 */ func testMapChangesAWitNull() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -108,8 +108,8 @@ class DataFilterTests: XCTestCase { - Deleted: 4 */ func testMapChangesAWithNil() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -137,8 +137,8 @@ class DataFilterTests: XCTestCase { - Deleted: None */ func testMapChangesB() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -166,8 +166,8 @@ class DataFilterTests: XCTestCase { - Deleted: None */ func testMapChangesC() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -196,8 +196,8 @@ class DataFilterTests: XCTestCase { - Deleted: 4 */ func testUniquing() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) self.user(remoteID: 0, firstName: "Amy", lastName: "Juergens", age: 21, context: backgroundContext) @@ -227,8 +227,8 @@ class DataFilterTests: XCTestCase { - Deleted: 0 */ func testStringID() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.note(remoteID: "123", text: "text", context: backgroundContext) try! backgroundContext.save() @@ -246,8 +246,8 @@ class DataFilterTests: XCTestCase { } func testInsertOnly() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.user(remoteID: 0, firstName: "Amy", lastName: "Juergens", age: 21, context: backgroundContext) self.user(remoteID: 1, firstName: "Ben", lastName: "Boykewich", age: 23, context: backgroundContext) @@ -269,8 +269,8 @@ class DataFilterTests: XCTestCase { } func testUpdateOnly() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.user(remoteID: 0, firstName: "Amy", lastName: "Juergens", age: 21, context: backgroundContext) self.user(remoteID: 1, firstName: "Ben", lastName: "Boykewich", age: 23, context: backgroundContext) @@ -292,8 +292,8 @@ class DataFilterTests: XCTestCase { } func testDeleteOnly() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.user(remoteID: 0, firstName: "Amy", lastName: "Juergens", age: 21, context: backgroundContext) self.user(remoteID: 1, firstName: "Ben", lastName: "Boykewich", age: 23, context: backgroundContext) @@ -320,8 +320,8 @@ class DataFilterTests: XCTestCase { the set existing ID: 1, meaning that if an item with ID: 2 appears, then this item will be inserted. */ func testPredicate() { - let dataStack = DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) - dataStack.performInNewBackgroundContext { backgroundContext in + let dataStack = try! DataStack(modelName: "DataFilter", bundle: Bundle(for: DataFilterTests.self), storeType: .inMemory) + try! dataStack.performInNewBackgroundContext { backgroundContext in self.createUsers(context: backgroundContext) let before = backgroundContext.objectIDs(inEntityNamed: "User", withAttributesNamed: "remoteID") @@ -348,7 +348,7 @@ class DataFilterTests: XCTestCase { var inserted = 0 var updated = 0 var ids = [Int]() - dataStack.performInNewBackgroundContext { backgroundContext in + try! dataStack.performInNewBackgroundContext { backgroundContext in DataFilter.changes(carsObject, inEntityNamed: "Racecar", localPrimaryKey: "remoteID", remotePrimaryKey: "id", context: backgroundContext, inserted: { insertedJSON in if let id = insertedJSON["id"] as? Int { ids.append(id) diff --git a/Tests/DataStack/Tests.swift b/Tests/DataStack/Tests.swift index 29269561..f8509812 100755 --- a/Tests/DataStack/Tests.swift +++ b/Tests/DataStack/Tests.swift @@ -4,7 +4,7 @@ import CoreData extension XCTestCase { func createDataStack(_ storeType: DataStackStoreType = .inMemory) -> DataStack { - let dataStack = DataStack(modelName: "ModelGroup", bundle: Bundle(for: Tests.self), storeType: storeType) + let dataStack = try! DataStack(modelName: "ModelGroup", bundle: Bundle(for: Tests.self), storeType: storeType) return dataStack } @@ -29,7 +29,7 @@ extension XCTestCase { class InitializerTests: XCTestCase { func testInitializeUsingXCDataModel() { - let dataStack = DataStack(modelName: "SimpleModel", bundle: Bundle(for: Tests.self), storeType: .inMemory) + let dataStack = try! DataStack(modelName: "SimpleModel", bundle: Bundle(for: Tests.self), storeType: .inMemory) self.insertUser(in: dataStack.mainContext) let objects = self.fetch(in: dataStack.mainContext) @@ -48,7 +48,7 @@ class InitializerTests: XCTestCase { func testInitializingUsingNSManagedObjectModel() { let model = NSManagedObjectModel(bundle: Bundle(for: Tests.self), name: "ModelGroup") - let dataStack = DataStack(model: model, storeType: .inMemory) + let dataStack = try! DataStack(model: model, storeType: .inMemory) self.insertUser(in: dataStack.mainContext) let objects = self.fetch(in: dataStack.mainContext) @@ -61,7 +61,7 @@ class Tests: XCTestCase { let dataStack = self.createDataStack() var synchronous = false - dataStack.performInNewBackgroundContext { _ in + try! dataStack.performInNewBackgroundContext { _ in synchronous = true } @@ -71,7 +71,7 @@ class Tests: XCTestCase { func testBackgroundContextSave() { let dataStack = self.createDataStack() - dataStack.performInNewBackgroundContext { backgroundContext in + try! dataStack.performInNewBackgroundContext { backgroundContext in self.insertUser(in: backgroundContext) let objects = self.fetch(in: backgroundContext) @@ -85,7 +85,7 @@ class Tests: XCTestCase { func testNewBackgroundContextSave() { var synchronous = false let dataStack = self.createDataStack() - let backgroundContext = dataStack.newBackgroundContext() + let backgroundContext = try! dataStack.newBackgroundContext() backgroundContext.performAndWait { synchronous = true self.insertUser(in: backgroundContext) @@ -132,7 +132,7 @@ class Tests: XCTestCase { func testDrop() { let dataStack = self.createDataStack(.sqLite) - dataStack.performInNewBackgroundContext { backgroundContext in + try! dataStack.performInNewBackgroundContext { backgroundContext in self.insertUser(in: backgroundContext) } @@ -144,7 +144,7 @@ class Tests: XCTestCase { let objects = self.fetch(in: dataStack.mainContext) XCTAssertEqual(objects.count, 0) - dataStack.performInNewBackgroundContext { backgroundContext in + try! dataStack.performInNewBackgroundContext { backgroundContext in self.insertUser(in: backgroundContext) } @@ -155,13 +155,13 @@ class Tests: XCTestCase { } func testAutomaticMigration() { - let firstDataStack = DataStack(modelName: "SimpleModel", bundle: Bundle(for: Tests.self), storeType: .sqLite, storeName: "Shared") + let firstDataStack = try! DataStack(modelName: "SimpleModel", bundle: Bundle(for: Tests.self), storeType: .sqLite, storeName: "Shared") self.insertUser(in: firstDataStack.mainContext) let objects = self.fetch(in: firstDataStack.mainContext) XCTAssertEqual(objects.count, 1) // LightweightMigrationModel is a copy of DataModel with the main difference that adds the updatedDate attribute. - let secondDataStack = DataStack(modelName: "LightweightMigrationModel", bundle: Bundle(for: Tests.self), storeType: .sqLite, storeName: "Shared") + let secondDataStack = try! DataStack(modelName: "LightweightMigrationModel", bundle: Bundle(for: Tests.self), storeType: .sqLite, storeName: "Shared") let fetchRequest = NSFetchRequest(entityName: "User") fetchRequest.predicate = NSPredicate(format: "remoteID = %@", NSNumber(value: 1)) let user = try! secondDataStack.mainContext.fetch(fetchRequest).first diff --git a/Tests/Sync/Helpers/Helper.swift b/Tests/Sync/Helpers/Helper.swift index 0a525896..c65f40ec 100644 --- a/Tests/Sync/Helpers/Helper.swift +++ b/Tests/Sync/Helpers/Helper.swift @@ -12,7 +12,7 @@ import Sync class func dataStackWithModelName(_ modelName: String) -> DataStack { let bundle = Bundle(for: Helper.self) - let dataStack = DataStack(modelName: modelName, bundle: bundle, storeType: .sqLite) + let dataStack = try! DataStack(modelName: modelName, bundle: bundle, storeType: .sqLite) return dataStack } @@ -61,7 +61,7 @@ import Sync class func dataStackWithModelName(_ modelName: String, storeType: DataStackStoreType = .sqLite) -> DataStack { let bundle = Bundle(for: Helper.self) - let dataStack = DataStack(modelName: modelName, bundle: bundle, storeType: storeType) + let dataStack = try! DataStack(modelName: modelName, bundle: bundle, storeType: storeType) return dataStack } diff --git a/Tests/Sync/NSManagedObjectContext+SyncTests.swift b/Tests/Sync/NSManagedObjectContext+SyncTests.swift index d11933a5..f19d1bdc 100644 --- a/Tests/Sync/NSManagedObjectContext+SyncTests.swift +++ b/Tests/Sync/NSManagedObjectContext+SyncTests.swift @@ -7,8 +7,8 @@ class NSManagedObjectContext_SyncTests: XCTestCase { } func configureUserWithRemoteID(remoteID: NSNumber?, localID: String?, name: String, block: @escaping (_ user: NSManagedObject, _ context: NSManagedObjectContext) -> Void) { - let stack = DataStack(modelName: "Tests", bundle: Bundle(for: NSManagedObjectContext_SyncTests.self), storeType: .inMemory) - stack.performInNewBackgroundContext { context in + let stack = try! DataStack(modelName: "Tests", bundle: Bundle(for: NSManagedObjectContext_SyncTests.self), storeType: .inMemory) + try! stack.performInNewBackgroundContext { context in let user = NSEntityDescription.insertNewObject(forEntityName: "User", into: context) user.setValue(remoteID, forKey: "remoteID") user.setValue(localID, forKey: "localID") diff --git a/Tests/Sync/SyncTests.swift b/Tests/Sync/SyncTests.swift index 389dc71e..6ceb65c1 100644 --- a/Tests/Sync/SyncTests.swift +++ b/Tests/Sync/SyncTests.swift @@ -8,7 +8,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Camelcase") let objects = Helper.objectsFromJSON("camelcase.json") as! [[String: Any]] var synchronous = false - dataStack.sync(objects, inEntityNamed: "NormalUser") { _ in + try! dataStack.sync(objects, inEntityNamed: "NormalUser") { _ in synchronous = true } XCTAssertTrue(synchronous) @@ -19,7 +19,7 @@ class SyncTests: XCTestCase { func testAutomaticCamelcaseMapping() { let dataStack = Helper.dataStackWithModelName("Camelcase") let objects = Helper.objectsFromJSON("camelcase.json") as! [[String: Any]] - dataStack.sync(objects, inEntityNamed: "NormalUser", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "NormalUser", completion: nil) let result = Helper.fetchEntity("NormalUser", inContext: dataStack.mainContext) XCTAssertEqual(result.count, 1) @@ -40,11 +40,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("users_a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 8) let objectsB = Helper.objectsFromJSON("users_b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 6) let result = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 7)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -67,7 +67,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objects = Helper.objectsFromJSON("users_company.json") as! [[String: Any]] - dataStack.sync(objects, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 5) let user = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -83,7 +83,7 @@ class SyncTests: XCTestCase { func testCustomMappingAndCustomPrimaryKey() { let dataStack = Helper.dataStackWithModelName("Contacts") let objects = Helper.objectsFromJSON("images.json") as! [[String: Any]] - dataStack.sync(objects, inEntityNamed: "Image", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Image", completion: nil) let array = Helper.fetchEntity("Image", sortDescriptors: [NSSortDescriptor(key: "url", ascending: true)], inContext: dataStack.mainContext) XCTAssertEqual(array.count, 3) @@ -97,7 +97,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objects = Helper.objectsFromJSON("users_c.json") as! [[String: Any]] - dataStack.sync(objects, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 4) let users = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 6)), inContext: dataStack.mainContext) @@ -122,11 +122,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("operation-types-users-a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let objectsB = Helper.objectsFromJSON("operation-types-users-b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) let result = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -142,17 +142,17 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("operation-types-users-a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let objectsB = Helper.objectsFromJSON("operation-types-users-b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) let result = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! XCTAssertEqual(result.value(forKey: "email") as? String, "melisawhite@ovium.com") - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) dataStack.drop() @@ -165,11 +165,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("operation-types-users-a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let objectsB = Helper.objectsFromJSON("operation-types-users-b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.update], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.update], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let result = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -185,11 +185,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("operation-types-users-a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let objectsB = Helper.objectsFromJSON("operation-types-users-b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.delete], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.delete], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) let result = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -205,11 +205,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("Contacts") let objectsA = Helper.objectsFromJSON("operation-types-users-a.json") as! [[String: Any]] - dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objectsA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) let objectsB = Helper.objectsFromJSON("operation-types-users-b.json") as! [[String: Any]] - dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert, .update], completion: nil) + try! dataStack.sync(objectsB, inEntityNamed: "User", operations: [.insert, .update], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) let user0 = Helper.fetchEntity("User", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), sortDescriptors: [NSSortDescriptor(key: "remoteID", ascending: true)], inContext: dataStack.mainContext).first! @@ -227,7 +227,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("users_notes.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Notes") - dataStack.sync(objects, inEntityNamed: "SuperUser", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "SuperUser", completion: nil) XCTAssertEqual(Helper.countForEntity("SuperUser", inContext: dataStack.mainContext), 4) let users = Helper.fetchEntity("SuperUser", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 6)), inContext: dataStack.mainContext) @@ -243,7 +243,7 @@ class SyncTests: XCTestCase { func testObjectsForParent() { let objects = Helper.objectsFromJSON("notes_for_user_a.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("InsertObjectsInParent") - dataStack.performInNewBackgroundContext { backgroundContext in + try! dataStack.performInNewBackgroundContext { backgroundContext in // First, we create a parent user, this user is the one that will own all the notes let user = NSEntityDescription.insertNewObject(forEntityName: "SuperUser", into: backgroundContext) user.setValue(NSNumber(value: 6), forKey: "remoteID") @@ -256,7 +256,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(users.count, 1) // Finally we say "Sync all the notes, for this user" - dataStack.sync(objects, inEntityNamed: "SuperNote", parent: users.first!, completion: nil) + try! dataStack.sync(objects, inEntityNamed: "SuperNote", parent: users.first!, completion: nil) // Here we just make sure that the user has the notes that we just inserted users = Helper.fetchEntity("SuperUser", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 6)), inContext: dataStack.mainContext) @@ -273,7 +273,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("tagged_notes.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Notes") - dataStack.sync(objects, inEntityNamed: "SuperNote", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "SuperNote", completion: nil) XCTAssertEqual(Helper.countForEntity("SuperNote", inContext: dataStack.mainContext), 3) let notes = Helper.fetchEntity("SuperNote", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), inContext: dataStack.mainContext) @@ -293,7 +293,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("custom_relationship_key_to_many.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("CustomRelationshipKey") - dataStack.sync(objects, inEntityNamed: "User", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "User", completion: nil) let array = Helper.fetchEntity("User", inContext: dataStack.mainContext) let user = array.first! @@ -308,7 +308,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("numbers.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Recursive") - dataStack.sync(objects, inEntityNamed: "Number", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Number", completion: nil) XCTAssertEqual(Helper.countForEntity("Number", inContext: dataStack.mainContext), 6) dataStack.drop() @@ -318,7 +318,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("numbers_in_collection.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Recursive") - dataStack.sync(objects, inEntityNamed: "Number", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Number", completion: nil) XCTAssertEqual(Helper.countForEntity("Collection", inContext: dataStack.mainContext), 1) @@ -336,7 +336,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("comments-no-id.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Social") - dataStack.sync(objects, inEntityNamed: "SocialComment", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "SocialComment", completion: nil) XCTAssertEqual(Helper.countForEntity("SocialComment", inContext: dataStack.mainContext), 8) let comments = Helper.fetchEntity("SocialComment", predicate: NSPredicate(format: "body = %@", "comment 1"), inContext: dataStack.mainContext) @@ -353,7 +353,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("stories-comments-no-ids.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Social") - dataStack.sync(objects, inEntityNamed: "Story", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Story", completion: nil) XCTAssertEqual(Helper.countForEntity("Story", inContext: dataStack.mainContext), 3) let stories = Helper.fetchEntity("Story", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), inContext: dataStack.mainContext) @@ -382,7 +382,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("custom_relationship_key_to_one.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Social") - dataStack.sync(objects, inEntityNamed: "Story", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Story", completion: nil) let array = Helper.fetchEntity("Story", inContext: dataStack.mainContext) let story = array.first! @@ -397,7 +397,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("markets_items.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Markets") - dataStack.sync(objects, inEntityNamed: "Market", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Market", completion: nil) XCTAssertEqual(Helper.countForEntity("Market", inContext: dataStack.mainContext), 2) let markets = Helper.fetchEntity("Market", predicate: NSPredicate(format: "uniqueId = %@", "1"), inContext: dataStack.mainContext) @@ -420,10 +420,10 @@ class SyncTests: XCTestCase { let json = Helper.objectsFromJSON("organizations-tree.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Organizations") - dataStack.sync(json, inEntityNamed: "OrganizationUnit", completion: nil) + try! dataStack.sync(json, inEntityNamed: "OrganizationUnit", completion: nil) XCTAssertEqual(Helper.countForEntity("OrganizationUnit", inContext: dataStack.mainContext), 7) - dataStack.sync(json, inEntityNamed: "OrganizationUnit", completion: nil) + try! dataStack.sync(json, inEntityNamed: "OrganizationUnit", completion: nil) XCTAssertEqual(Helper.countForEntity("OrganizationUnit", inContext: dataStack.mainContext), 7) dataStack.drop() @@ -440,12 +440,12 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("unique.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Unique") - dataStack.sync(objects, inEntityNamed: "A", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "A", completion: nil) XCTAssertEqual(Helper.countForEntity("A", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("B", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("C", inContext: dataStack.mainContext), 0) - dataStack.sync(objects, inEntityNamed: "C", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "C", completion: nil) XCTAssertEqual(Helper.countForEntity("A", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("B", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("C", inContext: dataStack.mainContext), 1) @@ -459,7 +459,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("patients.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Patients") - dataStack.sync(objects, inEntityNamed: "Patient", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Patient", completion: nil) XCTAssertEqual(Helper.countForEntity("Patient", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Baseline", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Alcohol", inContext: dataStack.mainContext), 1) @@ -476,7 +476,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("bug-number-84.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("84") - dataStack.sync(objects, inEntityNamed: "MSStaff", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "MSStaff", completion: nil) XCTAssertEqual(Helper.countForEntity("MSStaff", inContext: dataStack.mainContext), 1) @@ -502,7 +502,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("bug-113-comments-no-id.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("113") - dataStack.sync(objects, inEntityNamed: "AwesomeComment", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "AwesomeComment", completion: nil) XCTAssertEqual(Helper.countForEntity("AwesomeComment", inContext: dataStack.mainContext), 8) let comments = Helper.fetchEntity("AwesomeComment", predicate: NSPredicate(format: "body = %@", "comment 1"), inContext: dataStack.mainContext) @@ -519,7 +519,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("bug-113-stories-comments-no-ids.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("113") - dataStack.sync(objects, inEntityNamed: "AwesomeStory", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "AwesomeStory", completion: nil) XCTAssertEqual(Helper.countForEntity("AwesomeStory", inContext: dataStack.mainContext), 3) let stories = Helper.fetchEntity("AwesomeStory", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 0)), inContext: dataStack.mainContext) @@ -548,7 +548,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("bug-113-custom_relationship_key_to_one.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("113") - dataStack.sync(objects, inEntityNamed: "AwesomeStory", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "AwesomeStory", completion: nil) let array = Helper.fetchEntity("AwesomeStory", inContext: dataStack.mainContext) let story = array.first! @@ -564,7 +564,7 @@ class SyncTests: XCTestCase { let uri = formDictionary["uri"] as! String let dataStack = Helper.dataStackWithModelName("125") - dataStack.sync([formDictionary], inEntityNamed: "Form", predicate: NSPredicate(format: "uri == %@", uri), completion: nil) + try! dataStack.sync([formDictionary], inEntityNamed: "Form", predicate: NSPredicate(format: "uri == %@", uri), completion: nil) XCTAssertEqual(Helper.countForEntity("Form", inContext: dataStack.mainContext), 1) @@ -592,7 +592,7 @@ class SyncTests: XCTestCase { let formDictionary = Helper.objectsFromJSON("story-summarize.json") as! [String: Any] let dataStack = Helper.dataStackWithModelName("Social") - dataStack.sync([formDictionary], inEntityNamed: "Story", predicate: NSPredicate(format: "remoteID == %@", NSNumber(value: 1)), completion: nil) + try! dataStack.sync([formDictionary], inEntityNamed: "Story", predicate: NSPredicate(format: "remoteID == %@", NSNumber(value: 1)), completion: nil) XCTAssertEqual(Helper.countForEntity("Story", inContext: dataStack.mainContext), 1) let stories = Helper.fetchEntity("Story", predicate: NSPredicate(format: "remoteID = %@", NSNumber(value: 1)), inContext: dataStack.mainContext) @@ -621,14 +621,14 @@ class SyncTests: XCTestCase { let usersDictionary = Helper.objectsFromJSON("users_a.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("Notes") - dataStack.sync(usersDictionary, inEntityNamed: "SuperUser", completion: nil) + try! dataStack.sync(usersDictionary, inEntityNamed: "SuperUser", completion: nil) let usersCount = Helper.countForEntity("SuperUser", inContext: dataStack.mainContext) XCTAssertEqual(usersCount, 8) let notesDictionary = Helper.objectsFromJSON("notes_with_user_id.json") as! [[String: Any]] - dataStack.sync(notesDictionary, inEntityNamed: "SuperNote", completion: nil) + try! dataStack.sync(notesDictionary, inEntityNamed: "SuperNote", completion: nil) let notesCount = Helper.countForEntity("SuperNote", inContext: dataStack.mainContext) XCTAssertEqual(notesCount, 5) @@ -654,14 +654,14 @@ class SyncTests: XCTestCase { let usersDictionary = Helper.objectsFromJSON("users_a.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("NotesB") - dataStack.sync(usersDictionary, inEntityNamed: "SuperUserB", completion: nil) + try! dataStack.sync(usersDictionary, inEntityNamed: "SuperUserB", completion: nil) let usersCount = Helper.countForEntity("SuperUserB", inContext: dataStack.mainContext) XCTAssertEqual(usersCount, 8) let notesDictionary = Helper.objectsFromJSON("notes_with_user_id_custom.json") as! [[String: Any]] - dataStack.sync(notesDictionary, inEntityNamed: "SuperNoteB", completion: nil) + try! dataStack.sync(notesDictionary, inEntityNamed: "SuperNoteB", completion: nil) let notesCount = Helper.countForEntity("SuperNoteB", inContext: dataStack.mainContext) XCTAssertEqual(notesCount, 5) @@ -680,7 +680,7 @@ class SyncTests: XCTestCase { let objects = Helper.objectsFromJSON("comments-no-id.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("OrderedSocial") - dataStack.sync(objects, inEntityNamed: "Comment", completion: nil) + try! dataStack.sync(objects, inEntityNamed: "Comment", completion: nil) XCTAssertEqual(Helper.countForEntity("Comment", inContext: dataStack.mainContext), 8) let comments = Helper.fetchEntity("Comment", predicate: NSPredicate(format: "body = %@", "comment 1"), inContext: dataStack.mainContext) @@ -700,8 +700,8 @@ class SyncTests: XCTestCase { let routes = Helper.objectsFromJSON("bug-179-routes.json") as! [String: Any] let dataStack = Helper.dataStackWithModelName("179") - dataStack.sync(places, inEntityNamed: "Place", completion: nil) - dataStack.sync([routes], inEntityNamed: "Route", completion: nil) + try! dataStack.sync(places, inEntityNamed: "Place", completion: nil) + try! dataStack.sync([routes], inEntityNamed: "Route", completion: nil) XCTAssertEqual(Helper.countForEntity("Route", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Place", inContext: dataStack.mainContext), 2) @@ -724,11 +724,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("202") let initialInsert = Helper.objectsFromJSON("bug-202-a.json") as! [[String: Any]] - dataStack.sync(initialInsert, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initialInsert, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) let removeAll = Helper.objectsFromJSON("bug-202-b.json") as! [[String: Any]] - dataStack.sync(removeAll, inEntityNamed: "User", completion: nil) + try! dataStack.sync(removeAll, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) dataStack.drop() @@ -740,7 +740,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("id") let users = Helper.objectsFromJSON("id.json") as! [[String: Any]] - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) dataStack.drop() @@ -753,18 +753,18 @@ class SyncTests: XCTestCase { // 3 locations get synced, their references get ignored since no cities are found let locations = Helper.objectsFromJSON("157-locations.json") as! [[String: Any]] - dataStack.sync(locations, inEntityNamed: "Location", completion: nil) + try! dataStack.sync(locations, inEntityNamed: "Location", completion: nil) XCTAssertEqual(Helper.countForEntity("Location", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("City", inContext: dataStack.mainContext), 0) // 3 cities get synced let cities = Helper.objectsFromJSON("157-cities.json") as! [[String: Any]] - dataStack.sync(cities, inEntityNamed: "City", completion: nil) + try! dataStack.sync(cities, inEntityNamed: "City", completion: nil) XCTAssertEqual(Helper.countForEntity("Location", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("City", inContext: dataStack.mainContext), 3) // 3 locations get synced, but now since their references are available the relationships get made - dataStack.sync(locations, inEntityNamed: "Location", completion: nil) + try! dataStack.sync(locations, inEntityNamed: "Location", completion: nil) var location1 = Helper.fetchEntity("Location", predicate: NSPredicate(format: "locationID = 0"), inContext: dataStack.mainContext).first var location1City = location1?.value(forKey: "city") as? NSManagedObject XCTAssertEqual(location1City?.value(forKey: "name") as? String, "Oslo") @@ -777,7 +777,7 @@ class SyncTests: XCTestCase { // Finally we update the relationships to test changing relationships let updatedLocations = Helper.objectsFromJSON("157-locations-update.json") as! [[String: Any]] - dataStack.sync(updatedLocations, inEntityNamed: "Location", completion: nil) + try! dataStack.sync(updatedLocations, inEntityNamed: "Location", completion: nil) location1 = Helper.fetchEntity("Location", predicate: NSPredicate(format: "locationID = 0"), inContext: dataStack.mainContext).first location1City = location1?.value(forKey: "city") as? NSManagedObject XCTAssertNil(location1City?.value(forKey: "name") as? String) @@ -812,13 +812,13 @@ class SyncTests: XCTestCase { // Inserts 3 users, it ignores the relationships since no notes are found let users = Helper.objectsFromJSON("151-to-many-users.json") as! [[String: Any]] - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 0) // Inserts 3 notes let notes = Helper.objectsFromJSON("151-to-many-notes.json") as! [[String: Any]] - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) let savedUsers = Helper.fetchEntity("User", inContext: dataStack.mainContext) @@ -830,7 +830,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(total, 0) // Updates the first 3 users, but now it makes the relationships with the notes - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) var user10 = Helper.fetchEntity("User", predicate: NSPredicate(format: "userID = 10"), inContext: dataStack.mainContext).first @@ -854,7 +854,7 @@ class SyncTests: XCTestCase { // Updates the first 3 users again, but now it changes all the relationships let updatedUsers = Helper.objectsFromJSON("151-to-many-users-update.json") as! [[String: Any]] - dataStack.sync(updatedUsers, inEntityNamed: "User", completion: nil) + try! dataStack.sync(updatedUsers, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) user10 = Helper.fetchEntity("User", predicate: NSPredicate(format: "userID = 10"), inContext: dataStack.mainContext).first @@ -887,13 +887,13 @@ class SyncTests: XCTestCase { // Inserts 3 users, it ignores the relationships since no notes are found let users = Helper.objectsFromJSON("151-to-many-users.json") as! [[String: Any]] - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 0) // Inserts 3 notes let notes = Helper.objectsFromJSON("151-to-many-notes.json") as! [[String: Any]] - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) let savedUsers = Helper.fetchEntity("User", inContext: dataStack.mainContext) @@ -905,7 +905,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(total, 0) // Updates the first 3 users, but now it makes the relationships with the notes - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) var user10 = Helper.fetchEntity("User", predicate: NSPredicate(format: "id = 10"), inContext: dataStack.mainContext).first @@ -920,7 +920,7 @@ class SyncTests: XCTestCase { // Updates the first 3 users again, but now it changes all the relationships let updatedUsers = Helper.objectsFromJSON("151-to-many-users-update.json") as! [[String: Any]] - dataStack.sync(updatedUsers, inEntityNamed: "User", completion: nil) + try! dataStack.sync(updatedUsers, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 3) user10 = Helper.fetchEntity("User", predicate: NSPredicate(format: "id = 10"), inContext: dataStack.mainContext).first @@ -943,13 +943,13 @@ class SyncTests: XCTestCase { // Inserts 4 notes let notes = Helper.objectsFromJSON("151-many-to-many-notes.json") as! [[String: Any]] - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 0) // Inserts 3 tags let tags = Helper.objectsFromJSON("151-many-to-many-tags.json") as! [[String: Any]] - dataStack.sync(tags, inEntityNamed: "Tag", completion: nil) + try! dataStack.sync(tags, inEntityNamed: "Tag", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) let savedNotes = Helper.fetchEntity("Note", inContext: dataStack.mainContext) @@ -961,7 +961,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(total, 0) // Updates the first 4 notes, but now it makes the relationships with the tags - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) var note0 = Helper.fetchEntity("Note", predicate: NSPredicate(format: "noteID = 0"), inContext: dataStack.mainContext).first @@ -981,7 +981,7 @@ class SyncTests: XCTestCase { let updatedNotes = Helper.objectsFromJSON("151-many-to-many-notes-update.json") as! [[String: Any]] XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) - dataStack.sync(updatedNotes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(updatedNotes, inEntityNamed: "Note", completion: nil) note0 = Helper.fetchEntity("Note", predicate: NSPredicate(format: "noteID = 0"), inContext: dataStack.mainContext).first note0Tags = note0?.value(forKey: "tags") as? Set XCTAssertEqual(note0Tags?.count, 1) @@ -1005,13 +1005,13 @@ class SyncTests: XCTestCase { // Inserts 4 notes let notes = Helper.objectsFromJSON("151-many-to-many-notes.json") as! [[String: Any]] - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 0) // Inserts 3 tags let tags = Helper.objectsFromJSON("151-many-to-many-tags.json") as! [[String: Any]] - dataStack.sync(tags, inEntityNamed: "Tag", completion: nil) + try! dataStack.sync(tags, inEntityNamed: "Tag", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) let savedNotes = Helper.fetchEntity("Note", inContext: dataStack.mainContext) @@ -1023,7 +1023,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(total, 0) // Updates the first 4 notes, but now it makes the relationships with the tags - dataStack.sync(notes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(notes, inEntityNamed: "Note", completion: nil) XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) var note0 = Helper.fetchEntity("Note", predicate: NSPredicate(format: "id = 0"), inContext: dataStack.mainContext).first @@ -1043,7 +1043,7 @@ class SyncTests: XCTestCase { let updatedNotes = Helper.objectsFromJSON("151-many-to-many-notes-update.json") as! [[String: Any]] XCTAssertEqual(Helper.countForEntity("Note", inContext: dataStack.mainContext), 4) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) - dataStack.sync(updatedNotes, inEntityNamed: "Note", completion: nil) + try! dataStack.sync(updatedNotes, inEntityNamed: "Note", completion: nil) note0 = Helper.fetchEntity("Note", predicate: NSPredicate(format: "id = 0"), inContext: dataStack.mainContext).first note0Tags = note0?.value(forKey: "tags") as? NSOrderedSet XCTAssertEqual(note0Tags?.set.count, 1) @@ -1066,7 +1066,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("257") let JSON = Helper.objectsFromJSON("bug-257.json") as! [String: Any] - dataStack.sync([JSON], inEntityNamed: "Workout", completion: nil) + try! dataStack.sync([JSON], inEntityNamed: "Workout", completion: nil) XCTAssertEqual(Helper.countForEntity("Workout", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Exercise", inContext: dataStack.mainContext), 2) @@ -1079,7 +1079,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("254") let JSON = Helper.objectsFromJSON("bug-254.json") as! [String: Any] - dataStack.sync([JSON], inEntityNamed: "House", completion: nil) + try! dataStack.sync([JSON], inEntityNamed: "House", completion: nil) XCTAssertEqual(Helper.countForEntity("House", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Human", inContext: dataStack.mainContext), 1) @@ -1106,7 +1106,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("ToOne") let snakeCaseJSON = Helper.objectsFromJSON("to-one-snakecase.json") as! [String: Any] - dataStack.sync([snakeCaseJSON], inEntityNamed: "RentedHome", completion: nil) + try! dataStack.sync([snakeCaseJSON], inEntityNamed: "RentedHome", completion: nil) XCTAssertEqual(Helper.countForEntity("RentedHome", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("LegalPerson", inContext: dataStack.mainContext), 1) @@ -1117,7 +1117,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("ToOne") let camelCaseJSON = Helper.objectsFromJSON("to-one-camelcase.json") as! [String: Any] - dataStack.sync([camelCaseJSON], inEntityNamed: "RentedHome", completion: nil) + try! dataStack.sync([camelCaseJSON], inEntityNamed: "RentedHome", completion: nil) XCTAssertEqual(Helper.countForEntity("RentedHome", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("LegalPerson", inContext: dataStack.mainContext), 1) @@ -1129,7 +1129,7 @@ class SyncTests: XCTestCase { func testBug239() { let carsObject = Helper.objectsFromJSON("bug-239.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("239") - dataStack.sync(carsObject, inEntityNamed: "Racecar", completion: nil) + try! dataStack.sync(carsObject, inEntityNamed: "Racecar", completion: nil) XCTAssertEqual(Helper.countForEntity("Racecar", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Passenger", inContext: dataStack.mainContext), 2) @@ -1146,13 +1146,13 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("225") let usersA = Helper.objectsFromJSON("225-a.json") as! [[String: Any]] - dataStack.sync(usersA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) // This should remove the old tag reference to the user and insert this new one. let usersB = Helper.objectsFromJSON("225-a-replaced.json") as! [[String: Any]] - dataStack.sync(usersB, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersB, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) @@ -1168,13 +1168,13 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("225") let usersA = Helper.objectsFromJSON("225-a.json") as! [[String: Any]] - dataStack.sync(usersA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) // This should remove all the references. let usersB = Helper.objectsFromJSON("225-a-empty.json") as! [[String: Any]] - dataStack.sync(usersB, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersB, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) @@ -1190,12 +1190,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("225") let usersA = Helper.objectsFromJSON("225-a.json") as! [[String: Any]] - dataStack.sync(usersA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) let usersB = Helper.objectsFromJSON("225-a-null.json") as! [[String: Any]] - dataStack.sync(usersB, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersB, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) @@ -1211,12 +1211,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("280") let routes = Helper.objectsFromJSON("280.json") as! [[String: Any]] - dataStack.sync(routes, inEntityNamed: "Route", completion: nil) + try! dataStack.sync(routes, inEntityNamed: "Route", completion: nil) XCTAssertEqual(Helper.countForEntity("Route", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("RoutePolylineItem", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("RouteStop", inContext: dataStack.mainContext), 1) - dataStack.sync(routes, inEntityNamed: "Route", completion: nil) + try! dataStack.sync(routes, inEntityNamed: "Route", completion: nil) XCTAssertEqual(Helper.countForEntity("Route", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("RoutePolylineItem", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("RouteStop", inContext: dataStack.mainContext), 1) @@ -1228,7 +1228,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("283") let taskLists = Helper.objectsFromJSON("283.json") as! [[String: Any]] - dataStack.sync(taskLists, inEntityNamed: "TaskList", completion: nil) + try! dataStack.sync(taskLists, inEntityNamed: "TaskList", completion: nil) XCTAssertEqual(Helper.countForEntity("TaskList", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Owner", inContext: dataStack.mainContext), 1) @@ -1258,7 +1258,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) let usersB = Helper.objectsFromJSON("320.json") as! [[String: Any]] - dataStack.sync(usersB, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersB, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) @@ -1298,7 +1298,7 @@ class SyncTests: XCTestCase { // Change order of slides, before it was [1, 2], now it will be [2, 1] let presentationOrderB = Helper.objectsFromJSON("233.json") as! [[String: Any]] - dataStack.sync(presentationOrderB, inEntityNamed: "Presentation", completion: nil) + try! dataStack.sync(presentationOrderB, inEntityNamed: "Presentation", completion: nil) XCTAssertEqual(Helper.countForEntity("Presentation", inContext: dataStack.mainContext), 1) @@ -1341,7 +1341,7 @@ class SyncTests: XCTestCase { // Change order of slides, before it was [1, 2], now it will be [2, 1] let presentationOrderB = Helper.objectsFromJSON("237.json") as! [[String: Any]] - dataStack.sync(presentationOrderB, inEntityNamed: "Presentation", completion: nil) + try! dataStack.sync(presentationOrderB, inEntityNamed: "Presentation", completion: nil) XCTAssertEqual(Helper.countForEntity("Presentation", inContext: dataStack.mainContext), 1) @@ -1359,7 +1359,7 @@ class SyncTests: XCTestCase { func test265() { let dataStack = Helper.dataStackWithModelName("265") let players = Helper.objectsFromJSON("265.json") as! [[String: Any]] - dataStack.sync(players, inEntityNamed: "Player", completion: nil) + try! dataStack.sync(players, inEntityNamed: "Player", completion: nil) // Player 1 // Has one player group: 1 @@ -1377,7 +1377,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("3ca82a0") let taskLists = Helper.objectsFromJSON("3ca82a0.json") as! [[String: Any]] - dataStack.sync(taskLists, inEntityNamed: "Article", completion: nil) + try! dataStack.sync(taskLists, inEntityNamed: "Article", completion: nil) XCTAssertEqual(Helper.countForEntity("Article", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("ArticleTag", inContext: dataStack.mainContext), 1) @@ -1389,7 +1389,7 @@ class SyncTests: XCTestCase { func test277() { let carsObject = Helper.objectsFromJSON("277.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("277") - dataStack.sync(carsObject, inEntityNamed: "Racecar", completion: nil) + try! dataStack.sync(carsObject, inEntityNamed: "Racecar", completion: nil) XCTAssertEqual(Helper.countForEntity("Racecar", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("Passenger", inContext: dataStack.mainContext), 1) @@ -1410,7 +1410,7 @@ class SyncTests: XCTestCase { func test375() { let speeches = Helper.objectsFromJSON("375.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("375") - dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) + try! dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) XCTAssertEqual(Helper.countForEntity("Speech", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) @@ -1421,7 +1421,7 @@ class SyncTests: XCTestCase { func test375toOne() { let speeches = Helper.objectsFromJSON("375-to-one.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("375-to-one") - dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) + try! dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) XCTAssertEqual(Helper.countForEntity("Speech", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) dataStack.drop() @@ -1432,10 +1432,10 @@ class SyncTests: XCTestCase { let speeches = Helper.objectsFromJSON("375-to-many-speeches.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("375") - dataStack.sync(series, inEntityNamed: "Serie", completion: nil) + try! dataStack.sync(series, inEntityNamed: "Serie", completion: nil) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) - dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) + try! dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) XCTAssertEqual(Helper.countForEntity("Speech", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) let speech = Helper.fetchEntity("Speech", predicate: NSPredicate(format: "id = 4865"), inContext: dataStack.mainContext).first @@ -1450,10 +1450,10 @@ class SyncTests: XCTestCase { let speeches = Helper.objectsFromJSON("375-to-one-speeches.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("375-to-one") - dataStack.sync(series, inEntityNamed: "Serie", completion: nil) + try! dataStack.sync(series, inEntityNamed: "Serie", completion: nil) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) - dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) + try! dataStack.sync(speeches, inEntityNamed: "Speech", completion: nil) XCTAssertEqual(Helper.countForEntity("Speech", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Serie", inContext: dataStack.mainContext), 1) let speech = Helper.fetchEntity("Speech", predicate: NSPredicate(format: "id = 4865"), inContext: dataStack.mainContext).first! @@ -1467,7 +1467,7 @@ class SyncTests: XCTestCase { func testRemoteKeyCompatibility() { let entititesJSON = Helper.objectsFromJSON("remote_key.json") as! [[String: Any]] let dataStack = Helper.dataStackWithModelName("RemoteKey") - dataStack.sync(entititesJSON, inEntityNamed: "Entity", completion: nil) + try! dataStack.sync(entititesJSON, inEntityNamed: "Entity", completion: nil) XCTAssertEqual(Helper.countForEntity("Entity", inContext: dataStack.mainContext), 1) let entity = Helper.fetchEntity("Entity", inContext: dataStack.mainContext).first! @@ -1483,7 +1483,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("225") let usersA = Helper.objectsFromJSON("417.json") as! [[String: Any]] - dataStack.sync(usersA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) @@ -1495,7 +1495,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("225") let usersA = Helper.objectsFromJSON("373.json") as! [[String: Any]] - dataStack.sync(usersA, inEntityNamed: "User", completion: nil) + try! dataStack.sync(usersA, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 2) @@ -1515,7 +1515,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("412") let forms = Helper.objectsFromJSON("412.json") as! [[String: Any]] - dataStack.sync(forms, inEntityNamed: "Form", completion: nil) + try! dataStack.sync(forms, inEntityNamed: "Form", completion: nil) XCTAssertEqual(Helper.countForEntity("Form", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Field", inContext: dataStack.mainContext), 0) @@ -1527,20 +1527,20 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("DoublePrimaryKeys") let users = Helper.objectsFromJSON("primary-key-users.json") as! [[String: Any]] - dataStack.sync(users, inEntityNamed: "User", completion: nil) + try! dataStack.sync(users, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Category", inContext: dataStack.mainContext), 1) let organizations = Helper.objectsFromJSON("primary-key-organizations.json") as! [[String: Any]] - dataStack.sync(organizations, inEntityNamed: "Organization", completion: nil) + try! dataStack.sync(organizations, inEntityNamed: "Organization", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Category", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("Organization", inContext: dataStack.mainContext), 1) let organizations2 = Helper.objectsFromJSON("primary-key-organizations-update.json") as! [[String: Any]] - dataStack.sync(organizations2, inEntityNamed: "Organization", completion: nil) + try! dataStack.sync(organizations2, inEntityNamed: "Organization", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Category", inContext: dataStack.mainContext), 2) @@ -1554,7 +1554,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("447") let website = Helper.objectsFromJSON("447.json") as! [[String: Any]] - dataStack.sync(website, inEntityNamed: "Website", completion: nil) + try! dataStack.sync(website, inEntityNamed: "Website", completion: nil) XCTAssertEqual(Helper.countForEntity("Website", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Tag", inContext: dataStack.mainContext), 1) @@ -1568,13 +1568,13 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("457") let subcats = Helper.objectsFromJSON("457-subcategories.json") as! [[String: Any]] - dataStack.sync(subcats, inEntityNamed: "Subcategory", completion: nil) + try! dataStack.sync(subcats, inEntityNamed: "Subcategory", completion: nil) XCTAssertEqual(Helper.countForEntity("Subcategory", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Category", inContext: dataStack.mainContext), 1) let products = Helper.objectsFromJSON("457-products.json") as! [[String: Any]] - dataStack.sync(products, inEntityNamed: "Product", completion: nil) + try! dataStack.sync(products, inEntityNamed: "Product", completion: nil) let result = Helper.fetchEntity("Product", inContext: dataStack.mainContext) XCTAssertEqual(result.count, 1) @@ -1594,12 +1594,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422OneToMany") let initial = Helper.objectsFromJSON("422-one-to-many-insert-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) let updated = Helper.objectsFromJSON("422-one-to-many-insert-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .insertRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .insertRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 2) @@ -1613,12 +1613,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422OneToMany") let initial = Helper.objectsFromJSON("422-one-to-many-update-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) let updated = Helper.objectsFromJSON("422-one-to-many-update-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .updateRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .updateRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) @@ -1632,12 +1632,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422OneToMany") let initial = Helper.objectsFromJSON("422-one-to-many-delete-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 2) let updated = Helper.objectsFromJSON("422-one-to-many-delete-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .deleteRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .deleteRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) @@ -1655,12 +1655,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422ManyToMany") let initial = Helper.objectsFromJSON("422-many-to-many-insert-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) let updated = Helper.objectsFromJSON("422-many-to-many-insert-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .insertRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .insertRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 2) @@ -1674,12 +1674,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422ManyToMany") let initial = Helper.objectsFromJSON("422-many-to-many-update-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) let updated = Helper.objectsFromJSON("422-many-to-many-update-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .updateRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .updateRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 1) @@ -1693,12 +1693,12 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("422ManyToMany") let initial = Helper.objectsFromJSON("422-many-to-many-delete-option-initial.json") as! [[String: Any]] - dataStack.sync(initial, inEntityNamed: "User", completion: nil) + try! dataStack.sync(initial, inEntityNamed: "User", completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Message", inContext: dataStack.mainContext), 2) let updated = Helper.objectsFromJSON("422-many-to-many-delete-option-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .deleteRelationships], completion: nil) + try! dataStack.sync(updated, inEntityNamed: "User", operations: [.insert, .update, .delete, .deleteRelationships], completion: nil) XCTAssertEqual(Helper.countForEntity("User", inContext: dataStack.mainContext), 1) // count the messages that user 1 has instead of counting all messages let userMessageCount = Helper.countForEntity("Message", predicate: NSPredicate(format: "ANY users.id = 1"), inContext: dataStack.mainContext) @@ -1715,7 +1715,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("476") let data = Helper.objectsFromJSON("476.json") as! [[String: Any]] - dataStack.sync(data, inEntityNamed: "FitnessProfile", completion: nil) + try! dataStack.sync(data, inEntityNamed: "FitnessProfile", completion: nil) XCTAssertEqual(Helper.countForEntity("FitnessProfile", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("UserWeight", inContext: dataStack.mainContext), 1) @@ -1727,7 +1727,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("480") let data = Helper.objectsFromJSON("480.json") as! [[String: Any]] - dataStack.sync(data, inEntityNamed: "Report", completion: nil) + try! dataStack.sync(data, inEntityNamed: "Report", completion: nil) XCTAssertEqual(Helper.countForEntity("Report", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("HistoryItem", inContext: dataStack.mainContext), 6) @@ -1740,7 +1740,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("519") let data = Helper.objectsFromJSON("519.json") as! [[String: Any]] - dataStack.sync(data, inEntityNamed: "Book", completion: nil) + try! dataStack.sync(data, inEntityNamed: "Book", completion: nil) XCTAssertEqual(Helper.countForEntity("Book", inContext: dataStack.mainContext), 2) XCTAssertEqual(Helper.countForEntity("Author", inContext: dataStack.mainContext), 3) @@ -1753,11 +1753,11 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("ordered-many-to-many-update") let initialItems = Helper.objectsFromJSON("inital-ordered-many-to-many-update.json") as! [[String: Any]] - dataStack.sync(initialItems, inEntityNamed:"Item", completion: nil) + try! dataStack.sync(initialItems, inEntityNamed:"Item", completion: nil) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 5) let initialList = Helper.objectsFromJSON("ordered-many-to-many-update-inital.json") as! [[String: Any]] - dataStack.sync(initialList, inEntityNamed:"List", completion: nil) + try! dataStack.sync(initialList, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 5) @@ -1766,7 +1766,7 @@ class SyncTests: XCTestCase { XCTAssertEqual(unpopulatedListItems.count, 0) let updated = Helper.objectsFromJSON("ordered-many-to-many-update-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed:"List", completion: nil) + try! dataStack.sync(updated, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 5) @@ -1788,7 +1788,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("ordered-many-to-many-update") let initialItems = Helper.objectsFromJSON("453-to-many-ordered-relationship-objects-initial.json") as! [[String: Any]] - dataStack.sync(initialItems, inEntityNamed:"List", completion: nil) + try! dataStack.sync(initialItems, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) @@ -1800,7 +1800,7 @@ class SyncTests: XCTestCase { XCTAssertEqual((items.lastObject as! NSManagedObject).value(forKey:"id") as? Int16, 3) let updated = Helper.objectsFromJSON("453-to-many-ordered-relationship-objects-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed:"List", completion: nil) + try! dataStack.sync(updated, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 4) @@ -1819,7 +1819,7 @@ class SyncTests: XCTestCase { let dataStack = Helper.dataStackWithModelName("ordered-many-to-many-update") let initialItems = Helper.objectsFromJSON("453-to-many-ordered-relationship-objects-initial.json") as! [[String: Any]] - dataStack.sync(initialItems, inEntityNamed:"List", completion: nil) + try! dataStack.sync(initialItems, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 3) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) @@ -1832,11 +1832,11 @@ class SyncTests: XCTestCase { // Add the future 2 items 4, 5 since we're sycing by ids. let additionalItems = Helper.objectsFromJSON("453-to-many-ordered-relationship-item-insert.json") as! [[String: Any]] - dataStack.sync(additionalItems, inEntityNamed:"Item", completion: nil) + try! dataStack.sync(additionalItems, inEntityNamed:"Item", completion: nil) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 5) let updated = Helper.objectsFromJSON("453-to-many-ordered-relationship-ids-update.json") as! [[String: Any]] - dataStack.sync(updated, inEntityNamed:"List", completion: nil) + try! dataStack.sync(updated, inEntityNamed:"List", completion: nil) XCTAssertEqual(Helper.countForEntity("List", inContext: dataStack.mainContext), 1) XCTAssertEqual(Helper.countForEntity("Item", inContext: dataStack.mainContext), 5)