mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-17 06:27:02 +01:00
WIP: CSListMonitor
This commit is contained in:
@@ -74,6 +74,18 @@
|
||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
|
||||
82BA18DF1C4BBE2600A0916E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82BA18DE1C4BBE2600A0916E /* Foundation.framework */; };
|
||||
82BA18E11C4BBE2C00A0916E /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82BA18E01C4BBE2C00A0916E /* CoreData.framework */; };
|
||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */; };
|
||||
B501FDDE1CA8D05000BE22EF /* CSSectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */; };
|
||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */; };
|
||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */; };
|
||||
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */; };
|
||||
B501FDE31CA8D1F500BE22EF /* CSListMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */; };
|
||||
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */; };
|
||||
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */; };
|
||||
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE61CA8D20500BE22EF /* CSListObserver.swift */; };
|
||||
B501FDE81CA8D20500BE22EF /* CSListObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE61CA8D20500BE22EF /* CSListObserver.swift */; };
|
||||
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE61CA8D20500BE22EF /* CSListObserver.swift */; };
|
||||
B501FDEA1CA8D20500BE22EF /* CSListObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B501FDE61CA8D20500BE22EF /* CSListObserver.swift */; };
|
||||
B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||
B50392FB1C479640009900CA /* NSManagedObject+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */; };
|
||||
@@ -539,6 +551,9 @@
|
||||
82BA18921C4BBCBA00A0916E /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
82BA18DE1C4BBE2600A0916E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.1.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
82BA18E01C4BBE2C00A0916E /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.1.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSectionBy.swift; sourceTree = "<group>"; };
|
||||
B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListMonitor.swift; sourceTree = "<group>"; };
|
||||
B501FDE61CA8D20500BE22EF /* CSListObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSListObserver.swift; sourceTree = "<group>"; };
|
||||
B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Transaction.swift"; sourceTree = "<group>"; };
|
||||
B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Setup.swift"; sourceTree = "<group>"; };
|
||||
B519E4571C4CD2CA00E7B469 /* GCDKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GCDKit.framework; path = "../../Library/Developer/Xcode/DerivedData/Build/Products/Debug-iphoneos/GCDKit.framework"; sourceTree = "<group>"; };
|
||||
@@ -841,6 +856,16 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B501FDDB1CA8D03600BE22EF /* Observing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B501FDDC1CA8D05000BE22EF /* CSSectionBy.swift */,
|
||||
B501FDE11CA8D1F500BE22EF /* CSListMonitor.swift */,
|
||||
B501FDE61CA8D20500BE22EF /* CSListObserver.swift */,
|
||||
);
|
||||
name = Observing;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B546F9611C9A13F400D5AC55 /* Setup */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -910,6 +935,7 @@
|
||||
B546F9611C9A13F400D5AC55 /* Setup */,
|
||||
B5519A5D1CA20093002BEF78 /* Saving and Processing */,
|
||||
B5E2222F1CA5339200BA2E95 /* Fetching and Querying */,
|
||||
B501FDDB1CA8D03600BE22EF /* Observing */,
|
||||
B5E222211CA4DE5700BA2E95 /* Internal */,
|
||||
);
|
||||
path = ObjectiveC;
|
||||
@@ -1449,6 +1475,8 @@
|
||||
B5F1DA8D1B9AA97D007C5CBB /* ImportableObject.swift in Sources */,
|
||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */,
|
||||
B5FE4DAC1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */,
|
||||
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */,
|
||||
@@ -1480,6 +1508,7 @@
|
||||
B5E84F311AFF849C0064E85B /* WeakObject.swift in Sources */,
|
||||
B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */,
|
||||
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -1561,6 +1590,8 @@
|
||||
82BA18B01C4BBD3100A0916E /* NSManagedObject+Transaction.swift in Sources */,
|
||||
82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||
82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5FE4DA31C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||
B5ECDC131CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
82BA18C91C4BBD5900A0916E /* MigrationType.swift in Sources */,
|
||||
@@ -1592,6 +1623,7 @@
|
||||
82BA18AF1C4BBD3100A0916E /* CoreStore+Transaction.swift in Sources */,
|
||||
82BA18CB1C4BBD6400A0916E /* NSManagedObject+Convenience.swift in Sources */,
|
||||
82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -1774,6 +1806,8 @@
|
||||
B56321B21BD6521C006C9394 /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||
B5FE4DA41C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||
B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */,
|
||||
B501FDEA1CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5ECDC141CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */,
|
||||
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */,
|
||||
@@ -1805,6 +1839,7 @@
|
||||
B56321AC1BD6521C006C9394 /* Functions.swift in Sources */,
|
||||
B56321851BD65216006C9394 /* CoreStore+Logging.swift in Sources */,
|
||||
B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -1836,6 +1871,7 @@
|
||||
B5ECDC431CA836F800C7F112 /* SetupResult.swift in Sources */,
|
||||
B59983491CA54BC100E1A417 /* CSBaseDataTransaction.swift in Sources */,
|
||||
B5E2222B1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||
B501FDE81CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B5D9E2F01CA2C317007A9D52 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B5D9E3461CA2C6C4007A9D52 /* GCDQueue.swift in Sources */,
|
||||
B5D9E2F11CA2C317007A9D52 /* ImportableUniqueObject.swift in Sources */,
|
||||
@@ -1881,6 +1917,7 @@
|
||||
B5D9E30F1CA2C317007A9D52 /* DataStack.swift in Sources */,
|
||||
B5D9E3101CA2C317007A9D52 /* Functions.swift in Sources */,
|
||||
B5D9E3431CA2C6C4007A9D52 /* GCDBlock.swift in Sources */,
|
||||
B501FDE31CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5D9E3111CA2C317007A9D52 /* ListMonitor.swift in Sources */,
|
||||
B5ECDC2A1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||
B5E222241CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||
@@ -1909,6 +1946,7 @@
|
||||
B5D9E31E1CA2C317007A9D52 /* WeakObject.swift in Sources */,
|
||||
B5ECDC411CA836C800C7F112 /* CSSQliteStore.swift in Sources */,
|
||||
B5D7A5B21CA3B738005C752B /* SQLiteStore.swift in Sources */,
|
||||
B501FDDE1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B5D9E3471CA2C6C4007A9D52 /* GCDSemaphore.swift in Sources */,
|
||||
B5D9E31F1CA2C317007A9D52 /* GroupBy.swift in Sources */,
|
||||
B5D9E3201CA2C317007A9D52 /* DataStack+Observing.swift in Sources */,
|
||||
|
||||
@@ -37,7 +37,7 @@ public extension NSFetchedResultsController {
|
||||
@nonobjc
|
||||
public static func createForStack<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController {
|
||||
|
||||
return CoreStoreFetchedResultsController<T>(
|
||||
return CoreStoreFetchedResultsController(
|
||||
context: dataStack.mainContext,
|
||||
fetchRequest: fetchRequest,
|
||||
from: from,
|
||||
@@ -52,7 +52,7 @@ public extension NSFetchedResultsController {
|
||||
@nonobjc
|
||||
internal static func createFromContext<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) -> NSFetchedResultsController {
|
||||
|
||||
return CoreStoreFetchedResultsController<T>(
|
||||
return CoreStoreFetchedResultsController(
|
||||
context: context,
|
||||
fetchRequest: fetchRequest,
|
||||
from: from,
|
||||
@@ -60,39 +60,4 @@ public extension NSFetchedResultsController {
|
||||
fetchClauses: fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated=1.5.2, message="Use NSFetchedResultsController.createForStack(_:fetchRequest:from:sectionBy:fetchClauses:) to create NSFetchedResultsControllers directly")
|
||||
@nonobjc
|
||||
public convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
|
||||
let context = dataStack.mainContext
|
||||
from?.applyToFetchRequest(fetchRequest, context: context, applyAffectedStores: false)
|
||||
for clause in fetchClauses {
|
||||
|
||||
clause.applyToFetchRequest(fetchRequest)
|
||||
}
|
||||
|
||||
if let from = from {
|
||||
|
||||
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.")
|
||||
}
|
||||
from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
|
||||
self.init(
|
||||
fetchRequest: fetchRequest,
|
||||
managedObjectContext: context,
|
||||
sectionNameKeyPath: sectionBy?.sectionKeyPath,
|
||||
cacheName: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import CoreData
|
||||
let person = transaction.fetchOne(From<MyPersonEntity>("Configuration1"))
|
||||
```
|
||||
*/
|
||||
public struct From<T: NSManagedObject>: Hashable {
|
||||
public struct From<T: NSManagedObject> {
|
||||
|
||||
/**
|
||||
Initializes a `From` clause.
|
||||
@@ -299,20 +299,8 @@ public struct From<T: NSManagedObject>: Hashable {
|
||||
}
|
||||
|
||||
|
||||
// MARK: Hashable
|
||||
|
||||
public var hashValue: Int {
|
||||
|
||||
return ObjectIdentifier(self.entityClass).hashValue
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let entityClass: AnyClass
|
||||
|
||||
internal let findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?
|
||||
|
||||
internal func applyToFetchRequest(fetchRequest: NSFetchRequest, context: NSManagedObjectContext, applyAffectedStores: Bool = true) {
|
||||
|
||||
fetchRequest.entity = context.entityDescriptionForEntityClass(self.entityClass)
|
||||
@@ -329,15 +317,20 @@ public struct From<T: NSManagedObject>: Hashable {
|
||||
return stores?.isEmpty == false
|
||||
}
|
||||
|
||||
internal init(entityClass: AnyClass, findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?) {
|
||||
internal func upcast() -> From<NSManagedObject> {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.findPersistentStores = findPersistentStores
|
||||
return From<NSManagedObject>(
|
||||
entityClass: self.entityClass,
|
||||
findPersistentStores: self.findPersistentStores
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let entityClass: AnyClass
|
||||
private let findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?
|
||||
|
||||
private init(entityClass: AnyClass) {
|
||||
|
||||
self.init(
|
||||
@@ -393,13 +386,10 @@ public struct From<T: NSManagedObject>: Hashable {
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - From: Equatable
|
||||
|
||||
@warn_unused_result
|
||||
public func == <T: NSManagedObject, U: NSManagedObject>(lhs: From<T>, rhs: From<U>) -> Bool {
|
||||
|
||||
return lhs.entityClass == rhs.entityClass
|
||||
private init(entityClass: AnyClass, findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?) {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.findPersistentStores = findPersistentStores
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,11 @@ import CoreData
|
||||
// MARK: - CoreStoreFetchedResultsController
|
||||
|
||||
@available(OSX, unavailable)
|
||||
internal final class CoreStoreFetchedResultsController<T: NSManagedObject>: NSFetchedResultsController {
|
||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal convenience init<T>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
internal convenience init<T: NSManagedObject>(dataStack: DataStack, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -45,7 +45,7 @@ internal final class CoreStoreFetchedResultsController<T: NSManagedObject>: NSFe
|
||||
)
|
||||
}
|
||||
|
||||
internal init<T>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
internal init<T: NSManagedObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest, from: From<T>? = nil, sectionBy: SectionBy? = nil, fetchClauses: [FetchClause]) {
|
||||
|
||||
from?.applyToFetchRequest(fetchRequest, context: context, applyAffectedStores: false)
|
||||
for clause in fetchClauses {
|
||||
|
||||
@@ -106,33 +106,13 @@ public final class CSFrom: NSObject, CoreStoreBridge {
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSObject
|
||||
|
||||
public override var hash: Int {
|
||||
|
||||
return self.swift.hashValue
|
||||
}
|
||||
|
||||
public override func isEqual(object: AnyObject?) -> Bool {
|
||||
|
||||
guard let object = object as? CSFrom else {
|
||||
|
||||
return false
|
||||
}
|
||||
return self.swift == object.swift
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreBridge
|
||||
|
||||
internal let swift: From<NSManagedObject>
|
||||
|
||||
internal init<T: NSManagedObject>(_ swiftObject: From<T>) {
|
||||
|
||||
self.swift = From<NSManagedObject>(
|
||||
entityClass: swiftObject.entityClass,
|
||||
findPersistentStores: swiftObject.findPersistentStores
|
||||
)
|
||||
self.swift = swiftObject.upcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,11 +88,7 @@ public final class CSInto: NSObject, CoreStoreBridge {
|
||||
|
||||
public required init<T: NSManagedObject>(_ swiftObject: Into<T>) {
|
||||
|
||||
self.swift = Into<NSManagedObject>(
|
||||
entityClass: swiftObject.entityClass,
|
||||
configuration: swiftObject.configuration,
|
||||
inferStoreIfPossible: swiftObject.inferStoreIfPossible
|
||||
)
|
||||
self.swift = swiftObject.upcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
560
Sources/ObjectiveC/CSListMonitor.swift
Normal file
560
Sources/ObjectiveC/CSListMonitor.swift
Normal file
@@ -0,0 +1,560 @@
|
||||
//
|
||||
// CSListMonitor.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: - CSListMonitor
|
||||
|
||||
/**
|
||||
The `CSListMonitor` serves as the Objective-C bridging type for `ListMonitor<T>`.
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@objc
|
||||
public final class CSListMonitor: NSObject, CoreStoreBridge {
|
||||
|
||||
// MARK: Public (Accessors)
|
||||
|
||||
/**
|
||||
Returns the object at the given index within the first section. This subscript indexer is typically used for `CSListMonitor`s created without section groupings.
|
||||
|
||||
- parameter index: the index of the object. Using an index above the valid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified index
|
||||
*/
|
||||
@objc
|
||||
public subscript(index: Int) -> NSManagedObject {
|
||||
|
||||
return self.swift[index]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given index, or `nil` if out of bounds. This indexer is typically used for `CSListMonitor`s created without section groupings.
|
||||
|
||||
- parameter index: the index for the object. Using an index above the valid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified index, or `nil` if out of bounds
|
||||
*/
|
||||
@objc
|
||||
public func objectAtSafeIndex(index: Int) -> NSManagedObject? {
|
||||
|
||||
return self.swift[safeIndex: index]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given `sectionIndex` and `itemIndex`. This indexer is typically used for `CSListMonitor`s created as sectioned lists.
|
||||
|
||||
- parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will raise an exception.
|
||||
- parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified section and item index
|
||||
*/
|
||||
@objc
|
||||
public func objectAtSectionIndex(sectionIndex: Int, itemIndex: Int) -> NSManagedObject {
|
||||
|
||||
return self.swift[sectionIndex, itemIndex]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given section and item index, or `nil` if out of bounds. This indexer is typically used for `CSListMonitor`s created as sectioned lists.
|
||||
|
||||
- parameter sectionIndex: the section index for the object. Using a `sectionIndex` with an invalid range will return `nil`.
|
||||
- parameter itemIndex: the index for the object within the section. Using an `itemIndex` with an invalid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified section and item index, or `nil` if out of bounds
|
||||
*/
|
||||
@objc
|
||||
public func objectAtSafeSectionIndex(sectionIndex: Int, safeItemIndex itemIndex: Int) -> NSManagedObject? {
|
||||
|
||||
return self.swift[safeSectionIndex: sectionIndex, safeItemIndex: itemIndex]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given `NSIndexPath`. This subscript indexer is typically used for `CSListMonitor`s created as sectioned lists.
|
||||
|
||||
- parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will raise an exception.
|
||||
- returns: the `NSManagedObject` at the specified index path
|
||||
*/
|
||||
@objc
|
||||
public func objectAtIndexPath(indexPath: NSIndexPath) -> NSManagedObject {
|
||||
|
||||
return self.swift[indexPath]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object at the given `NSIndexPath`, or `nil` if out of bounds. This subscript indexer is typically used for `CSListMonitor`s created as sectioned lists.
|
||||
|
||||
- parameter indexPath: the `NSIndexPath` for the object. Using an `indexPath` with an invalid range will return `nil`.
|
||||
- returns: the `NSManagedObject` at the specified index path, or `nil` if out of bounds
|
||||
*/
|
||||
@objc
|
||||
public func objectAtSafeIndexPath(indexPath: NSIndexPath) -> NSManagedObject? {
|
||||
|
||||
return self.swift[safeIndexPath: indexPath]
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if the `CSListMonitor` has at least one object in any section.
|
||||
|
||||
- returns: `YES` if at least one object in any section exists, `NO` otherwise
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func hasObjects() -> Bool {
|
||||
|
||||
return self.swift.hasObjects()
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if the `CSListMonitor` has at least one object the specified section.
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will return `NO`.
|
||||
- returns: `YES` if at least one object in the specified section exists, `NO` otherwise
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func hasObjectsInSection(section: Int) -> Bool {
|
||||
|
||||
return self.swift.hasObjectsInSection(section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all objects in all sections
|
||||
|
||||
- returns: all objects in all sections
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func objectsInAllSections() -> [NSManagedObject] {
|
||||
|
||||
return self.swift.objectsInAllSections()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all objects in the specified section
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will raise an exception.
|
||||
- returns: all objects in the specified section
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func objectsInSection(section: Int) -> [NSManagedObject] {
|
||||
|
||||
return self.swift.objectsInSection(section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns all objects in the specified section, or `nil` if out of bounds.
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will return `nil`.
|
||||
- returns: all objects in the specified section, or `nil` if out of bounds
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func objectsInSafeSection(safeSectionIndex section: Int) -> [NSManagedObject]? {
|
||||
|
||||
return self.swift.objectsInSection(safeSectionIndex: section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the number of sections
|
||||
|
||||
- returns: the number of sections
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func numberOfSections() -> Int {
|
||||
|
||||
return self.swift.numberOfSections()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the number of objects in all sections
|
||||
|
||||
- returns: the number of objects in all sections
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func numberOfObjects() -> Int {
|
||||
|
||||
return self.swift.numberOfObjects()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the number of objects in the specified section
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will raise an exception.
|
||||
- returns: the number of objects in the specified section
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func numberOfObjectsInSection(section: Int) -> Int {
|
||||
|
||||
return self.swift.numberOfObjectsInSection(section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the number of objects in the specified section, or `nil` if out of bounds.
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will return `nil`.
|
||||
- returns: the number of objects in the specified section, or `nil` if out of bounds
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func numberOfObjectsInSafeSection(safeSectionIndex section: Int) -> NSNumber? {
|
||||
|
||||
return self.swift.numberOfObjectsInSection(safeSectionIndex: section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the `NSFetchedResultsSectionInfo` for the specified section
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will raise an exception.
|
||||
- returns: the `NSFetchedResultsSectionInfo` for the specified section
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func sectionInfoAtIndex(section: Int) -> NSFetchedResultsSectionInfo {
|
||||
|
||||
return self.swift.sectionInfoAtIndex(section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the `NSFetchedResultsSectionInfo` for the specified section, or `nil` if out of bounds.
|
||||
|
||||
- parameter section: the section index. Using an index outside the valid range will return `nil`.
|
||||
- returns: the `NSFetchedResultsSectionInfo` for the specified section, or `nil` if the section index is out of bounds.
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func sectionInfoAtSafeSectionIndex(safeSectionIndex section: Int) -> NSFetchedResultsSectionInfo? {
|
||||
|
||||
return self.swift.sectionInfoAtIndex(safeSectionIndex: section)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the `NSFetchedResultsSectionInfo`s for all sections
|
||||
|
||||
- returns: the `NSFetchedResultsSectionInfo`s for all sections
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func sections() -> [NSFetchedResultsSectionInfo] {
|
||||
|
||||
return self.swift.sections()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the target section for a specified "Section Index" title and index.
|
||||
|
||||
- parameter title: the title of the Section Index
|
||||
- parameter index: the index of the Section Index
|
||||
- returns: the target section for the specified "Section Index" title and index.
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func targetSectionForSectionIndexTitle(title title: String, index: Int) -> Int {
|
||||
|
||||
return self.swift.targetSectionForSectionIndex(title: title, index: index)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the section index titles for all sections
|
||||
|
||||
- returns: the section index titles for all sections
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func sectionIndexTitles() -> [String] {
|
||||
|
||||
return self.swift.sectionIndexTitles()
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the index of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found.
|
||||
|
||||
- parameter object: the `NSManagedObject` to search the index of
|
||||
- returns: the index of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found.
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func indexOf(object: NSManagedObject) -> NSNumber? {
|
||||
|
||||
return self.swift.indexOf(object)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the `NSIndexPath` of the `NSManagedObject` if it exists in the `CSListMonitor`'s fetched objects, or `nil` if not found.
|
||||
|
||||
- parameter object: the `NSManagedObject` to search the index of
|
||||
- returns: the `NSIndexPath` of the `NSManagedObject` if it exists in the `ListMonitor`'s fetched objects, or `nil` if not found.
|
||||
*/
|
||||
@objc
|
||||
@warn_unused_result
|
||||
public func indexPathOf(object: NSManagedObject) -> NSIndexPath? {
|
||||
|
||||
return self.swift.indexPathOf(object)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Public (Observers)
|
||||
|
||||
/**
|
||||
Registers a `CSListObserver` to be notified when changes to the receiver's list occur.
|
||||
|
||||
To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers.
|
||||
|
||||
For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread.
|
||||
|
||||
Calling `-addListObserver:` multiple times on the same observer is safe, as `CSListMonitor` unregisters previous notifications to the observer before re-registering them.
|
||||
|
||||
- parameter observer: a `CSListObserver` to send change notifications to
|
||||
*/
|
||||
@objc
|
||||
public func addListObserver(observer: CSListObserver) {
|
||||
|
||||
let swift = self.swift
|
||||
swift.unregisterObserver(observer)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
willChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillChange?(monitor.objc)
|
||||
},
|
||||
didChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidChange?(monitor.objc)
|
||||
},
|
||||
willRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillRefetch?(monitor.objc)
|
||||
},
|
||||
didRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidRefetch?(monitor.objc)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Registers a `CSListObjectObserver` to be notified when changes to the receiver's list occur.
|
||||
|
||||
To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers.
|
||||
|
||||
For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread.
|
||||
|
||||
Calling `-addListObjectObserver:` multiple times on the same observer is safe, as `ListMonitor` unregisters previous notifications to the observer before re-registering them.
|
||||
|
||||
- parameter observer: a `CSListObjectObserver` to send change notifications to
|
||||
*/
|
||||
public func addListObjectObserver(observer: CSListObjectObserver) {
|
||||
|
||||
let swift = self.swift
|
||||
swift.unregisterObserver(observer)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
willChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillChange?(monitor.objc)
|
||||
},
|
||||
didChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidChange?(monitor.objc)
|
||||
},
|
||||
willRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillRefetch?(monitor.objc)
|
||||
},
|
||||
didRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidRefetch?(monitor.objc)
|
||||
}
|
||||
)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
didInsertObject: { (observer, monitor, object, toIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didInsertObject: object, toIndexPath: toIndexPath)
|
||||
},
|
||||
didDeleteObject: { (observer, monitor, object, fromIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didDeleteObject: object, fromIndexPath: fromIndexPath)
|
||||
},
|
||||
didUpdateObject: { (observer, monitor, object, atIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didUpdateObject: object, atIndexPath: atIndexPath)
|
||||
},
|
||||
didMoveObject: { (observer, monitor, object, fromIndexPath, toIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didMoveObject: object, fromIndexPath: fromIndexPath, toIndexPath: toIndexPath)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Registers a `CSListSectionObserver` to be notified when changes to the receiver's list occur.
|
||||
|
||||
To prevent retain-cycles, `CSListMonitor` only keeps `weak` references to its observers.
|
||||
|
||||
For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread.
|
||||
|
||||
Calling `-addListSectionObserver:` multiple times on the same observer is safe, as `ListMonitor` unregisters previous notifications to the observer before re-registering them.
|
||||
|
||||
- parameter observer: a `CSListSectionObserver` to send change notifications to
|
||||
*/
|
||||
@objc
|
||||
public func addListSectionObserver(observer: CSListSectionObserver) {
|
||||
|
||||
let swift = self.swift
|
||||
swift.unregisterObserver(observer)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
willChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillChange?(monitor.objc)
|
||||
},
|
||||
didChange: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidChange?(monitor.objc)
|
||||
},
|
||||
willRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorWillRefetch?(monitor.objc)
|
||||
},
|
||||
didRefetch: { (observer, monitor) in
|
||||
|
||||
observer.listMonitorDidRefetch?(monitor.objc)
|
||||
}
|
||||
)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
didInsertObject: { (observer, monitor, object, toIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didInsertObject: object, toIndexPath: toIndexPath)
|
||||
},
|
||||
didDeleteObject: { (observer, monitor, object, fromIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didDeleteObject: object, fromIndexPath: fromIndexPath)
|
||||
},
|
||||
didUpdateObject: { (observer, monitor, object, atIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didUpdateObject: object, atIndexPath: atIndexPath)
|
||||
},
|
||||
didMoveObject: { (observer, monitor, object, fromIndexPath, toIndexPath) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didMoveObject: object, fromIndexPath: fromIndexPath, toIndexPath: toIndexPath)
|
||||
}
|
||||
)
|
||||
swift.registerObserver(
|
||||
observer,
|
||||
didInsertSection: { (observer, monitor, sectionInfo, toIndex) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didInsertSection: sectionInfo, toSectionIndex: toIndex)
|
||||
},
|
||||
didDeleteSection: { (observer, monitor, sectionInfo, fromIndex) in
|
||||
|
||||
observer.listMonitor?(monitor.objc, didDeleteSection: sectionInfo, fromSectionIndex: fromIndex)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Unregisters a `CSListObserver` from receiving notifications for changes to the receiver's list.
|
||||
|
||||
For thread safety, this method needs to be called from the main thread. An assertion failure will occur (on debug builds only) if called from any thread other than the main thread.
|
||||
|
||||
- parameter observer: a `CSListObserver` to unregister notifications to
|
||||
*/
|
||||
@objc
|
||||
public func removeObserver(observer: CSListObserver) {
|
||||
|
||||
self.swift.unregisterObserver(observer)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Public (Refetching)
|
||||
|
||||
/**
|
||||
Returns `YES` if a call to `-refetch:` was made to the `CSListMonitor` and is currently waiting for the fetching to complete. Returns `NO` otherwise.
|
||||
*/
|
||||
@objc
|
||||
public var isPendingRefetch: Bool {
|
||||
|
||||
return self.swift.isPendingRefetch
|
||||
}
|
||||
|
||||
/**
|
||||
Asks the `CSListMonitor` to refetch its objects using the specified series of `CSFetchClause`s. Note that this method does not execute the fetch immediately; the actual fetching will happen after the `NSFetchedResultsController`'s last `controllerDidChangeContent(_:)` notification completes.
|
||||
|
||||
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
|
||||
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Note that only specified clauses will be changed; unspecified clauses will use previous values.
|
||||
*/
|
||||
public func refetch(fetchClauses: [CSFetchClause]) {
|
||||
|
||||
self.swift.refetch { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSObject
|
||||
|
||||
public override var hash: Int {
|
||||
|
||||
return self.swift.hashValue
|
||||
}
|
||||
|
||||
public override func isEqual(object: AnyObject?) -> Bool {
|
||||
|
||||
guard let object = object as? CSListMonitor else {
|
||||
|
||||
return false
|
||||
}
|
||||
return self.swift == object.swift
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreBridge
|
||||
|
||||
internal let swift: ListMonitor<NSManagedObject>
|
||||
|
||||
public required init<T: NSManagedObject>(_ swiftObject: ListMonitor<T>) {
|
||||
|
||||
self.swift = swiftObject.upcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ListMonitor
|
||||
|
||||
extension ListMonitor: CoreStoreBridgeable {
|
||||
|
||||
// MARK: CoreStoreBridgeable
|
||||
|
||||
internal var objc: CSListMonitor {
|
||||
|
||||
return CSListMonitor(self)
|
||||
}
|
||||
}
|
||||
172
Sources/ObjectiveC/CSListObserver.swift
Normal file
172
Sources/ObjectiveC/CSListObserver.swift
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// CSListObserver.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: - CSListObserver
|
||||
|
||||
/**
|
||||
Implement the `CSListObserver` protocol to observe changes to a list of `NSManagedObject`s. `CSListObserver`s may register themselves to a `CSListMonitor`'s `-addListObserver:` method:
|
||||
```
|
||||
CSListMonitor *monitor = [CSCoreStore
|
||||
monitorListFrom:[CSFrom entityClass:[MyPersonEntity class]]
|
||||
fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]];
|
||||
[monitor addListObserver:self];
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@objc
|
||||
public protocol CSListObserver: class, AnyObject {
|
||||
|
||||
/**
|
||||
Handles processing just before a change to the observed list occurs
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitorWillChange(monitor: CSListMonitor)
|
||||
|
||||
/**
|
||||
Handles processing right after a change to the observed list occurs
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the object being observed
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitorDidChange(monitor: CSListMonitor)
|
||||
|
||||
/**
|
||||
This method is broadcast from within the `CSListMonitor`'s `-refetchWithFetchClauses:` method to let observers prepare for the internal `NSFetchedResultsController`'s pending change to its predicate, sort descriptors, etc. Note that the actual refetch will happen after the `NSFetchedResultsController`'s last `-controllerDidChangeContent:` notification completes.
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the object being observed
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitorWillRefetch(monitor: CSListMonitor)
|
||||
|
||||
/**
|
||||
After the `CSListMonitor`'s `-refetchWithFetchClauses:` method is called, this method is broadcast after the `NSFetchedResultsController`'s last `-controllerDidChangeContent:` notification completes.
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the object being observed
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitorDidRefetch(monitor: CSListMonitor)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ListObjectObserver
|
||||
|
||||
/**
|
||||
Implement the `CSListObjectObserver` protocol to observe detailed changes to a list's object. `CSListObjectObserver`s may register themselves to a `CSListMonitor`'s `-addListObjectObserver(_:)` method:
|
||||
```
|
||||
CSListMonitor *monitor = [CSCoreStore
|
||||
monitorListFrom:[CSFrom entityClass:[MyPersonEntity class]]
|
||||
fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]];
|
||||
[monitor addListObjectObserver:self];
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@objc
|
||||
public protocol CSListObjectObserver: CSListObserver {
|
||||
|
||||
/**
|
||||
Notifies that an object was inserted to the specified `NSIndexPath` in the list
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter object: the entity type for the inserted object
|
||||
- parameter indexPath: the new `NSIndexPath` for the inserted object
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didInsertObject object: NSManagedObject, toIndexPath indexPath: NSIndexPath)
|
||||
|
||||
/**
|
||||
Notifies that an object was deleted from the specified `NSIndexPath` in the list
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter object: the entity type for the deleted object
|
||||
- parameter indexPath: the `NSIndexPath` for the deleted object
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didDeleteObject object: NSManagedObject, fromIndexPath indexPath: NSIndexPath)
|
||||
|
||||
/**
|
||||
Notifies that an object at the specified `NSIndexPath` was updated
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter object: the entity type for the updated object
|
||||
- parameter indexPath: the `NSIndexPath` for the updated object
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didUpdateObject object: NSManagedObject, atIndexPath indexPath: NSIndexPath)
|
||||
|
||||
/**
|
||||
Notifies that an object's index changed
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter object: the entity type for the moved object
|
||||
- parameter fromIndexPath: the previous `NSIndexPath` for the moved object
|
||||
- parameter toIndexPath: the new `NSIndexPath` for the moved object
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didMoveObject object: NSManagedObject, fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - CSListSectionObserver
|
||||
|
||||
/**
|
||||
Implement the `CSListSectionObserver` protocol to observe changes to a list's section info. `CSListSectionObserver`s may register themselves to a `CSListMonitor`'s `-addListSectionObserver:` method:
|
||||
```
|
||||
CSListMonitor *monitor = [CSCoreStore
|
||||
monitorSectionedListFrom:[CSFrom entityClass:[MyPersonEntity class]]
|
||||
sectionBy:[CSSectionBy keyPath:@"age"]
|
||||
fetchClauses:@[[CSOrderBy sortDescriptor:[CSSortKey withKeyPath:@"lastName" ascending:YES]]]];
|
||||
[monitor addListSectionObserver:self];
|
||||
```
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@objc
|
||||
public protocol CSListSectionObserver: CSListObjectObserver {
|
||||
|
||||
/**
|
||||
Notifies that a section was inserted at the specified index
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the inserted section
|
||||
- parameter sectionIndex: the new section index for the new section
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int)
|
||||
|
||||
/**
|
||||
Notifies that a section was inserted at the specified index
|
||||
|
||||
- parameter monitor: the `CSListMonitor` monitoring the list being observed
|
||||
- parameter sectionInfo: the `NSFetchedResultsSectionInfo` for the deleted section
|
||||
- parameter sectionIndex: the previous section index for the deleted section
|
||||
*/
|
||||
@objc
|
||||
optional func listMonitor(monitor: CSListMonitor, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int)
|
||||
}
|
||||
@@ -27,6 +27,29 @@ import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - CSSortKey
|
||||
|
||||
/**
|
||||
The `CSSortKey` is a syntax-sugar class for `NSSortDescriptor` meant to be used with `CSOrderBy`.
|
||||
*/
|
||||
@objc
|
||||
public final class CSSortKey: NSSortDescriptor {
|
||||
|
||||
/**
|
||||
Initializes a `CSSortKey` with a the specified key path and sort order
|
||||
|
||||
- parameter keyPath: the property key to use when performing a comparison
|
||||
- parameter ascending: `YES` if the receiver specifies sorting in ascending order, otherwise `NO`
|
||||
- returns: a `CSSortKey` with a the specified key path and sort order
|
||||
*/
|
||||
@objc
|
||||
public static func withKeyPath(keyPath: KeyPath, ascending: Bool) -> CSSortKey {
|
||||
|
||||
return self.init(key: keyPath, ascending: ascending)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - CSOrderBy
|
||||
|
||||
/**
|
||||
|
||||
84
Sources/ObjectiveC/CSSectionBy.swift
Normal file
84
Sources/ObjectiveC/CSSectionBy.swift
Normal file
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// CSSectionBy.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: - CSSectionBy
|
||||
|
||||
/**
|
||||
The `CSSectionBy` serves as the Objective-C bridging type for `SectionBy`.
|
||||
*/
|
||||
@available(OSX, unavailable)
|
||||
@objc
|
||||
public final class CSSectionBy: NSObject, CoreStoreBridge {
|
||||
|
||||
/**
|
||||
Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
|
||||
- parameter sectionKeyPath: the key path to use to group the objects into sections
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(sectionKeyPath: KeyPath) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section name
|
||||
|
||||
- parameter sectionKeyPath: the key path to use to group the objects into sections
|
||||
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section name
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(sectionKeyPath: KeyPath, sectionIndexTransformer: (sectionName: String?) -> String?) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath, sectionIndexTransformer))
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreBridge
|
||||
|
||||
internal let swift: SectionBy
|
||||
|
||||
internal init(_ swiftObject: SectionBy) {
|
||||
|
||||
self.swift = swiftObject
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - SectionBy
|
||||
|
||||
extension SectionBy: CoreStoreBridgeable {
|
||||
|
||||
// MARK: CoreStoreBridgeable
|
||||
|
||||
internal typealias ObjCType = CSSectionBy
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -183,7 +183,7 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
fetchRequest.includesPendingChanges = false
|
||||
fetchRequest.shouldRefreshRefetchedObjects = true
|
||||
|
||||
let fetchedResultsController = CoreStoreFetchedResultsController<T>(
|
||||
let fetchedResultsController = CoreStoreFetchedResultsController(
|
||||
context: context,
|
||||
fetchRequest: fetchRequest,
|
||||
fetchClauses: [Where("SELF", isEqualTo: object.objectID)]
|
||||
@@ -209,7 +209,7 @@ public final class ObjectMonitor<T: NSManagedObject> {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let fetchedResultsController: CoreStoreFetchedResultsController<T>
|
||||
private let fetchedResultsController: CoreStoreFetchedResultsController
|
||||
private let fetchedResultsControllerDelegate: FetchedResultsControllerDelegate
|
||||
private var lastCommittedAttributes = [String: NSObject]()
|
||||
|
||||
|
||||
@@ -142,7 +142,19 @@ public struct Into<T: NSManagedObject>: Hashable {
|
||||
internal let configuration: String?
|
||||
internal let inferStoreIfPossible: Bool
|
||||
|
||||
internal init(entityClass: AnyClass, configuration: String?, inferStoreIfPossible: Bool) {
|
||||
internal func upcast() -> Into<NSManagedObject> {
|
||||
|
||||
return Into<NSManagedObject>(
|
||||
entityClass: self.entityClass,
|
||||
configuration: self.configuration,
|
||||
inferStoreIfPossible: self.inferStoreIfPossible
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private init(entityClass: AnyClass, configuration: String?, inferStoreIfPossible: Bool) {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.configuration = configuration
|
||||
|
||||
Reference in New Issue
Block a user