mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-05-28 10:29:31 +02:00
Merge branch 'develop'
This commit is contained in:
+3
-2
@@ -22,8 +22,9 @@ env:
|
||||
before_install:
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- brew update
|
||||
- brew install carthage
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.11/Carthage.pkg"
|
||||
- sudo installer -pkg "Carthage.pkg" -target /
|
||||
- rm "Carthage.pkg"
|
||||
before_script:
|
||||
- carthage update --use-submodules
|
||||
script:
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "1.4.4"
|
||||
s.version = "1.5.0"
|
||||
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"
|
||||
|
||||
@@ -208,6 +208,12 @@
|
||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; };
|
||||
B59D5C221B5BA34B00453479 /* NSFileManager+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59D5C211B5BA34B00453479 /* NSFileManager+Setup.swift */; };
|
||||
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A261201B64BFDB006EB6D3 /* MigrationType.swift */; };
|
||||
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; };
|
||||
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; };
|
||||
B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */; };
|
||||
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 */; };
|
||||
B5D372841A39CD6900F583D9 /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
||||
B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D372851A39CDDB00F583D9 /* TestEntity1.swift */; };
|
||||
@@ -317,6 +323,8 @@
|
||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
|
||||
B5BDC91A1C202269008147CD /* CartFile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CartFile; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
|
||||
B5D1E22B19FA9FBC003B2874 /* NSError+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSError+CoreStore.swift"; sourceTree = "<group>"; };
|
||||
B5D372831A39CD6900F583D9 /* Model.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Model.xcdatamodel; sourceTree = "<group>"; };
|
||||
B5D372851A39CDDB00F583D9 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = "<group>"; };
|
||||
@@ -627,6 +635,7 @@
|
||||
B56007131B3F6C2800A9A8F9 /* SectionBy.swift */,
|
||||
B5E84F1A1AFF84860064E85B /* DataStack+Observing.swift */,
|
||||
B5E84F1B1AFF84860064E85B /* CoreStore+Observing.swift */,
|
||||
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */,
|
||||
B5E84F1C1AFF84860064E85B /* ObjectMonitor.swift */,
|
||||
B5E84F1F1AFF84860064E85B /* ObjectObserver.swift */,
|
||||
B5E84F1D1AFF84860064E85B /* ListMonitor.swift */,
|
||||
@@ -654,6 +663,7 @@
|
||||
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
|
||||
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
|
||||
B59D5C211B5BA34B00453479 /* NSFileManager+Setup.swift */,
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
|
||||
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
|
||||
@@ -943,6 +953,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */,
|
||||
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
|
||||
B504D0D61B02362500B2BBB1 /* CoreStore+Setup.swift in Sources */,
|
||||
B5D1E22C19FA9FBC003B2874 /* NSError+CoreStore.swift in Sources */,
|
||||
@@ -952,6 +963,7 @@
|
||||
B5E84F141AFF847B0064E85B /* DataStack+Querying.swift in Sources */,
|
||||
B56007141B3F6C2800A9A8F9 /* SectionBy.swift in Sources */,
|
||||
B5E84F371AFF85470064E85B /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
|
||||
B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */,
|
||||
B5E84F121AFF847B0064E85B /* OrderBy.swift in Sources */,
|
||||
@@ -1018,6 +1030,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */,
|
||||
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
82BA18A21C4BBD1D00A0916E /* NSError+CoreStore.swift in Sources */,
|
||||
82BA18B21C4BBD3900A0916E /* ImportableObject.swift in Sources */,
|
||||
82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */,
|
||||
@@ -1027,6 +1040,7 @@
|
||||
82BA18C21C4BBD5300A0916E /* ObjectMonitor.swift in Sources */,
|
||||
82BA18A51C4BBD2200A0916E /* CoreStore+Setup.swift in Sources */,
|
||||
82BA18BD1C4BBD4A00A0916E /* GroupBy.swift in Sources */,
|
||||
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */,
|
||||
82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */,
|
||||
82BA18CF1C4BBD7100A0916E /* Functions.swift in Sources */,
|
||||
@@ -1159,6 +1173,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B56321A91BD65219006C9394 /* NSProgress+Convenience.swift in Sources */,
|
||||
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B56321801BD65216006C9394 /* NSError+CoreStore.swift in Sources */,
|
||||
B56321AD1BD6521C006C9394 /* MigrationManager.swift in Sources */,
|
||||
B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */,
|
||||
@@ -1168,6 +1183,7 @@
|
||||
B563219E1BD65216006C9394 /* CoreStore+Observing.swift in Sources */,
|
||||
B56321891BD65216006C9394 /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B56321831BD65216006C9394 /* CoreStore+Setup.swift in Sources */,
|
||||
B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B563217F1BD65216006C9394 /* CoreStore.swift in Sources */,
|
||||
B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObject+Convenience.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,20 +31,31 @@ import CoreData
|
||||
|
||||
public extension NSFetchedResultsController {
|
||||
|
||||
public convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
/**
|
||||
Utility for creating an `NSFetchedResultsController` from a `DataStack`. This is useful to partially support Objective-C classes by passing an `NSFetchedResultsController` instance instead of a `ListMonitor`.
|
||||
*/
|
||||
public func createForStack<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController {
|
||||
|
||||
let context = dataStack.mainContext
|
||||
from?.applyToFetchRequest(fetchRequest, context: context)
|
||||
for clause in fetchClauses {
|
||||
|
||||
clause.applyToFetchRequest(fetchRequest)
|
||||
return CoreStoreFetchedResultsController<T>(
|
||||
context: dataStack.mainContext,
|
||||
fetchRequest: fetchRequest,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
self.init(
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal func createFromContext<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController {
|
||||
|
||||
return CoreStoreFetchedResultsController<T>(
|
||||
context: context,
|
||||
fetchRequest: fetchRequest,
|
||||
managedObjectContext: context,
|
||||
sectionNameKeyPath: sectionBy?.sectionKeyPath,
|
||||
cacheName: nil
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObject+Convenience.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSProgress+Convenience.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -33,8 +33,6 @@ import Foundation
|
||||
|
||||
public extension NSProgress {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Sets a closure that the `NSProgress` calls whenever its `fractionCompleted` changes. You can use this instead of setting up KVO.
|
||||
- parameter closure: the closure to execute on progress change
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore.h
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -28,4 +28,3 @@
|
||||
|
||||
FOUNDATION_EXPORT double CoreStoreVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char CoreStoreVersionString[];
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -36,8 +36,6 @@ import CoreData
|
||||
*/
|
||||
public enum CoreStore {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
The default `DataStack` instance to be used. If `defaultStack` is not set before the first time accessed, a default-configured `DataStack` will be created.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// BaseDataTransaction+Querying.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,8 +31,6 @@ import CoreData
|
||||
|
||||
public extension BaseDataTransaction {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// From.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -30,43 +30,85 @@ import CoreData
|
||||
// MARK: - From
|
||||
|
||||
/**
|
||||
A `Form` clause binds the `NSManagedObject` entity type to the generics type system.
|
||||
A `From` clause specifies the source entity and source persistent store for fetch and query methods. A common usage is to just indicate the entity:
|
||||
```
|
||||
let person = transaction.fetchOne(From(MyPersonEntity))
|
||||
```
|
||||
For cases where multiple `NSPersistentStore`s contain the same entity, the source configuration's name needs to be specified as well:
|
||||
```
|
||||
let person = transaction.fetchOne(From<MyPersonEntity>("Configuration1"))
|
||||
```
|
||||
*/
|
||||
public struct From<T: NSManagedObject> {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `From` clause.
|
||||
Sample Usage:
|
||||
```
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
*/
|
||||
public init(){
|
||||
|
||||
self.entityClass = T.self
|
||||
self.findPersistentStores = { _ in nil }
|
||||
self.init(entityClass: T.self)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `From` clause with the specified entity type.
|
||||
Sample Usage:
|
||||
```
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
- parameter entity: the `NSManagedObject` type to be created
|
||||
*/
|
||||
public init(_ entity: T.Type) {
|
||||
|
||||
self.entityClass = entity
|
||||
self.findPersistentStores = { _ in nil }
|
||||
self.init(entityClass: entity)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `From` clause with the specified entity class.
|
||||
Sample Usage:
|
||||
```
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||
*/
|
||||
public init(_ entityClass: AnyClass) {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.findPersistentStores = { _ in nil }
|
||||
self.init(entityClass: entityClass)
|
||||
}
|
||||
|
||||
public init(_ configurations: String?...) {
|
||||
/**
|
||||
Initializes a `From` clause with the specified configurations.
|
||||
Sample Usage:
|
||||
```
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>(nil, "Configuration1"))
|
||||
```
|
||||
- parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||
- parameter otherConfigurations: an optional list of other configuration names to associate objects from (see `configuration` parameter)
|
||||
*/
|
||||
public init(_ configuration: String?, otherConfigurations: String?...) {
|
||||
|
||||
self.init(entityClass: T.self, configurations: configurations)
|
||||
self.init(entityClass: T.self, configurations: [configuration] + otherConfigurations)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `From` clause with the specified configurations.
|
||||
Sample Usage:
|
||||
```
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>(["Configuration1", "Configuration2"]))
|
||||
```
|
||||
- parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||
*/
|
||||
public init(_ configurations: [String?]) {
|
||||
|
||||
self.init(entityClass: T.self, configurations: configurations)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ configurations: String?...) {
|
||||
public init(_ entity: T.Type, _ configuration: String?, _ otherConfigurations: String?...) {
|
||||
|
||||
self.init(entityClass: entity, configurations: configurations)
|
||||
self.init(entityClass: entity, configurations: [configuration] + otherConfigurations)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ configurations: [String?]) {
|
||||
@@ -74,9 +116,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: entity, configurations: configurations)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ configurations: String?...) {
|
||||
public init(_ entityClass: AnyClass, _ configuration: String?, _ otherConfigurations: String?...) {
|
||||
|
||||
self.init(entityClass: entityClass, configurations: configurations)
|
||||
self.init(entityClass: entityClass, configurations: [configuration] + otherConfigurations)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ configurations: [String?]) {
|
||||
@@ -84,9 +126,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: entityClass, configurations: configurations)
|
||||
}
|
||||
|
||||
public init(_ storeURLs: NSURL...) {
|
||||
public init(_ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
self.init(entityClass: T.self, storeURLs: storeURLs)
|
||||
self.init(entityClass: T.self, storeURLs: [storeURL] + otherStoreURLs)
|
||||
}
|
||||
|
||||
public init(_ storeURLs: [NSURL]) {
|
||||
@@ -94,9 +136,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: T.self, storeURLs: storeURLs)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ storeURLs: NSURL...) {
|
||||
public init(_ entity: T.Type, _ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
self.init(entityClass: entity, storeURLs: storeURLs)
|
||||
self.init(entityClass: entity, storeURLs: [storeURL] + otherStoreURLs)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ storeURLs: [NSURL]) {
|
||||
@@ -104,9 +146,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: entity, storeURLs: storeURLs)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ storeURLs: NSURL...) {
|
||||
public init(_ entityClass: AnyClass, _ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
self.init(entityClass: entityClass, storeURLs: storeURLs)
|
||||
self.init(entityClass: entityClass, storeURLs: [storeURL] + otherStoreURLs)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ storeURLs: [NSURL]) {
|
||||
@@ -114,9 +156,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: entityClass, storeURLs: storeURLs)
|
||||
}
|
||||
|
||||
public init(_ persistentStores: NSPersistentStore...) {
|
||||
public init(_ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
self.init(entityClass: T.self, persistentStores: persistentStores)
|
||||
self.init(entityClass: T.self, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
}
|
||||
|
||||
public init(_ persistentStores: [NSPersistentStore]) {
|
||||
@@ -124,9 +166,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: T.self, persistentStores: persistentStores)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ persistentStores: NSPersistentStore...) {
|
||||
public init(_ entity: T.Type, _ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
self.init(entityClass: entity, persistentStores: persistentStores)
|
||||
self.init(entityClass: entity, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
}
|
||||
|
||||
public init(_ entity: T.Type, _ persistentStores: [NSPersistentStore]) {
|
||||
@@ -134,9 +176,9 @@ public struct From<T: NSManagedObject> {
|
||||
self.init(entityClass: entity, persistentStores: persistentStores)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ persistentStores: NSPersistentStore...) {
|
||||
public init(_ entityClass: AnyClass, _ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
self.init(entityClass: entityClass, persistentStores: persistentStores)
|
||||
self.init(entityClass: entityClass, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
}
|
||||
|
||||
public init(_ entityClass: AnyClass, _ persistentStores: [NSPersistentStore]) {
|
||||
@@ -147,10 +189,20 @@ public struct From<T: NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal func applyToFetchRequest(fetchRequest: NSFetchRequest, context: NSManagedObjectContext) {
|
||||
internal func applyToFetchRequest(fetchRequest: NSFetchRequest, context: NSManagedObjectContext, applyAffectedStores: Bool = true) {
|
||||
|
||||
fetchRequest.entity = context.entityDescriptionForEntityClass(self.entityClass)
|
||||
fetchRequest.affectedStores = self.findPersistentStores(context: context)
|
||||
if applyAffectedStores {
|
||||
|
||||
self.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
internal func applyAffectedStoresForFetchedRequest(fetchRequest: NSFetchRequest, context: NSManagedObjectContext) -> Bool {
|
||||
|
||||
let stores = self.findPersistentStores(context: context)
|
||||
fetchRequest.affectedStores = stores
|
||||
return stores?.isEmpty == false
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +212,15 @@ public struct From<T: NSManagedObject> {
|
||||
|
||||
private let findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?
|
||||
|
||||
private init(entityClass: AnyClass) {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.findPersistentStores = { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)
|
||||
}
|
||||
}
|
||||
|
||||
private init(entityClass: AnyClass, configurations: [String?]) {
|
||||
|
||||
let configurationsSet = Set(configurations.map { $0 ?? Into.defaultConfigurationName })
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// GroupBy.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -34,8 +34,6 @@ The `GroupBy` clause specifies that the result of a query be grouped accoording
|
||||
*/
|
||||
public struct GroupBy: QueryClause {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a list of key path strings
|
||||
|
||||
@@ -72,7 +70,7 @@ public struct GroupBy: QueryClause {
|
||||
|
||||
public func applyToFetchRequest(fetchRequest: NSFetchRequest) {
|
||||
|
||||
if fetchRequest.propertiesToGroupBy != nil {
|
||||
if let keyPaths = fetchRequest.propertiesToGroupBy as? [String] where keyPaths != self.keyPaths {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// OrderBy.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -69,8 +69,6 @@ The `OrderBy` clause specifies the sort order for results for a fetch or a query
|
||||
*/
|
||||
public struct OrderBy: FetchClause, QueryClause, DeleteClause {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `OrderBy` clause with a list of sort descriptors
|
||||
|
||||
@@ -139,7 +137,7 @@ public struct OrderBy: FetchClause, QueryClause, DeleteClause {
|
||||
|
||||
public func applyToFetchRequest(fetchRequest: NSFetchRequest) {
|
||||
|
||||
if fetchRequest.sortDescriptors != nil {
|
||||
if let sortDescriptors = fetchRequest.sortDescriptors where sortDescriptors != self.sortDescriptors {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Select.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -64,25 +64,23 @@ The `SelectTerm` is passed to the `Select` clause to indicate the attributes/agg
|
||||
*/
|
||||
public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for querying an entity attribute. A shorter way to do the same is to assign from the string keypath directly:
|
||||
|
||||
```
|
||||
let fullName = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<String>(.Attribute("fullName")),
|
||||
Where("employeeID", isEqualTo: 1111)
|
||||
)
|
||||
|
||||
```
|
||||
is equivalent to:
|
||||
|
||||
```
|
||||
let fullName = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<String>("fullName"),
|
||||
Where("employeeID", isEqualTo: 1111)
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying an entity attribute
|
||||
*/
|
||||
@@ -93,12 +91,12 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for querying the average value of an attribute.
|
||||
|
||||
```
|
||||
let averageAge = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Average("age"))
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "average(<attributeName>)" is used
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the average value of an attribute
|
||||
@@ -115,12 +113,12 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for a count query.
|
||||
|
||||
```
|
||||
let numberOfEmployees = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Count("employeeID"))
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "count(<attributeName>)" is used
|
||||
- returns: a `SelectTerm` to a `Select` clause for a count query
|
||||
@@ -137,12 +135,12 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for querying the maximum value for an attribute.
|
||||
|
||||
```
|
||||
let maximumAge = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Maximum("age"))
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "max(<attributeName>)" is used
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the maximum value for an attribute
|
||||
@@ -159,12 +157,12 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for querying the minimum value for an attribute.
|
||||
|
||||
```
|
||||
let minimumAge = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Minimum("age"))
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "min(<attributeName>)" is used
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the minimum value for an attribute
|
||||
@@ -181,12 +179,12 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
|
||||
/**
|
||||
Provides a `SelectTerm` to a `Select` clause for querying the sum value for an attribute.
|
||||
|
||||
```
|
||||
let totalAge = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Sum("age"))
|
||||
)
|
||||
|
||||
```
|
||||
- parameter keyPath: the attribute name
|
||||
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "sum(<attributeName>)" is used
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
|
||||
@@ -233,19 +231,19 @@ public enum SelectTerm: StringLiteralConvertible {
|
||||
The `Select` clause indicates the attribute / aggregate value to be queried. The generic type is a `SelectResultType`, and will be used as the return type for the query.
|
||||
|
||||
You can bind the return type by specializing the initializer:
|
||||
|
||||
```
|
||||
let maximumAge = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select<Int>(.Maximum("age"))
|
||||
)
|
||||
|
||||
```
|
||||
or by casting the type of the return value:
|
||||
|
||||
```
|
||||
let maximumAge: Int = CoreStore.queryValue(
|
||||
From(MyPersonEntity),
|
||||
Select(.Maximum("age"))
|
||||
)
|
||||
|
||||
```
|
||||
Valid return types depend on the query:
|
||||
|
||||
- for `queryValue(...)` methods:
|
||||
@@ -271,8 +269,6 @@ Valid return types depend on the query:
|
||||
*/
|
||||
public struct Select<T: SelectResultType> {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
The `SelectResultType` type for the query's return value
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Tweak.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,9 +31,8 @@ import CoreData
|
||||
|
||||
/**
|
||||
The `Tweak` clause allows fine-tuning the `NSFetchRequest` for a fetch or query.
|
||||
|
||||
Sample usage:
|
||||
|
||||
```
|
||||
let employees = transaction.fetchAll(
|
||||
From(MyPersonEntity),
|
||||
Tweak { (fetchRequest) -> Void in
|
||||
@@ -41,11 +40,10 @@ Sample usage:
|
||||
fetchRequest.fetchLimit = 5
|
||||
}
|
||||
)
|
||||
```
|
||||
*/
|
||||
public struct Tweak: FetchClause, QueryClause, DeleteClause {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `Tweak` clause with a closure where the `NSFetchRequest` may be configured.
|
||||
|
||||
@@ -65,5 +63,7 @@ public struct Tweak: FetchClause, QueryClause, DeleteClause {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let customization: (fetchRequest: NSFetchRequest) -> Void
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Where.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -50,8 +50,6 @@ The `Where` clause specifies the conditions for a fetch or a query.
|
||||
*/
|
||||
public struct Where: FetchClause, QueryClause, DeleteClause {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause with an `NSPredicate`
|
||||
|
||||
@@ -144,7 +142,7 @@ public struct Where: FetchClause, QueryClause, DeleteClause {
|
||||
|
||||
public func applyToFetchRequest(fetchRequest: NSFetchRequest) {
|
||||
|
||||
if fetchRequest.predicate != nil {
|
||||
if let predicate = fetchRequest.predicate where predicate != self.predicate {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Querying.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,8 +31,6 @@ import CoreData
|
||||
|
||||
public extension CoreStore {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the `NSManagedObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DataStack+Querying.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -34,8 +34,6 @@ import CoreData
|
||||
|
||||
public extension DataStack {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ClauseTypes.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -29,6 +29,9 @@ import CoreData
|
||||
|
||||
// MARK: - FetchClause
|
||||
|
||||
/**
|
||||
The `FetchClause` implement clauses used to configure `NSFetchRequest`s.
|
||||
*/
|
||||
public protocol FetchClause {
|
||||
|
||||
func applyToFetchRequest(fetchRequest: NSFetchRequest)
|
||||
@@ -37,6 +40,9 @@ public protocol FetchClause {
|
||||
|
||||
// MARK: - QueryClause
|
||||
|
||||
/**
|
||||
The `QueryClause` implement clauses used to configure `NSFetchRequest`s.
|
||||
*/
|
||||
public protocol QueryClause {
|
||||
|
||||
func applyToFetchRequest(fetchRequest: NSFetchRequest)
|
||||
@@ -45,6 +51,9 @@ public protocol QueryClause {
|
||||
|
||||
// MARK: - DeleteClause
|
||||
|
||||
/**
|
||||
The `DeleteClause` implement clauses used to configure `NSFetchRequest`s.
|
||||
*/
|
||||
public protocol DeleteClause {
|
||||
|
||||
func applyToFetchRequest(fetchRequest: NSFetchRequest)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// BaseDataTransaction+Importing.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,8 +31,6 @@ import CoreData
|
||||
|
||||
public extension BaseDataTransaction {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Creates an `ImportableObject` by importing from the specified import source.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ImportableObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,7 +31,7 @@ import CoreData
|
||||
|
||||
/**
|
||||
`NSManagedObject` subclasses that conform to the `ImportableObject` protocol can be imported from a specified `ImportSource`. This allows transactions to create and insert instances this way:
|
||||
|
||||
```
|
||||
class MyPersonEntity: NSManagedObject, ImportableObject {
|
||||
typealias ImportSource = NSDictionary
|
||||
// ...
|
||||
@@ -46,6 +46,7 @@ import CoreData
|
||||
// ...
|
||||
transaction.commit()
|
||||
}
|
||||
```
|
||||
*/
|
||||
public protocol ImportableObject: class {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ImportableUniqueObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,7 +31,7 @@ import CoreData
|
||||
|
||||
/**
|
||||
`NSManagedObject` subclasses that conform to the `ImportableUniqueObject` protocol can be imported from a specified `ImportSource`. This allows transactions to either update existing objects or create new instances this way:
|
||||
|
||||
```
|
||||
class MyPersonEntity: NSManagedObject, ImportableUniqueObject {
|
||||
typealias ImportSource = NSDictionary
|
||||
typealias UniqueIDType = NSString
|
||||
@@ -47,6 +47,7 @@ import CoreData
|
||||
// ...
|
||||
transaction.commit()
|
||||
}
|
||||
```
|
||||
*/
|
||||
public protocol ImportableUniqueObject: ImportableObject {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.4.4</string>
|
||||
<string>1.5.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSObject+CoreStore.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// CoreStoreFetchedResultsController.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 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: - CoreStoreFetchedResultsController
|
||||
|
||||
@available(OSX, unavailable)
|
||||
internal final class CoreStoreFetchedResultsController<T: NSManagedObject>: NSFetchedResultsController {
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal convenience init<T>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
fetchRequest: fetchRequest,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
internal init<T>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
|
||||
from?.applyToFetchRequest(fetchRequest, context: context, applyAffectedStores: false)
|
||||
for clause in fetchClauses {
|
||||
|
||||
clause.applyToFetchRequest(fetchRequest)
|
||||
}
|
||||
|
||||
if let from = from {
|
||||
|
||||
self.reapplyAffectedStores = {
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
guard let from = (fetchRequest.entity.flatMap { $0.managedObjectClassName }).flatMap(NSClassFromString).flatMap(From.init) else {
|
||||
|
||||
fatalError("Attempted to create an \(typeName(NSFetchedResultsController)) without a From clause or an NSEntityDescription.")
|
||||
}
|
||||
|
||||
self.reapplyAffectedStores = {
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
super.init(
|
||||
fetchRequest: fetchRequest,
|
||||
managedObjectContext: context,
|
||||
sectionNameKeyPath: sectionBy?.sectionKeyPath,
|
||||
cacheName: nil
|
||||
)
|
||||
}
|
||||
|
||||
internal func performFetchFromSpecifiedStores() throws {
|
||||
|
||||
if !self.reapplyAffectedStores() {
|
||||
|
||||
CoreStore.log(
|
||||
.Warning,
|
||||
message: "Attempted to perform a fetch on an \(typeName(NSFetchedResultsController)) but could not find any persistent store for the entity \(typeName(self.fetchRequest.entityName))"
|
||||
)
|
||||
}
|
||||
try self.performFetch()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let reapplyAffectedStores: () -> Bool
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// FetchedResultsControllerDelegate.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Functions.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// MigrationManager.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObjectContext+CoreStore.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObjectContext+Querying.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObjectContext+Setup.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObjectContext+Transaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -167,6 +167,18 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
}
|
||||
|
||||
internal func refreshAllObjectsAsFaults() {
|
||||
|
||||
if #available(iOS 8.3, OSX 10.11, *) {
|
||||
|
||||
self.refreshAllObjects()
|
||||
}
|
||||
else {
|
||||
|
||||
self.registeredObjects.forEach { self.refreshObject($0, mergeChanges: false) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObjectModel+Setup.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NotificationObserver.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// WeakObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Logging.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -30,8 +30,6 @@ import Foundation
|
||||
|
||||
public extension CoreStore {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
The `CoreStoreLogger` instance to be used. The default logger is an instance of a `DefaultLogger`.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStoreLogger.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -86,7 +86,7 @@ public protocol CoreStoreLogger {
|
||||
|
||||
internal func typeName<T>(value: T) -> String {
|
||||
|
||||
return "'\(_stdlib_getDemangledTypeName(value))'"
|
||||
return "'\(String(reflecting: value.dynamicType))'"
|
||||
}
|
||||
|
||||
internal func typeName<T>(value: T.Type) -> String {
|
||||
@@ -101,6 +101,5 @@ internal func typeName(value: AnyClass) -> String {
|
||||
|
||||
internal func typeName(name: String?) -> String {
|
||||
|
||||
let typeName = name ?? "unknown"
|
||||
return "<\(typeName)>"
|
||||
return "<\(name ?? "unknown")>"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DefaultLogger.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Migration.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DataStack+Migration.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// MigrationChain.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -33,23 +33,23 @@ import CoreData
|
||||
A `MigrationChain` indicates the sequence of model versions to be used as the order for incremental migration. This is typically passed to the `DataStack` initializer and will be applied to all stores added to the `DataStack` with `addSQLiteStore(...)` and its variants.
|
||||
|
||||
Initializing with empty values (either `nil`, `[]`, or `[:]`) instructs the `DataStack` to use the .xcdatamodel's current version as the final version, and to disable incremental migrations:
|
||||
|
||||
```
|
||||
let dataStack = DataStack(migrationChain: nil)
|
||||
|
||||
```
|
||||
This means that the mapping model will be computed from the store's version straight to the `DataStack`'s model version.
|
||||
To support incremental migrations, specify the linear order of versions:
|
||||
|
||||
```
|
||||
let dataStack = DataStack(migrationChain:
|
||||
["MyAppModel", "MyAppModelV2", "MyAppModelV3", "MyAppModelV4"])
|
||||
|
||||
```
|
||||
or for more complex migration paths, a version tree that maps the key-values to the source-destination versions:
|
||||
|
||||
```
|
||||
let dataStack = DataStack(migrationChain: [
|
||||
"MyAppModel": "MyAppModelV3",
|
||||
"MyAppModelV2": "MyAppModelV4",
|
||||
"MyAppModelV3": "MyAppModelV4"
|
||||
])
|
||||
|
||||
```
|
||||
This allows for different migration paths depending on the starting version. The example above resolves to the following paths:
|
||||
- MyAppModel-MyAppModelV3-MyAppModelV4
|
||||
- MyAppModelV2-MyAppModelV4
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// MigrationResult.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,7 +31,7 @@ import Foundation
|
||||
/**
|
||||
The `MigrationResult` indicates the result of a migration.
|
||||
The `MigrationResult` can be treated as a boolean:
|
||||
|
||||
```
|
||||
CoreStore.upgradeSQLiteStoreIfNeeded { transaction in
|
||||
// ...
|
||||
let result = transaction.commit()
|
||||
@@ -42,9 +42,9 @@ The `MigrationResult` can be treated as a boolean:
|
||||
// failed
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
or as an `enum`, where the resulting associated object can also be inspected:
|
||||
|
||||
```
|
||||
CoreStore.beginAsynchronous { transaction in
|
||||
// ...
|
||||
let result = transaction.commit()
|
||||
@@ -59,8 +59,6 @@ or as an `enum`, where the resulting associated object can also be inspected:
|
||||
*/
|
||||
public enum MigrationResult {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
`MigrationResult.Success` indicates either the migration succeeded, or there were no migrations needed. The associated value is an array of `MigrationType`s reflecting the migration steps completed.
|
||||
*/
|
||||
@@ -103,6 +101,7 @@ extension MigrationResult: BooleanType {
|
||||
public var boolValue: Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .Success: return true
|
||||
case .Failure: return false
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// MigrationType.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -33,8 +33,6 @@ The `MigrationType` specifies the type of migration required for a store.
|
||||
*/
|
||||
public enum MigrationType: BooleanType {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Indicates that the persistent store matches the latest model version and no migration is needed
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSError+CoreStore.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -26,6 +26,9 @@
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - CoreStoreError
|
||||
|
||||
/**
|
||||
The `NSError` error domain for `CoreStore`.
|
||||
*/
|
||||
@@ -58,7 +61,7 @@ public enum CoreStoreErrorCode: Int {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - NSError+CoreStore
|
||||
// MARK: - NSError
|
||||
|
||||
public extension NSError {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Observing.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -32,8 +32,6 @@ import CoreData
|
||||
@available(OSX, unavailable)
|
||||
public extension CoreStore {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, creates a `ObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DataStack+Observing.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -35,8 +35,6 @@ import CoreData
|
||||
@available(OSX, unavailable)
|
||||
public extension DataStack {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Creates a `ObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ListMonitor.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -34,25 +34,25 @@ import CoreData
|
||||
|
||||
/**
|
||||
The `ListMonitor` monitors changes to a list of `NSManagedObject` instances. Observers that implement the `ListObserver` protocol may then register themselves to the `ListMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorList(
|
||||
From(MyPersonEntity),
|
||||
Where("title", isEqualTo: "Engineer"),
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
|
||||
```
|
||||
The `ListMonitor` instance needs to be held on (retained) for as long as the list needs to be observed.
|
||||
Observers registered via `addObserver(_:)` are not retained. `ListMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles.
|
||||
|
||||
Lists created with `monitorList(...)` keep a single-section list of objects, where each object can be accessed by index:
|
||||
|
||||
```
|
||||
let firstPerson: MyPersonEntity = monitor[0]
|
||||
|
||||
```
|
||||
Accessing the list with an index above the valid range will throw an exception.
|
||||
|
||||
Creating a sectioned-list is also possible with the `monitorSectionedList(...)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorSectionedList(
|
||||
From(MyPersonEntity),
|
||||
SectionBy("age") { "Age \($0)" },
|
||||
@@ -60,13 +60,13 @@ Creating a sectioned-list is also possible with the `monitorSectionedList(...)`
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
|
||||
```
|
||||
Objects from `ListMonitor`s created this way can be accessed either by an `NSIndexPath` or a tuple:
|
||||
|
||||
```
|
||||
let indexPath = NSIndexPath(forItem: 3, inSection: 2)
|
||||
let person1 = monitor[indexPath]
|
||||
let person2 = monitor[2, 3]
|
||||
|
||||
```
|
||||
In the example above, both `person1` and `person2` will contain the object at section=2, index=3.
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@@ -882,12 +882,15 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
"Attempted to refetch a \(typeName(self)) outside the main thread."
|
||||
)
|
||||
|
||||
if !self.isPendingRefetch {
|
||||
|
||||
self.isPendingRefetch = true
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(
|
||||
ListMonitorWillRefetchListNotification,
|
||||
object: self
|
||||
)
|
||||
}
|
||||
|
||||
self.taskGroup.notify(.Main) { [weak self] () -> Void in
|
||||
|
||||
@@ -904,14 +907,14 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
clause.applyToFetchRequest(fetchRequest)
|
||||
}
|
||||
|
||||
strongSelf.parentStack?.childTransactionQueue.async {
|
||||
strongSelf.transactionQueue.async {
|
||||
|
||||
guard let strongSelf = self else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
try! strongSelf.fetchedResultsController.performFetch()
|
||||
try! strongSelf.fetchedResultsController.performFetchFromSpecifiedStores()
|
||||
|
||||
GCDQueue.Main.async { () -> Void in
|
||||
|
||||
@@ -938,36 +941,54 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
internal convenience init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause]) {
|
||||
|
||||
self.init(
|
||||
dataStack: dataStack,
|
||||
context: dataStack.mainContext,
|
||||
transactionQueue: dataStack.childTransactionQueue,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses,
|
||||
prepareFetch: { _, performFetch in performFetch() }
|
||||
createAsynchronously: nil
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], createAsynchronously: (ListMonitor<T>) -> Void) {
|
||||
|
||||
let queue = dataStack.childTransactionQueue
|
||||
self.init(
|
||||
dataStack: dataStack,
|
||||
context: dataStack.mainContext,
|
||||
transactionQueue: queue,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses,
|
||||
prepareFetch: { listMonitor, performFetch in
|
||||
|
||||
dataStack.childTransactionQueue.async {
|
||||
|
||||
performFetch()
|
||||
GCDQueue.Main.async {
|
||||
|
||||
createAsynchronously(listMonitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
createAsynchronously: createAsynchronously
|
||||
)
|
||||
}
|
||||
|
||||
private init(dataStack: DataStack, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], prepareFetch: (ListMonitor<T>, () -> Void) -> Void) {
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause]) {
|
||||
|
||||
self.init(
|
||||
context: unsafeTransaction.context,
|
||||
transactionQueue: unsafeTransaction.transactionQueue,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses,
|
||||
createAsynchronously: nil
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], createAsynchronously: (ListMonitor<T>) -> Void) {
|
||||
|
||||
let queue = unsafeTransaction.transactionQueue
|
||||
self.init(
|
||||
context: unsafeTransaction.context,
|
||||
transactionQueue: queue,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses,
|
||||
createAsynchronously: createAsynchronously
|
||||
)
|
||||
}
|
||||
|
||||
private init(context: NSManagedObjectContext, transactionQueue: GCDQueue, from: From<T>, sectionBy: SectionBy?, fetchClauses: [FetchClause], createAsynchronously: ((ListMonitor<T>) -> Void)?) {
|
||||
|
||||
let fetchRequest = NSFetchRequest()
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -976,8 +997,8 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
fetchRequest.includesPendingChanges = false
|
||||
fetchRequest.shouldRefreshRefetchedObjects = true
|
||||
|
||||
let fetchedResultsController = NSFetchedResultsController(
|
||||
dataStack: dataStack,
|
||||
let fetchedResultsController = CoreStoreFetchedResultsController<T>(
|
||||
context: context,
|
||||
fetchRequest: fetchRequest,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
@@ -988,7 +1009,6 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
|
||||
self.fetchedResultsController = fetchedResultsController
|
||||
self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate
|
||||
self.parentStack = dataStack
|
||||
|
||||
if let sectionIndexTransformer = sectionBy?.sectionIndexTransformer {
|
||||
|
||||
@@ -998,26 +1018,118 @@ public final class ListMonitor<T: NSManagedObject> {
|
||||
|
||||
self.sectionIndexTransformer = { $0 }
|
||||
}
|
||||
self.transactionQueue = transactionQueue
|
||||
|
||||
fetchedResultsControllerDelegate.handler = self
|
||||
fetchedResultsControllerDelegate.fetchedResultsController = fetchedResultsController
|
||||
|
||||
prepareFetch(self, { try! fetchedResultsController.performFetch() })
|
||||
guard let coordinator = context.parentStack?.coordinator else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.observerForWillChangePersistentStore = NotificationObserver(
|
||||
notificationName: NSPersistentStoreCoordinatorStoresWillChangeNotification,
|
||||
object: coordinator,
|
||||
closure: { [weak self] (note) -> Void in
|
||||
|
||||
guard let `self` = self else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.isPersistentStoreChanging = true
|
||||
|
||||
guard let removedStores = (note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore]).flatMap(Set.init)
|
||||
where !Set(self.fetchedResultsController.fetchRequest.affectedStores ?? []).intersect(removedStores).isEmpty else {
|
||||
|
||||
return
|
||||
}
|
||||
self.refetch(fetchClauses)
|
||||
}
|
||||
)
|
||||
|
||||
self.observerForDidChangePersistentStore = NotificationObserver(
|
||||
notificationName: NSPersistentStoreCoordinatorStoresDidChangeNotification,
|
||||
object: coordinator,
|
||||
closure: { [weak self] (note) -> Void in
|
||||
|
||||
guard let `self` = self else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if !self.isPendingRefetch {
|
||||
|
||||
let previousStores = Set(self.fetchedResultsController.fetchRequest.affectedStores ?? [])
|
||||
let currentStores = previousStores
|
||||
.subtract(note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore] ?? [])
|
||||
.union(note.userInfo?[NSAddedPersistentStoresKey] as? [NSPersistentStore] ?? [])
|
||||
|
||||
if previousStores != currentStores {
|
||||
|
||||
self.refetch(fetchClauses)
|
||||
}
|
||||
}
|
||||
|
||||
self.isPersistentStoreChanging = false
|
||||
}
|
||||
)
|
||||
|
||||
if let createAsynchronously = createAsynchronously {
|
||||
|
||||
transactionQueue.async {
|
||||
|
||||
try! fetchedResultsController.performFetchFromSpecifiedStores()
|
||||
self.taskGroup.notify(.Main) {
|
||||
|
||||
createAsynchronously(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
try! fetchedResultsController.performFetchFromSpecifiedStores()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
self.fetchedResultsControllerDelegate.fetchedResultsController = nil
|
||||
self.isPersistentStoreChanging = false
|
||||
}
|
||||
|
||||
private var isPersistentStoreChanging: Bool = false {
|
||||
|
||||
didSet {
|
||||
|
||||
let newValue = self.isPersistentStoreChanging
|
||||
guard newValue != oldValue else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if newValue {
|
||||
|
||||
self.taskGroup.enter()
|
||||
}
|
||||
else {
|
||||
|
||||
self.taskGroup.leave()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let fetchedResultsController: NSFetchedResultsController
|
||||
private let fetchedResultsController: CoreStoreFetchedResultsController<T>
|
||||
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate
|
||||
private let sectionIndexTransformer: (sectionName: KeyPath?) -> String?
|
||||
private var observerForWillChangePersistentStore: NotificationObserver!
|
||||
private var observerForDidChangePersistentStore: NotificationObserver!
|
||||
private let taskGroup = GCDGroup()
|
||||
private weak var parentStack: DataStack?
|
||||
private let transactionQueue: GCDQueue
|
||||
|
||||
private var willChangeListKey: Void?
|
||||
private var didChangeListKey: Void?
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ListObserver.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,12 +31,13 @@ import CoreData
|
||||
|
||||
/**
|
||||
Implement the `ListObserver` protocol to observe changes to a list of `NSManagedObject`s. `ListObserver`s may register themselves to a `ListMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorList(
|
||||
From(MyPersonEntity),
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
public protocol ListObserver: class {
|
||||
@@ -107,12 +108,13 @@ public extension ListObserver {
|
||||
|
||||
/**
|
||||
Implement the `ListObjectObserver` protocol to observe detailed changes to a list's object. `ListObjectObserver`s may register themselves to a `ListMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorList(
|
||||
From(MyPersonEntity),
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
public protocol ListObjectObserver: ListObserver {
|
||||
@@ -187,13 +189,14 @@ public extension ListObjectObserver {
|
||||
|
||||
/**
|
||||
Implement the `ListSectionObserver` protocol to observe changes to a list's section info. `ListSectionObserver`s may register themselves to a `ListMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorSectionedList(
|
||||
From(MyPersonEntity),
|
||||
SectionBy("age") { "Age \($0)" },
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
monitor.addObserver(self)
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
public protocol ListSectionObserver: ListObjectObserver {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ObjectMonitor.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -34,10 +34,10 @@ import CoreData
|
||||
|
||||
/**
|
||||
The `ObjectMonitor` monitors changes to a single `NSManagedObject` instance. Observers that implement the `ObjectObserver` protocol may then register themselves to the `ObjectMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorObject(object)
|
||||
monitor.addObserver(self)
|
||||
|
||||
```
|
||||
The created `ObjectMonitor` instance needs to be held on (retained) for as long as the object needs to be observed.
|
||||
|
||||
Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles.
|
||||
@@ -45,8 +45,6 @@ Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` onl
|
||||
@available(OSX, unavailable)
|
||||
public final class ObjectMonitor<T: NSManagedObject> {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Returns the `NSManagedObject` instance being observed, or `nil` if the object was already deleted.
|
||||
*/
|
||||
@@ -165,7 +163,17 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(dataStack: DataStack, object: T) {
|
||||
internal convenience init(dataStack: DataStack, object: T) {
|
||||
|
||||
self.init(context: dataStack.mainContext, object: object)
|
||||
}
|
||||
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, object: T) {
|
||||
|
||||
self.init(context: unsafeTransaction.context, object: object)
|
||||
}
|
||||
|
||||
private init(context: NSManagedObjectContext, object: T) {
|
||||
|
||||
let fetchRequest = NSFetchRequest()
|
||||
fetchRequest.entity = object.entity
|
||||
@@ -175,8 +183,8 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
fetchRequest.includesPendingChanges = false
|
||||
fetchRequest.shouldRefreshRefetchedObjects = true
|
||||
|
||||
let fetchedResultsController = NSFetchedResultsController(
|
||||
dataStack: dataStack,
|
||||
let fetchedResultsController = CoreStoreFetchedResultsController<T>(
|
||||
context: context,
|
||||
fetchRequest: fetchRequest,
|
||||
fetchClauses: [Where("SELF", isEqualTo: object.objectID)]
|
||||
)
|
||||
@@ -185,11 +193,10 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
|
||||
self.fetchedResultsController = fetchedResultsController
|
||||
self.fetchedResultsControllerDelegate = fetchedResultsControllerDelegate
|
||||
self.parentStack = dataStack
|
||||
|
||||
fetchedResultsControllerDelegate.handler = self
|
||||
fetchedResultsControllerDelegate.fetchedResultsController = fetchedResultsController
|
||||
try! fetchedResultsController.performFetch()
|
||||
try! fetchedResultsController.performFetchFromSpecifiedStores()
|
||||
|
||||
self.lastCommittedAttributes = (self.object?.committedValuesForKeys(nil) as? [String: NSObject]) ?? [:]
|
||||
}
|
||||
@@ -202,10 +209,9 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let fetchedResultsController: NSFetchedResultsController
|
||||
private let fetchedResultsController: CoreStoreFetchedResultsController<T>
|
||||
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate
|
||||
private var lastCommittedAttributes = [String: NSObject]()
|
||||
private weak var parentStack: DataStack?
|
||||
|
||||
private var willChangeObjectKey: Void?
|
||||
private var didDeleteObjectKey: Void?
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// ObjectObserver.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,9 +31,10 @@ import CoreData
|
||||
|
||||
/**
|
||||
Implement the `ObjectObserver` protocol to observe changes to a single `NSManagedObject` instance. `ObjectObserver`s may register themselves to a `ObjectMonitor`'s `addObserver(_:)` method:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorObject(object)
|
||||
monitor.addObserver(self)
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
public protocol ObjectObserver: class {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SectionBy.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -31,18 +31,17 @@ import CoreData
|
||||
|
||||
/**
|
||||
The `SectionBy` clause indicates the key path to use to group the `ListMonitor` objects into sections. An optional closure can also be provided to transform the value into an appropriate section name:
|
||||
|
||||
```
|
||||
let monitor = CoreStore.monitorSectionedList(
|
||||
From(MyPersonEntity),
|
||||
SectionBy("age") { "Age \($0)" },
|
||||
OrderBy(.Ascending("lastName"))
|
||||
)
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
public struct SectionBy {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
//
|
||||
// UnsafeDataTransaction+Observing.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 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
|
||||
#if USE_FRAMEWORKS
|
||||
import GCDKit
|
||||
#endif
|
||||
|
||||
|
||||
// MARK: - UnsafeDataTransaction
|
||||
|
||||
@available(OSX, unavailable)
|
||||
public extension UnsafeDataTransaction {
|
||||
|
||||
/**
|
||||
Creates a `ObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
|
||||
|
||||
- parameter object: the `NSManagedObject` to observe changes from
|
||||
- returns: a `ObjectMonitor` that monitors changes to `object`
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func monitorObject<T: NSManagedObject>(object: T) -> ObjectMonitor<T> {
|
||||
|
||||
return ObjectMonitor(
|
||||
unsafeTransaction: self,
|
||||
object: object
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func monitorList<T: NSManagedObject>(from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
return self.monitorList(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func monitorList<T: NSManagedObject>(from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchClauses.filter { $0 is OrderBy }.count > 0,
|
||||
"A ListMonitor requires an OrderBy clause."
|
||||
)
|
||||
|
||||
return ListMonitor(
|
||||
unsafeTransaction: self,
|
||||
from: from,
|
||||
sectionBy: nil,
|
||||
fetchClauses: 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...) {
|
||||
|
||||
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(
|
||||
fetchClauses.filter { $0 is OrderBy }.count > 0,
|
||||
"A ListMonitor requires an OrderBy clause."
|
||||
)
|
||||
|
||||
_ = ListMonitor(
|
||||
unsafeTransaction: 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.
|
||||
|
||||
- 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func monitorSectionedList<T: NSManagedObject>(from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
|
||||
return self.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
- 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.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func monitorSectionedList<T: NSManagedObject>(from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchClauses.filter { $0 is OrderBy }.count > 0,
|
||||
"A ListMonitor requires an OrderBy clause."
|
||||
)
|
||||
|
||||
return ListMonitor(
|
||||
unsafeTransaction: self,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
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(
|
||||
fetchClauses.filter { $0 is OrderBy }.count > 0,
|
||||
"A ListMonitor requires an OrderBy clause."
|
||||
)
|
||||
|
||||
_ = ListMonitor(
|
||||
unsafeTransaction: self,
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
fetchClauses: fetchClauses,
|
||||
createAsynchronously: createAsynchronously
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// AsynchronousDataTransaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -37,8 +37,6 @@ The `AsynchronousDataTransaction` provides an interface for `NSManagedObject` cr
|
||||
*/
|
||||
public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Saves the transaction changes. This method should not be used after the `commit()` method was already called once.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// BaseDataTransaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -188,6 +188,257 @@ 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: Inspecting Pending Objects
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- returns: a `Set` of pending `NSManagedObject`s that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access inserted objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return self.context.insertedObjects
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjects<T: NSManagedObject>(entity: T.Type) -> Set<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access inserted objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.insertedObjects.flatMap { $0 as? T })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access inserted object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.insertedObjects.map { $0.objectID })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjectIDs<T: NSManagedObject>(entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access inserted object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.insertedObjects.flatMap { $0 as? T }.map { $0.objectID })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- returns: a `Set` of pending `NSManagedObject`s that were updated to the transaction.
|
||||
*/
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access updated objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return self.context.updatedObjects
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were updated in the transaction.
|
||||
*/
|
||||
public func updatedObjects<T: NSManagedObject>(entity: T.Type) -> Set<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access updated objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.updatedObjects.flatMap { $0 as? T })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s that were updated in the transaction.
|
||||
*/
|
||||
public func updatedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access updated object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated object IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.updatedObjects.map { $0.objectID })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction.
|
||||
*/
|
||||
public func updatedObjectIDs<T: NSManagedObject>(entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access updated object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated object IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.updatedObjects.flatMap { $0 as? T }.map { $0.objectID })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- returns: a `Set` of pending `NSManagedObject`s that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access deleted objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return self.context.deletedObjects
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObject`s of the specified type that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjects<T: NSManagedObject>(entity: T.Type) -> Set<T> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access deleted objects from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.deletedObjects.flatMap { $0 as? T })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access deleted object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted object IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.deletedObjects.map { $0.objectID })
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called.
|
||||
|
||||
- parameter entity: the `NSManagedObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjectIDs<T: NSManagedObject>(entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.isCurrentExecutionContext(),
|
||||
"Attempted to access deleted object IDs from a \(typeName(self)) outside its designated queue."
|
||||
)
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted object IDs from an already committed \(typeName(self))."
|
||||
)
|
||||
|
||||
return Set(self.context.deletedObjects.flatMap { $0 as? T }.map { $0.objectID })
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Transaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -30,8 +30,6 @@ import Foundation
|
||||
|
||||
public extension CoreStore {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
@@ -65,6 +63,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 {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DataStack+Transaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -34,8 +34,6 @@ import CoreData
|
||||
|
||||
public extension DataStack {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.
|
||||
|
||||
@@ -82,6 +80,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 {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Into.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -30,25 +30,23 @@ import CoreData
|
||||
// MARK: - Into
|
||||
|
||||
/**
|
||||
A `Into` clause contains the destination entity and destination persistent store for a `create(...)` method. A common usage is to just indicate the entity:
|
||||
|
||||
An `Into` clause contains the destination entity and destination persistent store for a `create(...)` method. A common usage is to just indicate the entity:
|
||||
```
|
||||
let person = transaction.create(Into(MyPersonEntity))
|
||||
|
||||
```
|
||||
For cases where multiple `NSPersistentStore`s contain the same entity, the destination configuration's name needs to be specified as well:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into<MyPersonEntity>("Configuration1"))
|
||||
|
||||
This helps the `NSManagedObjectContext` to determine which
|
||||
```
|
||||
*/
|
||||
public struct Into<T: NSManagedObject> {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes an `Into` clause.
|
||||
Sample Usage:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into<MyPersonEntity>())
|
||||
```
|
||||
*/
|
||||
public init(){
|
||||
|
||||
@@ -60,9 +58,9 @@ public struct Into<T: NSManagedObject> {
|
||||
/**
|
||||
Initializes an `Into` clause with the specified entity type.
|
||||
Sample Usage:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into(MyPersonEntity))
|
||||
|
||||
```
|
||||
- parameter entity: the `NSManagedObject` type to be created
|
||||
*/
|
||||
public init(_ entity: T.Type) {
|
||||
@@ -74,7 +72,10 @@ public struct Into<T: NSManagedObject> {
|
||||
|
||||
/**
|
||||
Initializes an `Into` clause with the specified entity class.
|
||||
|
||||
Sample Usage:
|
||||
```
|
||||
let person = transaction.create(Into(MyPersonEntity))
|
||||
```
|
||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||
*/
|
||||
public init(_ entityClass: AnyClass) {
|
||||
@@ -87,9 +88,9 @@ public struct Into<T: NSManagedObject> {
|
||||
/**
|
||||
Initializes an `Into` clause with the specified configuration.
|
||||
Sample Usage:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into<MyPersonEntity>("Configuration1"))
|
||||
|
||||
```
|
||||
- parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||
*/
|
||||
public init(_ configuration: String?) {
|
||||
@@ -102,9 +103,9 @@ public struct Into<T: NSManagedObject> {
|
||||
/**
|
||||
Initializes an `Into` clause with the specified entity type and configuration.
|
||||
Sample Usage:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into(MyPersonEntity.self, "Configuration1"))
|
||||
|
||||
```
|
||||
- parameter entity: the `NSManagedObject` type to be created
|
||||
- parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||
*/
|
||||
@@ -118,9 +119,9 @@ public struct Into<T: NSManagedObject> {
|
||||
/**
|
||||
Initializes an `Into` clause with the specified entity class and configuration.
|
||||
Sample Usage:
|
||||
|
||||
```
|
||||
let person = transaction.create(Into(MyPersonEntity.self, "Configuration1"))
|
||||
|
||||
```
|
||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||
- parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// NSManagedObject+Transaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2016 John Rommel Estropia
|
||||
// Copyright © 2016 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
|
||||
@@ -26,12 +26,11 @@
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - NSManagedObject
|
||||
|
||||
public extension NSManagedObject {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Returns this object's parent `UnsafeDataTransaction` instance if it was created from one. Returns `nil` if the parent transaction is either an `AsynchronousDataTransaction` or a `SynchronousDataTransaction`, or if the object is not managed by CoreStore.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SaveResult.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -31,7 +31,7 @@ import Foundation
|
||||
/**
|
||||
The `SaveResult` indicates the result of a `commit(...)` for a transaction.
|
||||
The `SaveResult` can be treated as a boolean:
|
||||
|
||||
```
|
||||
CoreStore.beginAsynchronous { transaction in
|
||||
// ...
|
||||
let result = transaction.commit()
|
||||
@@ -42,9 +42,9 @@ The `SaveResult` can be treated as a boolean:
|
||||
// failed
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
or as an `enum`, where the resulting associated object can also be inspected:
|
||||
|
||||
```
|
||||
CoreStore.beginAsynchronous { transaction in
|
||||
// ...
|
||||
let result = transaction.commit()
|
||||
@@ -59,8 +59,6 @@ or as an `enum`, where the resulting associated object can also be inspected:
|
||||
*/
|
||||
public enum SaveResult {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
`SaveResult.Success` indicates that the `commit()` for the transaction succeeded, either because the save succeeded or because there were no changes to save. The associated value `hasChanges` indicates if there were saved changes or not.
|
||||
*/
|
||||
@@ -103,6 +101,7 @@ extension SaveResult: BooleanType {
|
||||
public var boolValue: Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
case .Success: return true
|
||||
case .Failure: return false
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SynchronousDataTransaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -37,8 +37,6 @@ The `SynchronousDataTransaction` provides an interface for `NSManagedObject` cre
|
||||
*/
|
||||
public final class SynchronousDataTransaction: BaseDataTransaction {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `commit()` method was already called once.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// UnsafeDataTransaction.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
@@ -41,8 +41,6 @@ The `UnsafeDataTransaction` provides an interface for non-contiguous `NSManagedO
|
||||
*/
|
||||
public final class UnsafeDataTransaction: BaseDataTransaction {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Saves the transaction changes asynchronously. For a `UnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStore+Setup.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2015 John Rommel Estropia
|
||||
// Copyright © 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// DataStack.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -50,8 +50,6 @@ The `DataStack` encapsulates the data model for the Core Data stack. Each `DataS
|
||||
*/
|
||||
public final class DataStack {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes a `DataStack` from an `NSManagedObjectModel`.
|
||||
|
||||
@@ -367,11 +365,17 @@ public final class DataStack {
|
||||
self.configurationStoreMapping[configurationName] = persistentStore
|
||||
for entityDescription in (self.coordinator.managedObjectModel.entitiesForConfiguration(configurationName) ?? []) {
|
||||
|
||||
if self.entityConfigurationsMapping[entityDescription.managedObjectClassName] == nil {
|
||||
let managedObjectClassName = entityDescription.managedObjectClassName
|
||||
CoreStore.assert(
|
||||
NSClassFromString(managedObjectClassName) != nil,
|
||||
"The class \(typeName(managedObjectClassName)) for the entity \(typeName(entityDescription.name)) does not exist. Check if the subclass type and module name are properly configured."
|
||||
)
|
||||
|
||||
self.entityConfigurationsMapping[entityDescription.managedObjectClassName] = []
|
||||
if self.entityConfigurationsMapping[managedObjectClassName] == nil {
|
||||
|
||||
self.entityConfigurationsMapping[managedObjectClassName] = []
|
||||
}
|
||||
self.entityConfigurationsMapping[entityDescription.managedObjectClassName]?.insert(configurationName)
|
||||
self.entityConfigurationsMapping[managedObjectClassName]?.insert(configurationName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// PersistentStoreResult.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
@@ -32,7 +32,7 @@ import CoreData
|
||||
/**
|
||||
The `PersistentStoreResult` indicates the result of an asynchronous initialization of a persistent store.
|
||||
The `PersistentStoreResult` can be treated as a boolean:
|
||||
|
||||
```
|
||||
try! CoreStore.addSQLiteStore(completion: { (result: PersistentStoreResult) -> Void in
|
||||
if result {
|
||||
// succeeded
|
||||
@@ -41,9 +41,9 @@ The `PersistentStoreResult` can be treated as a boolean:
|
||||
// failed
|
||||
}
|
||||
})
|
||||
|
||||
```
|
||||
or as an `enum`, where the resulting associated object can also be inspected:
|
||||
|
||||
```
|
||||
try! CoreStore.addSQLiteStore(completion: { (result: PersistentStoreResult) -> Void in
|
||||
switch result {
|
||||
case .Success(let persistentStore):
|
||||
@@ -56,8 +56,6 @@ or as an `enum`, where the resulting associated object can also be inspected:
|
||||
*/
|
||||
public enum PersistentStoreResult {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
`PersistentStoreResult.Success` indicates that the persistent store process succeeded. The associated object for this `enum` value is the related `NSPersistentStore` instance.
|
||||
*/
|
||||
@@ -88,9 +86,7 @@ public enum PersistentStoreResult {
|
||||
|
||||
internal init(_ errorCode: CoreStoreErrorCode, userInfo: [NSObject: AnyObject]?) {
|
||||
|
||||
self.init(NSError(
|
||||
coreStoreErrorCode: errorCode,
|
||||
userInfo: userInfo))
|
||||
self.init(NSError(coreStoreErrorCode: errorCode, userInfo: userInfo))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +95,6 @@ public enum PersistentStoreResult {
|
||||
|
||||
extension PersistentStoreResult: BooleanType {
|
||||
|
||||
// MARK: Public
|
||||
|
||||
public var boolValue: Bool {
|
||||
|
||||
switch self {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/02.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/12.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/17.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/17.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/15.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/02.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/06.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/24.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/05.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/05.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/05.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/21.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/27.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/21.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/21.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/27.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/27.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/06.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/06/06.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/24.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/24.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/24.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// CoreStoreDemo
|
||||
//
|
||||
// Created by John Rommel Estropia on 2015/05/24.
|
||||
// Copyright (c) 2015 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2015 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// CoreStoreTests.swift
|
||||
// CoreStoreTests
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// TestEntity1.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// TestEntity1.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright (c) 2014 John Rommel Estropia
|
||||
// Copyright © 2014 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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 John Rommel Estropia
|
||||
Copyright © 2014 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
|
||||
|
||||
@@ -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)**
|
||||
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ class MyViewController: UIViewController {
|
||||
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(
|
||||
let progress: NSProgress? = try dataStack.addSQLiteStore(
|
||||
fileName: "MyStore.sqlite",
|
||||
configuration: "Config2",
|
||||
completion: { (result) -> Void in
|
||||
@@ -566,7 +566,7 @@ CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
From(MyPersonEntity),
|
||||
Where("name", isEqualTo: "Jane Smith")
|
||||
)
|
||||
jane.friends = NSSet(array: transactin.fetchExisting(peopleIDs)!)
|
||||
jane.friends = NSSet(array: transaction.fetchExisting(peopleIDs)!)
|
||||
// ...
|
||||
}
|
||||
```
|
||||
@@ -714,7 +714,7 @@ class func uniqueIDFromImportSource(source: ImportSource, inTransaction transact
|
||||
```
|
||||
For `ImportableUniqueObject`, the extraction and assignment of values should be implemented from the `updateFromImportSource(...)` method. The `didInsertFromImportSource(...)` by default calls `updateFromImportSource(...)`, but you can separate the implementation for inserts and updates if needed.
|
||||
|
||||
You can then call create/update an object by calling a transaction's `importUniqueObject(...)` method:
|
||||
You can then create/update an object by calling a transaction's `importUniqueObject(...)` method:
|
||||
```swift
|
||||
CoreStore.beginAsynchronous { (transaction) -> Void in
|
||||
let json: [String: AnyObject] = // ...
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user