Merge branch 'develop' of github.com:JohnEstropia/CoreStore into develop

This commit is contained in:
John Rommel Estropia
2015-12-05 18:19:33 +09:00
26 changed files with 328 additions and 56 deletions

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "1.3.3"
s.version = "1.3.4"
s.license = "MIT"
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
s.homepage = "https://github.com/JohnEstropia/CoreStore"
@@ -12,8 +12,10 @@ Pod::Spec.new do |s|
s.watchos.deployment_target = "2.0"
s.source_files = "CoreStore", "CoreStore/**/*.{swift}"
s.osx.exclude_files = "CoreStore/Observing/*.{swift}", "CoreStore/Internal/FetchedResultsControllerDelegate.swift"
s.osx.exclude_files = "CoreStore/Observing/*.{swift}", "CoreStore/Internal/FetchedResultsControllerDelegate.swift", "CoreStore/Internal/NSFetchedResultsController+Convenience.swift"
s.frameworks = "Foundation", "CoreData"
s.requires_arc = true
s.dependency "GCDKit", "1.1.3"
s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS' => '-D USE_FRAMEWORKS' }
s.dependency "GCDKit", "1.1.4"
end

View File

@@ -13,6 +13,8 @@
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F291E2619C6D3CF007AF63F /* CoreStore.swift */; };
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */; };
B51BE06A1B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
B52DD17E1BE1F8CD00949AFE /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B52DD1741BE1F8CC00949AFE /* CoreStore.framework */; };
B52DD1901BE1F8E600949AFE /* GCDKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5D808021A34715700A44484 /* GCDKit.framework */; };
B52DD1911BE1F8EB00949AFE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5548CD51BD65AE00077652A /* Foundation.framework */; };
@@ -274,6 +276,7 @@
2F291E2619C6D3CF007AF63F /* CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CoreStore.swift; sourceTree = "<group>"; };
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Setup.swift"; sourceTree = "<group>"; };
B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectModel+Setup.swift"; sourceTree = "<group>"; };
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
B52DD1741BE1F8CC00949AFE /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchedResultsControllerDelegate.swift; sourceTree = "<group>"; };
@@ -295,7 +298,7 @@
B5D39A0119FD00C9000E91BB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = "<group>"; };
B5D806C51A34715700A44484 /* GCDKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = GCDKit.xcodeproj; sourceTree = "<group>"; };
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; };
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; };
B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaseDataTransaction+Importing.swift"; sourceTree = "<group>"; };
B5E834BA1B7691F3001D3D50 /* Functions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = "<group>"; };
B5E84ED81AFF82360064E85B /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
@@ -617,6 +620,7 @@
children = (
B5E84F271AFF84920064E85B /* NSManagedObject+Convenience.swift */,
B5FAD6A81B50A4B300714891 /* NSProgress+Convenience.swift */,
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */,
);
path = "Convenience Helpers";
sourceTree = "<group>";
@@ -918,6 +922,7 @@
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B5E84EE11AFF84500064E85B /* PersistentStoreResult.swift in Sources */,
B5E84F251AFF84860064E85B /* ObjectObserver.swift in Sources */,
B5E84F2F1AFF849C0064E85B /* NotificationObserver.swift in Sources */,
@@ -1056,6 +1061,7 @@
B56321811BD65216006C9394 /* DataStack.swift in Sources */,
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
B56321981BD65216006C9394 /* Where.swift in Sources */,
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B56321AF1BD6521C006C9394 /* NSFileManager+Setup.swift in Sources */,
B56321971BD65216006C9394 /* Select.swift in Sources */,
B56321AB1BD6521C006C9394 /* FetchedResultsControllerDelegate.swift in Sources */,
@@ -1169,6 +1175,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-D USE_FRAMEWORKS -D DEBUG";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1208,6 +1215,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.1;
MTL_ENABLE_DEBUG_INFO = NO;
OTHER_SWIFT_FLAGS = "-D USE_FRAMEWORKS";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1230,7 +1238,6 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_SWIFT_FLAGS = "-D DEBUG";
PRODUCT_BUNDLE_IDENTIFIER = "com.johnestropia.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = CoreStore;
SKIP_INSTALL = YES;

View File

@@ -0,0 +1,50 @@
//
// NSManagedObject+Convenience.swift
// CoreStore
//
// Copyright (c) 2015 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: - NSFetchedResultsController
public extension NSFetchedResultsController {
public convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
let context = dataStack.mainContext
from?.applyToFetchRequest(fetchRequest, context: context)
for clause in fetchClauses {
clause.applyToFetchRequest(fetchRequest)
}
self.init(
fetchRequest: fetchRequest,
managedObjectContext: context,
sectionNameKeyPath: sectionBy?.sectionKeyPath,
cacheName: nil
)
}
}

View File

@@ -24,7 +24,9 @@
//
import Foundation
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - NSProgress

View File

@@ -24,7 +24,9 @@
//
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - CoreStore

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - DataStack

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - NSManagedObjectContext

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - NSManagedObjectContext

