diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 719c0a8..56ab788 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -14,7 +14,7 @@ 82BA18931C4BBCBA00A0916E /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82BA18891C4BBCBA00A0916E /* CoreStore.framework */; }; 82BA18A01C4BBD1400A0916E /* CoreStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F03A53519C5C6DA005002A5 /* CoreStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; 82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F291E2619C6D3CF007AF63F /* CoreStore.swift */; }; - 82BA18A21C4BBD1D00A0916E /* NSError+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */; }; + 82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; 82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; }; 82BA18A41C4BBD2200A0916E /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDE1AFF84500064E85B /* SetupResult.swift */; }; 82BA18A51C4BBD2200A0916E /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; }; @@ -92,7 +92,7 @@ B52DD1921BE1F8F000949AFE /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5548CD71BD65AE50077652A /* CoreData.framework */; }; B52DD1931BE1F8FD00949AFE /* CoreStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F03A53519C5C6DA005002A5 /* CoreStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F291E2619C6D3CF007AF63F /* CoreStore.swift */; }; - B52DD1951BE1F92500949AFE /* NSError+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */; }; + B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; }; B52DD1971BE1F92500949AFE /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDE1AFF84500064E85B /* SetupResult.swift */; }; B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; }; @@ -154,7 +154,7 @@ B563217C1BD650E3006C9394 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B563217B1BD650E3006C9394 /* Foundation.framework */; }; B563217E1BD65110006C9394 /* CoreStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F03A53519C5C6DA005002A5 /* CoreStore.h */; settings = {ATTRIBUTES = (Public, ); }; }; B563217F1BD65216006C9394 /* CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F291E2619C6D3CF007AF63F /* CoreStore.swift */; }; - B56321801BD65216006C9394 /* NSError+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */; }; + B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; B56321811BD65216006C9394 /* DataStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDB1AFF84500064E85B /* DataStack.swift */; }; B56321821BD65216006C9394 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EDE1AFF84500064E85B /* SetupResult.swift */; }; B56321831BD65216006C9394 /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; }; @@ -223,7 +223,7 @@ B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; }; - B5D1E22C19FA9FBC003B2874 /* NSError+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */; }; + B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; }; B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; }; B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D372851A39CDDB00F583D9 /* TestEntity1.swift */; }; B5D39A0219FD00C9000E91BB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D39A0119FD00C9000E91BB /* Foundation.framework */; }; @@ -364,7 +364,7 @@ B5BDC9271C2024F2008147CD /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; }; B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = ""; }; B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = ""; }; - B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSError+CoreStore.swift"; sourceTree = ""; }; + B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = ""; }; B5D372831A39CD6900F583D9 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = ""; }; B5D372851A39CDDB00F583D9 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = ""; }; B5D39A0119FD00C9000E91BB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; @@ -521,7 +521,7 @@ children = ( 2F03A53519C5C6DA005002A5 /* CoreStore.h */, 2F291E2619C6D3CF007AF63F /* CoreStore.swift */, - B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */, + B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */, B5E84EDA1AFF84500064E85B /* Setting Up */, B51F25981C5747790083A5DD /* iCloud */, B5E84EE21AFF84610064E85B /* Logging */, @@ -1030,7 +1030,7 @@ B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */, B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */, B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */, - B5D1E22C19FA9FBC003B2874 /* NSError+CoreStore.swift in Sources */, + B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */, B5E84F131AFF847B0064E85B /* Where.swift in Sources */, B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */, B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */, @@ -1114,7 +1114,7 @@ files = ( 82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */, B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */, - 82BA18A21C4BBD1D00A0916E /* NSError+CoreStore.swift in Sources */, + 82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */, 82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */, 82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */, 82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */, @@ -1199,7 +1199,7 @@ buildActionMask = 2147483647; files = ( B52DD1BE1BE1F94300949AFE /* NSProgress+Convenience.swift in Sources */, - B52DD1951BE1F92500949AFE /* NSError+CoreStore.swift in Sources */, + B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */, B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */, B5FEC1911C9166E700532541 /* NSPersistentStore+Setup.swift in Sources */, B52DD1AB1BE1F93900949AFE /* From.swift in Sources */, @@ -1275,7 +1275,7 @@ files = ( B56321A91BD65219006C9394 /* NSProgress+Convenience.swift in Sources */, B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */, - B56321801BD65216006C9394 /* NSError+CoreStore.swift in Sources */, + B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */, B56321AD1BD6521C006C9394 /* MigrationManager.swift in Sources */, B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */, B56321961BD65216006C9394 /* From.swift in Sources */, diff --git a/Sources/NSError+CoreStore.swift b/Sources/CoreStoreError.swift similarity index 54% rename from Sources/NSError+CoreStore.swift rename to Sources/CoreStoreError.swift index 8e54555..6e23a99 100644 --- a/Sources/NSError+CoreStore.swift +++ b/Sources/CoreStoreError.swift @@ -1,5 +1,5 @@ // -// NSError+CoreStore.swift +// CoreStoreError.swift // CoreStore // // Copyright © 2014 John Rommel Estropia @@ -29,14 +29,102 @@ import CoreData // MARK: - CoreStoreError +public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStringConvertible { + + /** + A failure occured because of an unknown error. + */ + case Unknown + + /** + The `NSPersistentStore` could note be initialized because another store existed at the specified `NSURL`. + */ + case DifferentStorageExistsAtURL(existingPersistentStoreURL: NSURL) + + /** + An `NSMappingModel` could not be found for a specific source and destination model versions. + */ + case MappingModelNotFound(storage: LocalStorage, targetModel: NSManagedObjectModel, targetModelVersion: String) + + /** + Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions. + */ + case ProgressiveMigrationRequired(storage: LocalStorage) + + /** + An internal SDK call failed with the specified `NSError`. + */ + case InternalError(NSError) + + + // MARK: ErrorType + + public var _domain: String { + + return "com.corestore.error" + } + + public var _code: Int { + + switch self { + + case .Unknown: return 1 + case .DifferentStorageExistsAtURL: return 2 + case .MappingModelNotFound: return 3 + case .ProgressiveMigrationRequired: return 4 + case .InternalError: return 5 + } + } + + + // MARK: CustomStringConvertible + + public var description: String { + + // TODO: + return (self as NSError).description + } + + + // MARK: CustomDebugStringConvertible + + public var debugDescription: String { + + return self.description + } + + + // MARK: Internal + + internal init(_ error: ErrorType?) { + + switch error { + + case (let error as CoreStoreError)?: + self = error + + case (let error as NSError)?: + self = .InternalError(error) + + default: + self = .Unknown + } + } +} + + +// MARK: - CoreStoreErrorCode + /** The `NSError` error domain for `CoreStore`. */ +@available(*, deprecated=2.0.0, message="Use CoreStoreError enum values instead.") public let CoreStoreErrorDomain = "com.corestore.error" /** The `NSError` error codes for `CoreStoreErrorDomain`. */ +@available(*, deprecated=2.0.0, message="Use CoreStoreError enum values instead.") public enum CoreStoreErrorCode: Int { /** @@ -49,11 +137,6 @@ public enum CoreStoreErrorCode: Int { */ case DifferentPersistentStoreExistsAtURL - /** - The `NSPersistentStore` specified could not be found. - */ - case PersistentStoreNotFound - /** An `NSMappingModel` could not be found for a specific source and destination model versions. */ @@ -70,32 +153,8 @@ public enum CoreStoreErrorCode: Int { public extension NSError { - /** - If the error's domain is equal to `CoreStoreErrorDomain`, returns the associated `CoreStoreErrorCode`. For other domains, returns `nil`. - */ - public var coreStoreErrorCode: CoreStoreErrorCode? { - - return (self.domain == CoreStoreErrorDomain - ? CoreStoreErrorCode(rawValue: self.code) - : nil) - } - - // MARK: Internal - internal convenience init(coreStoreErrorCode: CoreStoreErrorCode) { - - self.init(coreStoreErrorCode: coreStoreErrorCode, userInfo: nil) - } - - internal convenience init(coreStoreErrorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) { - - self.init( - domain: CoreStoreErrorDomain, - code: coreStoreErrorCode.rawValue, - userInfo: userInfo) - } - internal var isCoreDataMigrationError: Bool { let code = self.code @@ -104,4 +163,18 @@ public extension NSError { || code == NSMigrationError) && self.domain == NSCocoaErrorDomain } + + + // MARK: Deprecated + + /** + If the error's domain is equal to `CoreStoreErrorDomain`, returns the associated `CoreStoreErrorCode`. For other domains, returns `nil`. + */ + @available(*, deprecated=2.0.0, message="Use CoreStoreError enum values instead.") + public var coreStoreErrorCode: CoreStoreErrorCode? { + + return (self.domain == CoreStoreErrorDomain + ? CoreStoreErrorCode(rawValue: self.code) + : nil) + } } diff --git a/Sources/Internal/NSManagedObjectContext+CoreStore.swift b/Sources/Internal/NSManagedObjectContext+CoreStore.swift index ffcc064..3231453 100644 --- a/Sources/Internal/NSManagedObjectContext+CoreStore.swift +++ b/Sources/Internal/NSManagedObjectContext+CoreStore.swift @@ -96,8 +96,8 @@ internal extension NSManagedObjectContext { } catch { - CoreStore.handleError( - error as NSError, + CoreStore.log( + CoreStoreError(error), "Failed to obtain permanent ID(s) for \(numberOfInsertedObjects) inserted object(s)." ) } diff --git a/Sources/Internal/NSManagedObjectContext+Querying.swift b/Sources/Internal/NSManagedObjectContext+Querying.swift index 7beb916..2e2f63f 100644 --- a/Sources/Internal/NSManagedObjectContext+Querying.swift +++ b/Sources/Internal/NSManagedObjectContext+Querying.swift @@ -46,8 +46,8 @@ internal extension NSManagedObjectContext { } catch { - CoreStore.handleError( - error as NSError, + CoreStore.log( + CoreStoreError(error), "Failed to obtain permanent ID for object." ) return nil @@ -61,8 +61,8 @@ internal extension NSManagedObjectContext { } catch { - CoreStore.handleError( - error as NSError, + CoreStore.log( + CoreStoreError(error), "Failed to load existing \(typeName(object)) in context." ) return nil @@ -88,7 +88,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [T]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -97,13 +97,13 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if fetchResults == nil { - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -131,7 +131,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [T]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -140,13 +140,13 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if fetchResults == nil { - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -178,8 +178,8 @@ internal extension NSManagedObjectContext { } if count == NSNotFound { - CoreStore.handleError( - error ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(error), "Failed executing fetch request." ) return nil @@ -207,7 +207,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [NSManagedObjectID]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -216,13 +216,13 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if fetchResults == nil { - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -250,7 +250,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [NSManagedObjectID]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -259,13 +259,13 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if fetchResults == nil { - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -295,7 +295,7 @@ internal extension NSManagedObjectContext { } var numberOfDeletedObjects: Int? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { autoreleasepool { @@ -311,14 +311,14 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } } if numberOfDeletedObjects == nil { - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -347,7 +347,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [AnyObject]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -356,7 +356,7 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if let fetchResults = fetchResults { @@ -369,8 +369,8 @@ internal extension NSManagedObjectContext { return nil } - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil @@ -396,7 +396,7 @@ internal extension NSManagedObjectContext { } var fetchResults: [AnyObject]? - var fetchError: NSError? + var fetchError: ErrorType? self.performBlockAndWait { do { @@ -405,7 +405,7 @@ internal extension NSManagedObjectContext { } catch { - fetchError = error as NSError + fetchError = error } } if let fetchResults = fetchResults { @@ -413,8 +413,8 @@ internal extension NSManagedObjectContext { return Select.ReturnType.fromResultObjects(fetchResults) } - CoreStore.handleError( - fetchError ?? NSError(coreStoreErrorCode: .UnknownError), + CoreStore.log( + CoreStoreError(fetchError), "Failed executing fetch request." ) return nil diff --git a/Sources/Internal/NSManagedObjectContext+Transaction.swift b/Sources/Internal/NSManagedObjectContext+Transaction.swift index 255db60..eafcebc 100644 --- a/Sources/Internal/NSManagedObjectContext+Transaction.swift +++ b/Sources/Internal/NSManagedObjectContext+Transaction.swift @@ -93,8 +93,8 @@ internal extension NSManagedObjectContext { } catch { - let saveError = error as NSError - CoreStore.handleError( + let saveError = CoreStoreError(error) + CoreStore.log( saveError, "Failed to save \(typeName(NSManagedObjectContext))." ) @@ -141,8 +141,8 @@ internal extension NSManagedObjectContext { } catch { - let saveError = error as NSError - CoreStore.handleError( + let saveError = CoreStoreError(error) + CoreStore.log( saveError, "Failed to save \(typeName(NSManagedObjectContext))." ) diff --git a/Sources/Internal/NSPersistentStoreCoordinator+Setup.swift b/Sources/Internal/NSPersistentStoreCoordinator+Setup.swift index d637ba8..b99cfa5 100644 --- a/Sources/Internal/NSPersistentStoreCoordinator+Setup.swift +++ b/Sources/Internal/NSPersistentStoreCoordinator+Setup.swift @@ -84,6 +84,6 @@ internal extension NSPersistentStoreCoordinator { return store } - throw storeError ?? NSError(coreStoreErrorCode: .UnknownError) + throw CoreStoreError(storeError) } } \ No newline at end of file diff --git a/Sources/Logging/CoreStore+Logging.swift b/Sources/Logging/CoreStore+Logging.swift index 76a3bc7..78ab487 100644 --- a/Sources/Logging/CoreStore+Logging.swift +++ b/Sources/Logging/CoreStore+Logging.swift @@ -49,9 +49,9 @@ public extension CoreStore { ) } - internal static func handleError(error: NSError, _ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) { + internal static func log(error: CoreStoreError, _ message: String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) { - self.logger.handleError( + self.logger.log( error: error, message: message, fileName: fileName, diff --git a/Sources/Logging/CoreStoreLogger.swift b/Sources/Logging/CoreStoreLogger.swift index 6a6652b..83c34c8 100644 --- a/Sources/Logging/CoreStoreLogger.swift +++ b/Sources/Logging/CoreStoreLogger.swift @@ -67,7 +67,7 @@ public protocol CoreStoreLogger { :lineNumber: the source line number :functionName: the source function name */ - func handleError(error error: NSError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) + func log(error error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) /** Handles assertions made throughout the `CoreStore` framework. @@ -79,6 +79,24 @@ public protocol CoreStoreLogger { :functionName: the source function name */ func assert(@autoclosure condition: () -> Bool, @autoclosure message: () -> String, fileName: StaticString, lineNumber: Int, functionName: StaticString) + + + // MARK: Deprecated + + /** + Deprecated. Use `log(error:message:fileName:lineNumber:functionName:)` instead. + */ + @available(*, deprecated=2.0.0, message="Use log(error:message:fileName:lineNumber:functionName:) instead.") + func handleError(error error: NSError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) +} + +extension CoreStoreLogger { + + /** + Deprecated. Use `log(error:message:fileName:lineNumber:functionName:)` instead. + */ + @available(*, deprecated=2.0.0, message="Use log(error:message:fileName:lineNumber:functionName:) instead.") + public func handleError(error error: NSError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {} } diff --git a/Sources/Logging/DefaultLogger.swift b/Sources/Logging/DefaultLogger.swift index 8cff94f..c4cdbfb 100644 --- a/Sources/Logging/DefaultLogger.swift +++ b/Sources/Logging/DefaultLogger.swift @@ -66,7 +66,7 @@ public final class DefaultLogger: CoreStoreLogger { #endif } - public func handleError(error error: NSError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { + public func log(error error: CoreStoreError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { #if DEBUG Swift.print("⚠️ [CoreStore: Error] \((fileName.stringValue as NSString).lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ \(message)\n \(error)\n") diff --git a/Sources/Migrating/DataStack+Migration.swift b/Sources/Migrating/DataStack+Migration.swift index 5e965bc..e979444 100644 --- a/Sources/Migrating/DataStack+Migration.swift +++ b/Sources/Migrating/DataStack+Migration.swift @@ -101,8 +101,8 @@ public extension DataStack { } catch { - let storeError = error as NSError - CoreStore.handleError( + let storeError = CoreStoreError(error) + CoreStore.log( storeError, "Failed to add \(typeName(storage)) to the stack." ) @@ -187,8 +187,8 @@ public extension DataStack { return nil } - let error = NSError(coreStoreErrorCode: .DifferentPersistentStoreExistsAtURL) - CoreStore.handleError( + let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: fileURL) + CoreStore.log( error, "Failed to add \(typeName(storage)) at \"\(fileURL)\" because a different \(typeName(NSPersistentStore)) at that URL already exists." ) @@ -214,7 +214,7 @@ public extension DataStack { metadata: metadata, completion: { (result) -> Void in - if case .Failure(let error) = result { + if case .Failure(.InternalError(let error)) = result { if storage.localStorageOptions.contains(.RecreateStoreOnModelMismatch) && error.isCoreDataMigrationError { @@ -230,7 +230,7 @@ public extension DataStack { } catch { - completion(SetupResult(error as NSError)) + completion(SetupResult(error)) } return } @@ -247,7 +247,7 @@ public extension DataStack { } catch { - completion(SetupResult(error as NSError)) + completion(SetupResult(error)) } } ) @@ -265,11 +265,12 @@ public extension DataStack { } catch { - CoreStore.handleError( - error as NSError, + let storeError = CoreStoreError(error) + CoreStore.log( + storeError, "Failed to load SQLite \(typeName(NSPersistentStore)) metadata." ) - throw error + throw storeError } } } @@ -306,11 +307,12 @@ public extension DataStack { } catch { - CoreStore.handleError( - error as NSError, + let metadataError = CoreStoreError(error) + CoreStore.log( + metadataError, "Failed to load \(typeName(storage)) metadata from URL \"\(fileURL)\"." ) - throw error + throw metadataError } } } @@ -342,8 +344,12 @@ public extension DataStack { guard let migrationSteps = self.computeMigrationFromStorage(storage, metadata: metadata) else { - let error = NSError(coreStoreErrorCode: .MappingModelNotFound) - CoreStore.handleError( + let error = CoreStoreError.MappingModelNotFound( + storage: storage, + targetModel: self.model, + targetModelVersion: self.modelVersion + ) + CoreStore.log( error, "Failed to find migration steps from the \(typeName(storage)) at URL \"\(fileURL)\" to version model \"\(self.modelVersion)\"." ) @@ -352,8 +358,8 @@ public extension DataStack { if migrationSteps.count > 1 && storage.localStorageOptions.contains(.PreventProgressiveMigration) { - let error = NSError(coreStoreErrorCode: .ProgressiveMigrationRequired) - CoreStore.handleError( + let error = CoreStoreError.ProgressiveMigrationRequired(storage: storage) + CoreStore.log( error, "Failed to find migration mapping from the \(typeName(storage)) at URL \"\(fileURL)\" to version model \"\(self.modelVersion)\" without requiring progessive migrations." ) @@ -369,11 +375,12 @@ public extension DataStack { } catch { - CoreStore.handleError( - error as NSError, + let metadataError = CoreStoreError(error) + CoreStore.log( + metadataError, "Failed to load \(typeName(storage)) metadata from URL \"\(fileURL)\"." ) - throw error + throw metadataError } } } @@ -385,14 +392,19 @@ public extension DataStack { guard let migrationSteps = self.computeMigrationFromStorage(storage, metadata: metadata) else { - CoreStore.handleError( - NSError(coreStoreErrorCode: .MappingModelNotFound), - "Failed to find migration steps from \(typeName(storage)) at URL \"\(storage.fileURL )\" to version model \"\(model)\"." + let error = CoreStoreError.MappingModelNotFound( + storage: storage, + targetModel: self.model, + targetModelVersion: self.modelVersion + ) + CoreStore.log( + error, + "Failed to find migration steps from \(typeName(storage)) at URL \"\(storage.fileURL)\" to version model \"\(self.model)\"." ) GCDQueue.Main.async { - completion(MigrationResult(.MappingModelNotFound)) + completion(MigrationResult(error)) } return nil } @@ -409,14 +421,14 @@ public extension DataStack { } else if numberOfMigrations > 1 && storage.localStorageOptions.contains(.PreventProgressiveMigration) { - let error = NSError(coreStoreErrorCode: .ProgressiveMigrationRequired) - CoreStore.handleError( + let error = CoreStoreError.ProgressiveMigrationRequired(storage: storage) + CoreStore.log( error, "Failed to find migration mapping from the \(typeName(storage)) at URL \"\(storage.fileURL)\" to version model \"\(self.modelVersion)\" without requiring progessive migrations." ) GCDQueue.Main.async { - completion(MigrationResult(.ProgressiveMigrationRequired)) + completion(MigrationResult(error)) } return nil } @@ -458,7 +470,7 @@ public extension DataStack { } catch { - migrationResult = MigrationResult(error as NSError) + migrationResult = MigrationResult(error) cancelled = true } } @@ -619,12 +631,13 @@ public extension DataStack { let sourceVersion = migrationManager.sourceModel.currentModelVersion ?? "???" let destinationVersion = migrationManager.destinationModel.currentModelVersion ?? "???" - CoreStore.handleError( - error as NSError, + let migrationError = CoreStoreError(error) + CoreStore.log( + migrationError, "Failed to migrate from version model \"\(sourceVersion)\" to version model \"\(destinationVersion)\"." ) - throw error + throw migrationError } do { @@ -649,12 +662,13 @@ public extension DataStack { let sourceVersion = migrationManager.sourceModel.currentModelVersion ?? "???" let destinationVersion = migrationManager.destinationModel.currentModelVersion ?? "???" - CoreStore.handleError( - error as NSError, + let fileError = CoreStoreError(error) + CoreStore.log( + fileError, "Failed to save store after migrating from version model \"\(sourceVersion)\" to version model \"\(destinationVersion)\"." ) - throw error + throw fileError } } @@ -679,7 +693,7 @@ public extension DataStack { completion(PersistentStoreResult(self.persistentStoreForStorage(storage)!)) case .Failure(let error): - completion(PersistentStoreResult(error)) + completion(PersistentStoreResult(error as NSError)) } } ) @@ -713,7 +727,7 @@ public extension DataStack { completion(PersistentStoreResult(self.persistentStoreForStorage(storage)!)) case .Failure(let error): - completion(PersistentStoreResult(error)) + completion(PersistentStoreResult(error as NSError)) } } ) @@ -742,7 +756,7 @@ public extension DataStack { completion(PersistentStoreResult(self.persistentStoreForStorage(storage)!)) case .Failure(let error): - completion(PersistentStoreResult(error)) + completion(PersistentStoreResult(error as NSError)) } } ) diff --git a/Sources/Migrating/MigrationResult.swift b/Sources/Migrating/MigrationResult.swift index 00d1c32..5450814 100644 --- a/Sources/Migrating/MigrationResult.swift +++ b/Sources/Migrating/MigrationResult.swift @@ -52,7 +52,7 @@ import Foundation case .Success(let hasChanges): // hasChanges indicates if there were changes or not case .Failure(let error): - // error is the NSError instance for the failure + // error is a CoreStoreError enum value } } ``` @@ -65,9 +65,9 @@ public enum MigrationResult { case Success([MigrationType]) /** - `SaveResult.Failure` indicates that the migration failed. The associated object for this value is the related `NSError` instance. + `SaveResult.Failure` indicates that the migration failed. The associated object for this value is the a `CoreStoreError` enum value. */ - case Failure(NSError) + case Failure(CoreStoreError) // MARK: Internal @@ -77,19 +77,14 @@ public enum MigrationResult { self = .Success(migrationTypes) } - internal init(_ error: NSError) { + internal init(_ error: CoreStoreError) { self = .Failure(error) } - internal init(_ errorCode: CoreStoreErrorCode) { + internal init(_ error: ErrorType) { - self.init(errorCode, userInfo: nil) - } - - internal init(_ errorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) { - - self.init(NSError(coreStoreErrorCode: errorCode, userInfo: userInfo)) + self = .Failure(CoreStoreError(error)) } } diff --git a/Sources/Saving and Processing/SaveResult.swift b/Sources/Saving and Processing/SaveResult.swift index 5bc6615..90d34ba 100644 --- a/Sources/Saving and Processing/SaveResult.swift +++ b/Sources/Saving and Processing/SaveResult.swift @@ -52,7 +52,7 @@ import Foundation case .Success(let hasChanges): // hasChanges indicates if there were changes or not case .Failure(let error): - // error is the NSError instance for the failure + // error is a CoreStoreError enum value } } ``` @@ -65,9 +65,9 @@ public enum SaveResult { case Success(hasChanges: Bool) /** - `SaveResult.Failure` indicates that the `commit()` for the transaction failed. The associated object for this value is the related `NSError` instance. + `SaveResult.Failure` indicates that the `commit()` for the transaction failed. The associated object for this value is a `CoreStoreError` enum value. */ - case Failure(NSError) + case Failure(CoreStoreError) // MARK: Internal @@ -77,20 +77,10 @@ public enum SaveResult { self = .Success(hasChanges: hasChanges) } - internal init(_ error: NSError) { + internal init(_ error: CoreStoreError) { self = .Failure(error) } - - internal init(_ errorCode: CoreStoreErrorCode) { - - self.init(errorCode, userInfo: nil) - } - - internal init(_ errorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) { - - self.init(NSError(coreStoreErrorCode: errorCode, userInfo: userInfo)) - } } diff --git a/Sources/Setting Up/CoreStore+Setup.swift b/Sources/Setting Up/CoreStore+Setup.swift index a017424..8f9b9a4 100644 --- a/Sources/Setting Up/CoreStore+Setup.swift +++ b/Sources/Setting Up/CoreStore+Setup.swift @@ -132,6 +132,9 @@ public extension CoreStore { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `InMemoryStore` instance. + ``` + try CoreStore.addStorage(InMemoryStore(configuration: configuration)) + ``` */ @available(*, deprecated=2.0.0, obsoleted=2.0.0, message="Use addStorageAndWait(_:) by passing an InMemoryStore instance.") public static func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore { @@ -141,6 +144,15 @@ public extension CoreStore { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance. + ``` + try CoreStore.addStorage( + LegacySQLiteStore( + fileName: fileName, + configuration: configuration, + localStorageOptions: .RecreateStoreOnModelMismatch + ) + ) + ``` - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`. */ @available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.") @@ -155,6 +167,15 @@ public extension CoreStore { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance. + ``` + try CoreStore.addStorage( + LegacySQLiteStore( + fileURL: fileURL, + configuration: configuration, + localStorageOptions: .RecreateStoreOnModelMismatch + ) + ) + ``` - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`. */ @available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.") diff --git a/Sources/Setting Up/DataStack.swift b/Sources/Setting Up/DataStack.swift index 92fbf05..22bad37 100644 --- a/Sources/Setting Up/DataStack.swift +++ b/Sources/Setting Up/DataStack.swift @@ -168,11 +168,12 @@ public final class DataStack { } catch { - CoreStore.handleError( - error as NSError, + let storeError = CoreStoreError(error) + CoreStore.log( + storeError, "Failed to add \(typeName(storage)) to the stack." ) - throw error + throw storeError } } @@ -222,8 +223,8 @@ public final class DataStack { return existingStorage } - let error = NSError(coreStoreErrorCode: .DifferentPersistentStoreExistsAtURL) - CoreStore.handleError( + let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: fileURL) + CoreStore.log( error, "Failed to add \(typeName(storage)) at \"\(fileURL)\" because a different \(typeName(NSPersistentStore)) at that URL already exists." ) @@ -271,11 +272,12 @@ public final class DataStack { } catch { - CoreStore.handleError( - error as NSError, + let storeError = CoreStoreError(error) + CoreStore.log( + storeError, "Failed to add \(typeName(storage)) to the stack." ) - throw error + throw storeError } } } @@ -410,6 +412,9 @@ public final class DataStack { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `InMemoryStore` instance. + ``` + try dataStack.addStorage(InMemoryStore(configuration: configuration)) + ``` */ @available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing an InMemoryStore instance.") public func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore { @@ -420,7 +425,15 @@ public final class DataStack { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance. - + ``` + try dataStack.addStorage( + LegacySQLiteStore( + fileName: fileName, + configuration: configuration, + localStorageOptions: .RecreateStoreOnModelMismatch + ) + ) + ``` - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`. */ @available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.") @@ -438,7 +451,15 @@ public final class DataStack { /** Deprecated. Use `addStorageAndWait(_:)` by passing a `LegacySQLiteStore` instance. - + ``` + try dataStack.addStorage( + LegacySQLiteStore( + fileURL: fileURL, + configuration: configuration, + localStorageOptions: .RecreateStoreOnModelMismatch + ) + ) + ``` - Warning: The default SQLite file location for the `LegacySQLiteStore` and `SQLiteStore` are different. If the app was using this method prior to 2.0.0, make sure to use `LegacySQLiteStore`. */ @available(*, deprecated=2.0.0, message="Use addStorageAndWait(_:) by passing a LegacySQLiteStore instance. Warning: The default SQLite file location for the LegacySQLiteStore and SQLiteStore are different. If the app was using this method prior to 2.0.0, make sure to use LegacySQLiteStore.") diff --git a/Sources/Setting Up/SetupResult.swift b/Sources/Setting Up/SetupResult.swift index babdef2..112d3c7 100644 --- a/Sources/Setting Up/SetupResult.swift +++ b/Sources/Setting Up/SetupResult.swift @@ -1,5 +1,5 @@ // -// PersistentStoreResult.swift +// SetupResult.swift // CoreStore // // Copyright © 2014 John Rommel Estropia @@ -54,7 +54,7 @@ import CoreData case .Success(let storage): // storage is the related StorageInterface instance case .Failure(let error): - // error is the NSError instance for the failure + // error is the CoreStoreError enum value for the failure } } ) @@ -68,9 +68,9 @@ public enum SetupResult: BooleanType { case Success(T) /** - `SetupResult.Failure` indicates that the storage setup failed. The associated object for this value is the related `NSError` instance. + `SetupResult.Failure` indicates that the storage setup failed. The associated object for this value is the related `CoreStoreError` enum value. */ - case Failure(NSError) + case Failure(CoreStoreError) // MARK: BooleanType @@ -92,19 +92,14 @@ public enum SetupResult: BooleanType { self = .Success(storage) } - internal init(_ error: NSError) { + internal init(_ error: CoreStoreError) { self = .Failure(error) } - internal init(_ errorCode: CoreStoreErrorCode) { + internal init(_ error: ErrorType) { - self.init(errorCode, userInfo: nil) - } - - internal init(_ errorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) { - - self.init(NSError(coreStoreErrorCode: errorCode, userInfo: userInfo)) + self = .Failure(CoreStoreError(error)) } } @@ -152,14 +147,4 @@ public enum PersistentStoreResult: BooleanType { self = .Failure(error) } - - internal init(_ errorCode: CoreStoreErrorCode) { - - self.init(errorCode, userInfo: nil) - } - - internal init(_ errorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) { - - self.init(NSError(coreStoreErrorCode: errorCode, userInfo: userInfo)) - } }