diff --git a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift index d9960cd..dea33d8 100644 --- a/CoreStore/Internal/NSManagedObjectContext+Transaction.swift +++ b/CoreStore/Internal/NSManagedObjectContext+Transaction.swift @@ -167,6 +167,18 @@ internal extension NSManagedObjectContext { } } + internal func refreshAllObjectsAsFaults() { + + if #available(iOS 8.3, *) { + + self.refreshAllObjects() + } + else { + + self.registeredObjects.forEach { self.refreshObject($0, mergeChanges: false) } + } + } + // MARK: Private diff --git a/CoreStore/Saving and Processing/BaseDataTransaction.swift b/CoreStore/Saving and Processing/BaseDataTransaction.swift index e43c09c..e8e59dd 100644 --- a/CoreStore/Saving and Processing/BaseDataTransaction.swift +++ b/CoreStore/Saving and Processing/BaseDataTransaction.swift @@ -188,6 +188,19 @@ public /*abstract*/ class BaseDataTransaction { objects.forEach { context.fetchExisting($0)?.deleteFromContext() } } + /** + Refreshes all registered objects `NSManagedObject`s in the transaction. + */ + public func refreshAllObjectsAsFaults() { + + CoreStore.assert( + self.isRunningInAllowedQueue(), + "Attempted to refresh entities outside their designated queue." + ) + + self.context.refreshAllObjectsAsFaults() + } + // MARK: Internal diff --git a/CoreStore/Saving and Processing/CoreStore+Transaction.swift b/CoreStore/Saving and Processing/CoreStore+Transaction.swift index fb1941f..f6e6209 100644 --- a/CoreStore/Saving and Processing/CoreStore+Transaction.swift +++ b/CoreStore/Saving and Processing/CoreStore+Transaction.swift @@ -65,6 +65,14 @@ public extension CoreStore { return self.defaultStack.beginUnsafe(supportsUndo: supportsUndo) } + /** + Refreshes all registered objects `NSManagedObject`s in the `DataStack`. + */ + public static func refreshAllObjectsAsFaults() { + + self.defaultStack.refreshAllObjectsAsFaults() + } + @available(*, deprecated=1.3.1, renamed="beginUnsafe") @warn_unused_result public static func beginDetached() -> UnsafeDataTransaction { diff --git a/CoreStore/Saving and Processing/DataStack+Transaction.swift b/CoreStore/Saving and Processing/DataStack+Transaction.swift index 53a345f..28abca4 100644 --- a/CoreStore/Saving and Processing/DataStack+Transaction.swift +++ b/CoreStore/Saving and Processing/DataStack+Transaction.swift @@ -82,6 +82,19 @@ public extension DataStack { ) } + /** + Refreshes all registered objects `NSManagedObject`s in the `DataStack`. + */ + public func refreshAllObjectsAsFaults() { + + CoreStore.assert( + NSThread.isMainThread(), + "Attempted to refresh entities outside their designated queue." + ) + + self.mainContext.refreshAllObjectsAsFaults() + } + @available(*, deprecated=1.3.1, renamed="beginUnsafe") @warn_unused_result public func beginDetached() -> UnsafeDataTransaction { diff --git a/CoreStoreDemo/CoreStoreDemo.xcodeproj/project.pbxproj b/CoreStoreDemo/CoreStoreDemo.xcodeproj/project.pbxproj index 264fbf2..34d67aa 100644 --- a/CoreStoreDemo/CoreStoreDemo.xcodeproj/project.pbxproj +++ b/CoreStoreDemo/CoreStoreDemo.xcodeproj/project.pbxproj @@ -36,13 +36,13 @@ B569651C1B30889A0075EE4A /* QueryingResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */; }; B56965291B3582D30075EE4A /* MigrationDemo.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B56965271B3582D30075EE4A /* MigrationDemo.xcdatamodeld */; }; B5A93A141C214E5900E47273 /* SpotlightDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A93A131C214E5900E47273 /* SpotlightDemoViewController.swift */; }; - B5BDC9221C202429008147CD /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; }; - B5BDC9231C202429008147CD /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - B5BDC9251C202429008147CD /* GCDKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9241C202429008147CD /* GCDKit.framework */; }; - B5BDC9261C202429008147CD /* GCDKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9241C202429008147CD /* GCDKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; B5C12CE71C21B2F70098E05F /* CoreSpotlight.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5C12CE61C21B2F70098E05F /* CoreSpotlight.framework */; }; B5C12CE91C21B2FD0098E05F /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5C12CE81C21B2FD0098E05F /* MobileCoreServices.framework */; }; B5E599321B5240F50084BD5F /* OrganismTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */; }; + B5E89ACD1C52929C003B04A9 /* GCDKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9241C202429008147CD /* GCDKit.framework */; }; + B5E89ACE1C52929C003B04A9 /* GCDKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9241C202429008147CD /* GCDKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; }; + B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B5BDC9211C202429008147CD /* CoreStore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; B5EE25851B36E23C0000406B /* OrganismV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25841B36E23C0000406B /* OrganismV1.swift */; }; B5EE25871B36E2520000406B /* OrganismV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE25861B36E2520000406B /* OrganismV2.swift */; }; B5EE258C1B36E40D0000406B /* MigrationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5EE258B1B36E40D0000406B /* MigrationsDemoViewController.swift */; }; @@ -51,14 +51,14 @@ /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - B583A9241AF5F542001F76AF /* Embed Frameworks */ = { + B5E89ACF1C52929C003B04A9 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - B5BDC9261C202429008147CD /* GCDKit.framework in Embed Frameworks */, - B5BDC9231C202429008147CD /* CoreStore.framework in Embed Frameworks */, + B5E89ACE1C52929C003B04A9 /* GCDKit.framework in Embed Frameworks */, + B5E89AD11C5292A2003B04A9 /* CoreStore.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -96,9 +96,9 @@ B56965191B30888A0075EE4A /* FetchingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchingResultsViewController.swift; sourceTree = ""; }; B569651B1B30889A0075EE4A /* QueryingResultsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryingResultsViewController.swift; sourceTree = ""; }; B56965281B3582D30075EE4A /* MigrationDemo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MigrationDemo.xcdatamodel; sourceTree = ""; }; + B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B5BDC9241C202429008147CD /* GCDKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = GCDKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B5A93A131C214E5900E47273 /* SpotlightDemoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpotlightDemoViewController.swift; sourceTree = ""; }; - B5BDC9211C202429008147CD /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = CoreStore.framework; path = "/Users/JohnEstropia/Library/Developer/Xcode/DerivedData/Build/Products/Debug-iphoneos/CoreStore.framework"; sourceTree = ""; }; - B5BDC9241C202429008147CD /* GCDKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; name = GCDKit.framework; path = "/Users/JohnEstropia/Library/Developer/Xcode/DerivedData/Build/Products/Debug-iphoneos/GCDKit.framework"; sourceTree = ""; }; B5C12CE61C21B2F70098E05F /* CoreSpotlight.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSpotlight.framework; path = System/Library/Frameworks/CoreSpotlight.framework; sourceTree = SDKROOT; }; B5C12CE81C21B2FD0098E05F /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; B5E599311B5240F50084BD5F /* OrganismTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = OrganismTableViewCell.swift; path = "CoreStoreDemo/MIgrations Demo/OrganismTableViewCell.swift"; sourceTree = SOURCE_ROOT; }; @@ -116,11 +116,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + B5E89ACD1C52929C003B04A9 /* GCDKit.framework in Frameworks */, + B5E89AD01C5292A2003B04A9 /* CoreStore.framework in Frameworks */, B5C12CE91C21B2FD0098E05F /* MobileCoreServices.framework in Frameworks */, B5C12CE71C21B2F70098E05F /* CoreSpotlight.framework in Frameworks */, B52977E11B120F8A003D50A5 /* CoreLocation.framework in Frameworks */, - B5BDC9221C202429008147CD /* CoreStore.framework in Frameworks */, - B5BDC9251C202429008147CD /* GCDKit.framework in Frameworks */, B52977DF1B120F83003D50A5 /* MapKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -273,7 +273,7 @@ B54AAD451AF4D26E00848AE0 /* Sources */, B54AAD461AF4D26E00848AE0 /* Frameworks */, B54AAD471AF4D26E00848AE0 /* Resources */, - B583A9241AF5F542001F76AF /* Embed Frameworks */, + B5E89ACF1C52929C003B04A9 /* Embed Frameworks */, ); buildRules = ( ); diff --git a/README.md b/README.md index 29a0581..593270a 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,18 @@ Unleashing the real power of Core Data with the elegance and safety of Swift ## What CoreStore does better: -- Heavily supports multiple persistent stores per data stack, just the way *.xcdatamodeld* files are designed to. CoreStore will also manage one data stack by default, but you can create and manage as many as you need. -- Incremental Migrations! Just tell the data stack the sequence of model versions and CoreStore will automatically use incremental migrations if needed on stores added to that stack. -- Ability to plug-in your own logging framework -- Gets around a limitation with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the managed object model file, so you are free to name them independently. -- Provides type-safe, easy to configure observers to replace `NSFetchedResultsController` and KVO -- Exposes API not just for fetching, but also for querying aggregates and property values -- Makes it hard to fall into common concurrency mistakes. All `NSManagedObjectContext` tasks are encapsulated into safer, higher-level abstractions without sacrificing flexibility and customizability. -- Exposes clean and convenient API designed around Swift’s code elegance and type safety. -- Documentation! No magic here; all public classes, functions, properties, etc. have detailed Apple Docs. This README also introduces a lot of concepts and explains a lot of CoreStore's behavior. -- **New in 1.3.0:** Efficient importing utilities! +- **Heavily supports multiple persistent stores per data stack**, just the way *.xcdatamodeld* files are designed to. CoreStore will also manage one data stack by default, but you can create and manage as many as you need. +- **Incremental Migrations!** Just tell the data stack the sequence of model versions and CoreStore will automatically use incremental migrations if needed on stores added to that stack. +- Ability to **plug-in your own logging framework** +- Gets around a limitation with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the managed object model file, so you are **free to name entities and their class names independently**. +- Provides type-safe, easy to configure **observers to replace `NSFetchedResultsController` and KVO** +- Exposes **API not just for fetching, but also for querying aggregates and property values** +- Makes it hard to fall into common concurrency mistakes. All `NSManagedObjectContext` tasks are encapsulated into **safer, higher-level abstractions** without sacrificing flexibility and customizability. +- Exposes clean and convenient API designed around **Swift’s code elegance and type safety**. +- **Documentation!** No magic here; all public classes, functions, properties, etc. have detailed Apple Docs. This README also introduces a lot of concepts and explains a lot of CoreStore's behavior. +- **Efficient importing utilities!** -**[Or vote for the next feature!](http://goo.gl/RIiHMP)** +**[Vote for the next feature!](http://goo.gl/RIiHMP)** @@ -1162,8 +1162,8 @@ let person2 = self.monitor[1, 2] # Roadmap -- Data importing utilities for transactions - Support iCloud stores +- CoreSpotlight auto-indexing (experimental) # Installation @@ -1180,9 +1180,14 @@ pod 'CoreStore' This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library. ### Install with Carthage +In your `Cartfile`, add ``` -github "JohnEstropia/CoreStore" >= 1.3.0 -github "JohnEstropia/GCDKit" >= 1.1.5 +github "JohnEstropia/CoreStore" >= 1.4.4 +github "JohnEstropia/GCDKit" >= 1.1.7 +``` +and run +``` +carthage update ``` ### Install as Git Submodule