View File

@@ -65,10 +65,13 @@ internal extension NSManagedObjectModel {
}
else if let resolvedVersion = modelVersions.first ?? modelVersionHints.first {
CoreStore.log(
.Warning,
message: "The MigrationChain leaf versions do not include any of the model file's embedded versions. Resolving to version \"\(resolvedVersion)\"."
)
if !modelVersionHints.isEmpty {
CoreStore.log(
.Warning,
message: "The MigrationChain leaf versions do not include any of the model file's embedded versions. Resolving to version \"\(resolvedVersion)\"."
)
}
currentModelVersion = resolvedVersion
}
else {

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - CoreStore

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - DataStack

View File

@@ -72,6 +72,30 @@ public extension CoreStore {
return self.defaultStack.monitorList(from, queryClauses)
}
/**
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public static func monitorList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
}
/**
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public static func monitorList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
}
/**
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
@@ -99,4 +123,30 @@ public extension CoreStore {
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
}
/**
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public static func monitorSectionedList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
}
/**
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public static func monitorSectionedList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
}
}

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - DataStack
@@ -95,6 +97,45 @@ public extension DataStack {
)
}
/**
Asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public func monitorList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
self.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
}
/**
Asynchronously creates a `ListMonitor` for a list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public func monitorList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
CoreStore.assert(
NSThread.isMainThread(),
"Attempted to observe objects from \(typeName(self)) outside the main thread."
)
CoreStore.assert(
fetchClauses.filter { $0 is OrderBy }.count > 0,
"A ListMonitor requires an OrderBy clause."
)
_ = ListMonitor(
dataStack: self,
from: from,
sectionBy: nil,
fetchClauses: fetchClauses,
createAsynchronously: createAsynchronously
)
}
/**
Creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
@@ -136,4 +177,45 @@ public extension DataStack {
fetchClauses: fetchClauses
)
}
/**
Asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public func monitorSectionedList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
self.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
}
/**
Asynchronously creates a `ListMonitor` for a sectioned list of `NSManagedObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
- parameter from: a `From` clause indicating the entity type
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
*/
public func monitorSectionedList<T: NSManagedObject>(createAsynchronously createAsynchronously: (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
CoreStore.assert(
NSThread.isMainThread(),
"Attempted to observe objects from \(typeName(self)) outside the main thread."
)
CoreStore.assert(
fetchClauses.filter { $0 is OrderBy }.count > 0,
"A ListMonitor requires an OrderBy clause."
)
_ = ListMonitor(
dataStack: self,
from: from,
sectionBy: sectionBy,
fetchClauses: fetchClauses,
createAsynchronously: createAsynchronously
)
}
}

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - ListMonitor
@@ -883,29 +885,53 @@ public final class ListMonitor<T: NSManagedObject> {
// MARK: Internal
internal init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause]) {
internal convenience init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause]) {
self.init(
dataStack: dataStack,
from: from,
sectionBy: sectionBy,
fetchClauses: fetchClauses,
prepareFetch: { _, performFetch in performFetch() }
)
}
internal convenience init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], createAsynchronously: (ListMonitor<T>) -> Void) {
let context = dataStack.mainContext
self.init(
dataStack: dataStack,
from: from,
sectionBy: sectionBy,
fetchClauses: fetchClauses,
prepareFetch: { listMonitor, performFetch in
dataStack.childTransactionQueue.async {
performFetch()
GCDQueue.Main.async {
createAsynchronously(listMonitor)
}
}
}
)
}
private init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], prepareFetch: (ListMonitor<T>, () -> Void) -> Void) {
let fetchRequest = NSFetchRequest()
from.applyToFetchRequest(fetchRequest, context: context)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .ManagedObjectResultType
fetchRequest.fetchBatchSize = 20
fetchRequest.includesPendingChanges = false
fetchRequest.shouldRefreshRefetchedObjects = true
for clause in fetchClauses {
clause.applyToFetchRequest(fetchRequest)
}
let fetchedResultsController = NSFetchedResultsController(
dataStack: dataStack,
fetchRequest: fetchRequest,
managedObjectContext: context,
sectionNameKeyPath: sectionBy?.sectionKeyPath,
cacheName: nil
from: from,
sectionBy: sectionBy,
fetchClauses: fetchClauses
)
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate()
@@ -925,7 +951,8 @@ public final class ListMonitor<T: NSManagedObject> {
fetchedResultsControllerDelegate.handler = self
fetchedResultsControllerDelegate.fetchedResultsController = fetchedResultsController
try! fetchedResultsController.performFetch()
prepareFetch(self, { try! fetchedResultsController.performFetch() })
}
deinit {

View File

@@ -205,7 +205,6 @@ public protocol ListSectionObserver: ListObjectObserver {
- parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the inserted section
- parameter sectionIndex: the new section index for the new section
*/
@available(iOS 8.0, *)
func listMonitor(monitor: ListMonitor<ListEntityType>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int)
/**
@@ -215,7 +214,6 @@ public protocol ListSectionObserver: ListObjectObserver {
- parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the deleted section
- parameter sectionIndex: the previous section index for the deleted section
*/
@available(iOS 8.0, *)
func listMonitor(monitor: ListMonitor<ListEntityType>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int)
}

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - ObjectMonitor
@@ -165,25 +167,18 @@ public final class ObjectMonitor<T: NSManagedObject> {
internal init(dataStack: DataStack, object: T) {
let context = dataStack.mainContext
let fetchRequest = NSFetchRequest()
fetchRequest.entity = object.entity
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .ManagedObjectResultType
fetchRequest.sortDescriptors = []
fetchRequest.includesPendingChanges = false
fetchRequest.shouldRefreshRefetchedObjects = true
let originalObjectID = object.objectID
Where("SELF", isEqualTo: originalObjectID).applyToFetchRequest(fetchRequest)
let fetchedResultsController = NSFetchedResultsController(
dataStack: dataStack,
fetchRequest: fetchRequest,
managedObjectContext: context,
sectionNameKeyPath: nil,
cacheName: nil
fetchClauses: [Where("SELF", isEqualTo: object.objectID)]
)
let fetchedResultsControllerDelegate = FetchedResultsControllerDelegate()

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - AsynchronousDataTransaction

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - BaseDataTransaction

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - DataStack

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - SynchronousDataTransaction

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
@available(*, deprecated=1.3.1, renamed="UnsafeDataTransaction")

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
// MARK: - CoreStore

View File

@@ -25,7 +25,9 @@
import Foundation
import CoreData
import GCDKit
#if USE_FRAMEWORKS
import GCDKit
#endif
internal let applicationSupportDirectory = NSFileManager.defaultManager().URLsForDirectory(.ApplicationSupportDirectory, inDomains: .UserDomainMask).first!

View File

@@ -48,6 +48,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
B5202CF11C044CC800DED140 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B583A9141AF5F4F3001F76AF /* CoreStore.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = B52DD1741BE1F8CC00949AFE;
remoteInfo = "CoreStore OSX";
};
B5202CF31C044CC800DED140 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B583A9141AF5F4F3001F76AF /* CoreStore.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = B52DD17D1BE1F8CC00949AFE;
remoteInfo = "CoreStoreTests OSX";
};
B56321C51BD65965006C9394 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B583A9141AF5F4F3001F76AF /* CoreStore.xcodeproj */;
@@ -286,8 +300,10 @@
isa = PBXGroup;
children = (
B583A91B1AF5F4F4001F76AF /* CoreStore.framework */,
B583A91D1AF5F4F4001F76AF /* CoreStoreTests iOS.xctest */,
B583A91D1AF5F4F4001F76AF /* CoreStoreTests.xctest */,
B56321C61BD65965006C9394 /* CoreStore.framework */,
B5202CF21C044CC800DED140 /* CoreStore.framework */,
B5202CF41C044CC800DED140 /* CoreStoreTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -355,6 +371,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
B5202CF21C044CC800DED140 /* CoreStore.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = CoreStore.framework;
remoteRef = B5202CF11C044CC800DED140 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B5202CF41C044CC800DED140 /* CoreStoreTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = CoreStoreTests.xctest;
remoteRef = B5202CF31C044CC800DED140 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B56321C61BD65965006C9394 /* CoreStore.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@@ -369,10 +399,10 @@
remoteRef = B583A91A1AF5F4F4001F76AF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
B583A91D1AF5F4F4001F76AF /* CoreStoreTests iOS.xctest */ = {
B583A91D1AF5F4F4001F76AF /* CoreStoreTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "CoreStoreTests iOS.xctest";
path = CoreStoreTests.xctest;
remoteRef = B583A91C1AF5F4F4001F76AF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};

View File

@@ -24,7 +24,7 @@ Unleashing the real power of Core Data with the elegance and safety of Swift
- 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!
**CoreStore's goal is not to expose shorter, magical syntax, but to provide an API that focuses on readability, consistency, and safety.**
**[Or vote for the next feature!](http://goo.gl/RIiHMP)**
@@ -255,7 +255,7 @@ class MyViewController: UIViewController {
## Migrations
So far we have only seen `addSQLiteStoreAndWait(...)` used to initialize our persistent store. As the method name's "AndWait" suffix suggests, this method will block, even if a migration occurs. If migrations are expected, the asynchronous variant `addSQLiteStore(... completion:)` method is recommended:
So far we have only seen `addSQLiteStoreAndWait(...)` used to initialize our persistent store. As the method name's "AndWait" suffix suggests, this method blocks so it should not do long tasks such as store migrations (in fact CoreStore won't even attempt to, and any model mismatch will be reported as an error). If migrations are expected, the asynchronous variant `addSQLiteStore(... completion:)` method should be used instead:
```swift
do {
let progress: NSProgress = try dataStack.addSQLiteStore(