mirror of
https://github.com/modo-studio/SugarRecord.git
synced 2024-09-11 14:36:41 +03:00
[observable] Implement Observable feature for Storage
This commit is contained in:
parent
16a81a4554
commit
74b4f98c2a
@ -47,16 +47,6 @@
|
||||
2310154E1CDCCA42004486FA /* CoreDataObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310154C1CDCCA42004486FA /* CoreDataObservable.swift */; };
|
||||
2310154F1CDCCA42004486FA /* CoreDataObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310154C1CDCCA42004486FA /* CoreDataObservable.swift */; };
|
||||
231015501CDCCA42004486FA /* CoreDataObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310154C1CDCCA42004486FA /* CoreDataObservable.swift */; };
|
||||
231015511CDCCA42004486FA /* CoreDataObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310154C1CDCCA42004486FA /* CoreDataObservable.swift */; };
|
||||
231015531CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015541CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015551CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015561CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015571CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015581CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
231015591CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
2310155A1CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
2310155B1CDCCE9F004486FA /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 231015521CDCCE9F004486FA /* ArrayExtension.swift */; };
|
||||
2310155D1CDCCF8D004486FA /* CoreDataChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310155C1CDCCF8D004486FA /* CoreDataChange.swift */; };
|
||||
2310155E1CDCCF8D004486FA /* CoreDataChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310155C1CDCCF8D004486FA /* CoreDataChange.swift */; };
|
||||
2310155F1CDCCF8D004486FA /* CoreDataChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2310155C1CDCCF8D004486FA /* CoreDataChange.swift */; };
|
||||
@ -268,6 +258,16 @@
|
||||
237A93D01C62A28B006BC2F1 /* iCloudConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2388637E1C5C285F0048B691 /* iCloudConfig.swift */; };
|
||||
239C8E051BF48B680025DB9A /* ContextParent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239C8E041BF48B680025DB9A /* ContextParent.swift */; };
|
||||
239C8E061BF48B680025DB9A /* ContextParent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239C8E041BF48B680025DB9A /* ContextParent.swift */; };
|
||||
239FE4CE1CDE67DE0050502F /* CoreDataObservableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CD1CDE67DE0050502F /* CoreDataObservableTests.swift */; };
|
||||
239FE4D11CDE7FCE0050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D21CDE7FCE0050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D31CDE7FCF0050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D41CDE7FCF0050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D51CDE7FD00050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D61CDE7FD00050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D71CDE7FD10050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4D81CDE7FD10050502F /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */; };
|
||||
239FE4DA1CDE81D00050502F /* CoreDataChangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 239FE4D91CDE81D00050502F /* CoreDataChangeTests.swift */; };
|
||||
23A916751C17365A005E57D8 /* DirUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A916741C17365A005E57D8 /* DirUtilsTests.swift */; };
|
||||
23A916771C173CAF005E57D8 /* OptionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A916761C173CAF005E57D8 /* OptionsTests.swift */; };
|
||||
23A916791C173E5F005E57D8 /* CoreDataDefaultStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23A916781C173E5F005E57D8 /* CoreDataDefaultStorageTests.swift */; };
|
||||
@ -339,7 +339,6 @@
|
||||
231015401CDC9F0B004486FA /* Observable+ReactiveCocoa.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+ReactiveCocoa.swift"; sourceTree = "<group>"; };
|
||||
2310154A1CDCB529004486FA /* RealmObservableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmObservableTests.swift; sourceTree = "<group>"; };
|
||||
2310154C1CDCCA42004486FA /* CoreDataObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataObservable.swift; sourceTree = "<group>"; };
|
||||
231015521CDCCE9F004486FA /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = "<group>"; };
|
||||
2310155C1CDCCF8D004486FA /* CoreDataChange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataChange.swift; sourceTree = "<group>"; };
|
||||
2319B7FA1C23FF8F0050ABE8 /* SugarRecordRealm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SugarRecordRealm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2319B81F1C2400420050ABE8 /* SugarRecordRealm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SugarRecordRealm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -394,6 +393,9 @@
|
||||
238863791C5C239C0048B691 /* CoreDataiCloudStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataiCloudStorage.swift; sourceTree = "<group>"; };
|
||||
2388637E1C5C285F0048B691 /* iCloudConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = iCloudConfig.swift; sourceTree = "<group>"; };
|
||||
239C8E041BF48B680025DB9A /* ContextParent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextParent.swift; sourceTree = "<group>"; };
|
||||
239FE4CD1CDE67DE0050502F /* CoreDataObservableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataObservableTests.swift; sourceTree = "<group>"; };
|
||||
239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayExtension.swift; sourceTree = "<group>"; };
|
||||
239FE4D91CDE81D00050502F /* CoreDataChangeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataChangeTests.swift; sourceTree = "<group>"; };
|
||||
23A916741C17365A005E57D8 /* DirUtilsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DirUtilsTests.swift; sourceTree = "<group>"; };
|
||||
23A916761C173CAF005E57D8 /* OptionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionsTests.swift; sourceTree = "<group>"; };
|
||||
23A916781C173E5F005E57D8 /* CoreDataDefaultStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CoreDataDefaultStorageTests.swift; path = Storage/CoreDataDefaultStorageTests.swift; sourceTree = "<group>"; };
|
||||
@ -578,6 +580,8 @@
|
||||
2305F8ED1BF0FAFC00F9D379 /* ObjectModelTests.swift */,
|
||||
2305F8EB1BF0F89200F9D379 /* StoreTests.swift */,
|
||||
23A916761C173CAF005E57D8 /* OptionsTests.swift */,
|
||||
239FE4CD1CDE67DE0050502F /* CoreDataObservableTests.swift */,
|
||||
239FE4D91CDE81D00050502F /* CoreDataChangeTests.swift */,
|
||||
);
|
||||
path = Entities;
|
||||
sourceTree = "<group>";
|
||||
@ -722,7 +726,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2353E6331BED4AC00081E6E7 /* RequestExtension.swift */,
|
||||
231015521CDCCE9F004486FA /* ArrayExtension.swift */,
|
||||
239FE4CF1CDE7FC90050502F /* ArrayExtension.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@ -1704,7 +1708,7 @@
|
||||
2319B7DF1C23FF8F0050ABE8 /* Requestable.swift in Sources */,
|
||||
2319B7E11C23FF8F0050ABE8 /* ReactiveError.swift in Sources */,
|
||||
2319B7E21C23FF8F0050ABE8 /* NSPredicateConvertible.swift in Sources */,
|
||||
231015541CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
239FE4D71CDE7FD10050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B7E31C23FF8F0050ABE8 /* Error.swift in Sources */,
|
||||
2319B7E41C23FF8F0050ABE8 /* Context.swift in Sources */,
|
||||
2319B7E51C23FF8F0050ABE8 /* Results.swift in Sources */,
|
||||
@ -1734,7 +1738,7 @@
|
||||
2319B8001C2400420050ABE8 /* Request.swift in Sources */,
|
||||
2319B8061C2400420050ABE8 /* NSSortDescriptorConvertible.swift in Sources */,
|
||||
2319B80A1C2400420050ABE8 /* NSPredicateConvertible.swift in Sources */,
|
||||
231015561CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
239FE4D51CDE7FD00050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B80B1C2400420050ABE8 /* Error.swift in Sources */,
|
||||
2319B80C1C2400420050ABE8 /* Context.swift in Sources */,
|
||||
2319B80E1C2400420050ABE8 /* RequestExtension.swift in Sources */,
|
||||
@ -1764,7 +1768,7 @@
|
||||
233390171C67B41400844B9D /* ReactiveStorage+ReactiveCocoa.swift in Sources */,
|
||||
2319B87F1C2402300050ABE8 /* NSSortDescriptorConvertible.swift in Sources */,
|
||||
2319B8801C2402300050ABE8 /* Context.swift in Sources */,
|
||||
231015581CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
239FE4D31CDE7FCF0050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B8811C2402300050ABE8 /* Entity.swift in Sources */,
|
||||
2319B8821C2402300050ABE8 /* Requestable.swift in Sources */,
|
||||
2319B8741C2402290050ABE8 /* Realm.swift in Sources */,
|
||||
@ -1794,7 +1798,7 @@
|
||||
233390191C67B41400844B9D /* ReactiveStorage+ReactiveCocoa.swift in Sources */,
|
||||
2319B8D51C2402C30050ABE8 /* NSSortDescriptorConvertible.swift in Sources */,
|
||||
2319B8D61C2402C30050ABE8 /* Context.swift in Sources */,
|
||||
2310155A1CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
239FE4D11CDE7FCE0050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B8D71C2402C30050ABE8 /* Entity.swift in Sources */,
|
||||
2319B8D81C2402C30050ABE8 /* Requestable.swift in Sources */,
|
||||
2319B8C81C2402BA0050ABE8 /* ReactiveError.swift in Sources */,
|
||||
@ -1829,6 +1833,7 @@
|
||||
2310154D1CDCCA42004486FA /* CoreDataObservable.swift in Sources */,
|
||||
2333901A1C67B41400844B9D /* ReactiveStorage+Rx.swift in Sources */,
|
||||
231015251CDC8EC3004486FA /* Observable.swift in Sources */,
|
||||
239FE4D81CDE7FD10050502F /* ArrayExtension.swift in Sources */,
|
||||
2353E6671BED4B250081E6E7 /* CoreData.swift in Sources */,
|
||||
23A9167D1C173FCF005E57D8 /* Requestable.swift in Sources */,
|
||||
2353E63D1BED4AC00081E6E7 /* NSManagedObjectContext.swift in Sources */,
|
||||
@ -1840,7 +1845,6 @@
|
||||
239C8E051BF48B680025DB9A /* ContextParent.swift in Sources */,
|
||||
2353E6511BED4AC00081E6E7 /* RequestExtension.swift in Sources */,
|
||||
2305F8FF1BF1EA8D00F9D379 /* Entity.swift in Sources */,
|
||||
231015531CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
2353E6491BED4AC00081E6E7 /* Storage.swift in Sources */,
|
||||
233390121C67B41400844B9D /* ReactiveStorage+ReactiveCocoa.swift in Sources */,
|
||||
2305F8F11BF0FE4500F9D379 /* DirUtils.swift in Sources */,
|
||||
@ -1866,6 +1870,7 @@
|
||||
2310154E1CDCCA42004486FA /* CoreDataObservable.swift in Sources */,
|
||||
2353E6681BED4B250081E6E7 /* CoreData.swift in Sources */,
|
||||
231015271CDC8EC3004486FA /* Observable.swift in Sources */,
|
||||
239FE4D61CDE7FD00050502F /* ArrayExtension.swift in Sources */,
|
||||
239C8E061BF48B680025DB9A /* ContextParent.swift in Sources */,
|
||||
2353E63E1BED4AC00081E6E7 /* NSManagedObjectContext.swift in Sources */,
|
||||
2353E65A1BED4AC00081E6E7 /* NSPredicateConvertible.swift in Sources */,
|
||||
@ -1877,7 +1882,6 @@
|
||||
23F3F36B1C1DFA6D009A5CC1 /* ReactiveError.swift in Sources */,
|
||||
23AC16271BF370BA00FAF97A /* Entity.swift in Sources */,
|
||||
2353E64A1BED4AC00081E6E7 /* Storage.swift in Sources */,
|
||||
231015551CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
23A9167E1C173FCF005E57D8 /* Requestable.swift in Sources */,
|
||||
233390141C67B41400844B9D /* ReactiveStorage+ReactiveCocoa.swift in Sources */,
|
||||
2305F8F21BF0FE4500F9D379 /* DirUtils.swift in Sources */,
|
||||
@ -1904,7 +1908,6 @@
|
||||
2319B86F1C2401F90050ABE8 /* Entity.swift in Sources */,
|
||||
2319B8701C2401F90050ABE8 /* Requestable.swift in Sources */,
|
||||
2333901E1C67B41400844B9D /* ReactiveStorage+Rx.swift in Sources */,
|
||||
231015571CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
2319B85D1C2401F20050ABE8 /* CoreData.swift in Sources */,
|
||||
2319B85E1C2401F20050ABE8 /* ObjectModel.swift in Sources */,
|
||||
2319B85F1C2401F20050ABE8 /* Store.swift in Sources */,
|
||||
@ -1916,6 +1919,7 @@
|
||||
2319B8641C2401F20050ABE8 /* NSManagedObjectContext.swift in Sources */,
|
||||
2310153C1CDC9C64004486FA /* Observable+Rx.swift in Sources */,
|
||||
2310154F1CDCCA42004486FA /* CoreDataObservable.swift in Sources */,
|
||||
239FE4D41CDE7FCF0050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B8651C2401F20050ABE8 /* NSManagedObjectMemoryContext.swift in Sources */,
|
||||
2319B8661C2401F20050ABE8 /* CoreDataDefaultStorage.swift in Sources */,
|
||||
2319B85B1C2401E80050ABE8 /* ReactiveError.swift in Sources */,
|
||||
@ -1942,7 +1946,6 @@
|
||||
2319B8C51C2402960050ABE8 /* NSManagedObjectMemoryContext.swift in Sources */,
|
||||
2319B8C61C2402960050ABE8 /* CoreDataDefaultStorage.swift in Sources */,
|
||||
233390201C67B41400844B9D /* ReactiveStorage+Rx.swift in Sources */,
|
||||
231015591CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
2319B8B21C24028C0050ABE8 /* DirUtils.swift in Sources */,
|
||||
2319B8B31C24028C0050ABE8 /* Request.swift in Sources */,
|
||||
2319B8B41C24028C0050ABE8 /* Storage.swift in Sources */,
|
||||
@ -1954,6 +1957,7 @@
|
||||
2319B8B91C24028C0050ABE8 /* Context.swift in Sources */,
|
||||
2310153E1CDC9C64004486FA /* Observable+Rx.swift in Sources */,
|
||||
231015501CDCCA42004486FA /* CoreDataObservable.swift in Sources */,
|
||||
239FE4D21CDE7FCE0050502F /* ArrayExtension.swift in Sources */,
|
||||
2319B8BA1C24028C0050ABE8 /* Entity.swift in Sources */,
|
||||
2319B8BB1C24028C0050ABE8 /* Requestable.swift in Sources */,
|
||||
2319B8B11C2402850050ABE8 /* ReactiveError.swift in Sources */,
|
||||
@ -1972,14 +1976,14 @@
|
||||
23B15C521BF352AD0059008E /* Issue.swift in Sources */,
|
||||
3DE3FD961BF12B8C00009071 /* DataModel.xcdatamodeld in Sources */,
|
||||
3DDE7D451BF4E45E00D166C4 /* Track+CoreDataProperties.swift in Sources */,
|
||||
231015511CDCCA42004486FA /* CoreDataObservable.swift in Sources */,
|
||||
230CBDC21BF37F7A00C43A48 /* ResultsTests.swift in Sources */,
|
||||
2305F8EE1BF0FAFC00F9D379 /* ObjectModelTests.swift in Sources */,
|
||||
23A916791C173E5F005E57D8 /* CoreDataDefaultStorageTests.swift in Sources */,
|
||||
239FE4CE1CDE67DE0050502F /* CoreDataObservableTests.swift in Sources */,
|
||||
239FE4DA1CDE81D00050502F /* CoreDataChangeTests.swift in Sources */,
|
||||
23B15C591BF353F70059008E /* Realm.swift in Sources */,
|
||||
23B15C571BF3535E0059008E /* RealmTests.swift in Sources */,
|
||||
3D733FD51C0C2AC400B74DA1 /* RequestTests.swift in Sources */,
|
||||
2310155B1CDCCE9F004486FA /* ArrayExtension.swift in Sources */,
|
||||
231C61EF1C17482100CD6532 /* CoreData.swift in Sources */,
|
||||
2305F8EC1BF0F89200F9D379 /* StoreTests.swift in Sources */,
|
||||
23B15C501BF352540059008E /* Repository.swift in Sources */,
|
||||
|
@ -2,8 +2,6 @@ import Foundation
|
||||
|
||||
internal enum CoreDataChange<T> {
|
||||
|
||||
// TODO - Test
|
||||
|
||||
case Update(T)
|
||||
case Insert(T)
|
||||
case Delete(T)
|
||||
@ -18,7 +16,7 @@ internal enum CoreDataChange<T> {
|
||||
|
||||
func isDeletion() -> Bool {
|
||||
switch self {
|
||||
case .Insert(_): return true
|
||||
case .Delete(_): return true
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
@ -36,4 +34,5 @@ internal enum CoreDataChange<T> {
|
||||
default: return false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,74 +1,69 @@
|
||||
//import Foundation
|
||||
//import CoreData
|
||||
//
|
||||
//public class CoreDataObservable<T: NSManagedObject>: Observable<T>, NSFetchedResultsControllerDelegate {
|
||||
//
|
||||
// // MARK: - Attributes
|
||||
//
|
||||
// internal let fetchedResultsController: NSFetchedResultsController
|
||||
// internal let fetchRequest: NSFetchRequest
|
||||
// internal var observer: (ObservableChange<[T]> -> Void)?
|
||||
// private var batchChanges: [CoreDataChange<T>] = []
|
||||
//
|
||||
//
|
||||
// // MARK: - Init
|
||||
//
|
||||
// public init(request: Request<T>, context: NSManagedObjectContext) {
|
||||
// let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: T.entityName)
|
||||
// if let predicate = request.predicate {
|
||||
// fetchRequest.predicate = predicate
|
||||
// }
|
||||
// if let sortDescriptor = request.sortDescriptor {
|
||||
// fetchRequest.sortDescriptors = [sortDescriptor]
|
||||
// }
|
||||
// self.fetchRequest = fetchRequest
|
||||
// self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
|
||||
// super.init(request: request)
|
||||
// self.fetchedResultsController.delegate = self
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // MARK: - Observable
|
||||
//
|
||||
// public override func observe(closure: ObservableChange<[T]> -> Void) {
|
||||
// assert(self.observer != nil, "Observable can be observed only once")
|
||||
// let initial = try! self.fetchedResultsController.managedObjectContext.executeFetchRequest(self.fetchRequest) as! [T]
|
||||
// closure(ObservableChange.Initial(initial))
|
||||
// self.observer = closure
|
||||
// }
|
||||
//
|
||||
// // MARK: - NSFetchedResultsControllerDelegate
|
||||
//
|
||||
// public func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
|
||||
// switch type {
|
||||
// case .Delete:
|
||||
// self.batchChanges.append(.Delete(anObject as! T))
|
||||
// case .Insert:
|
||||
// self.batchChanges.append(.Insert(anObject as! T))
|
||||
// case .Update:
|
||||
// self.batchChanges.append(.Update(anObject as! T))
|
||||
// default: break
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public func controllerWillChangeContent(controller: NSFetchedResultsController) {
|
||||
// self.batchChanges = []
|
||||
// }
|
||||
//
|
||||
// public func controllerDidChangeContent(controller: NSFetchedResultsController) {
|
||||
// let objects = self.batchChanges.map {$0.object()}
|
||||
// let deleted = self.batchChanges.filterAndMapIndex { $0.isDeletion() }
|
||||
// let inserted = self.batchChanges.filterAndMapIndex { $0.isInsertion() }
|
||||
// let updated = self.batchChanges.filterAndMapIndex { $0.isUpdate() }
|
||||
// self.observer?(ObservableChange.Update(objects, deletions: deleted, insertions: inserted, modifications: updated))
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // MARK: - Deinit
|
||||
//
|
||||
// deinit {
|
||||
// self.fetchedResultsController.delegate = nil
|
||||
// self.observer = nil
|
||||
// }
|
||||
//
|
||||
//}
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
public class CoreDataObservable<T: NSManagedObject where T:Equatable>: Observable<T>, NSFetchedResultsControllerDelegate {
|
||||
|
||||
// MARK: - Attributes
|
||||
|
||||
internal let fetchRequest: NSFetchRequest
|
||||
internal var observer: (ObservableChange<[T]> -> Void)?
|
||||
internal let fetchedResultsController: NSFetchedResultsController
|
||||
private var batchChanges: [CoreDataChange<T>] = []
|
||||
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
internal init(request: Request<T>, context: NSManagedObjectContext) {
|
||||
|
||||
let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: T.entityName)
|
||||
if let predicate = request.predicate {
|
||||
fetchRequest.predicate = predicate
|
||||
}
|
||||
if let sortDescriptor = request.sortDescriptor {
|
||||
fetchRequest.sortDescriptors = [sortDescriptor]
|
||||
}
|
||||
fetchRequest.fetchBatchSize = 0
|
||||
self.fetchRequest = fetchRequest
|
||||
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
|
||||
super.init(request: request)
|
||||
self.fetchedResultsController.delegate = self
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Observable
|
||||
|
||||
public override func observe(closure: ObservableChange<[T]> -> Void) {
|
||||
assert(self.observer == nil, "Observable can be observed only once")
|
||||
let initial = try! self.fetchedResultsController.managedObjectContext.executeFetchRequest(self.fetchRequest) as! [T]
|
||||
closure(ObservableChange.Initial(initial))
|
||||
self.observer = closure
|
||||
_ = try? self.fetchedResultsController.performFetch()
|
||||
}
|
||||
|
||||
|
||||
// MARK: - NSFetchedResultsControllerDelegate
|
||||
|
||||
public func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
|
||||
switch type {
|
||||
case .Delete:
|
||||
self.batchChanges.append(.Delete(anObject as! T))
|
||||
case .Insert:
|
||||
self.batchChanges.append(.Insert(anObject as! T))
|
||||
case .Update:
|
||||
self.batchChanges.append(.Update(anObject as! T))
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
public func controllerWillChangeContent(controller: NSFetchedResultsController) {
|
||||
self.batchChanges = []
|
||||
}
|
||||
|
||||
public func controllerDidChangeContent(controller: NSFetchedResultsController) {
|
||||
let deleted = self.batchChanges.filter { $0.isDeletion() }.map { $0.object() }
|
||||
let inserted = self.batchChanges.filter { $0.isInsertion() }.map { $0.object() }
|
||||
let updated = self.batchChanges.filter { $0.isUpdate() }.map { $0.object() }
|
||||
self.observer?(ObservableChange.Update(deletions: deleted, insertions: inserted, modifications: updated))
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ public extension CoreData {
|
||||
switch self {
|
||||
case .Default:
|
||||
var sqliteOptions: [String: String] = [String: String] ()
|
||||
sqliteOptions["WAL"] = "journal_mode"
|
||||
sqliteOptions["journal_mode"] = "DELETE"
|
||||
var options: [NSObject: AnyObject] = [NSObject: AnyObject] ()
|
||||
options[NSMigratePersistentStoresAutomaticallyOption] = NSNumber(bool: true)
|
||||
options[NSInferMappingModelAutomaticallyOption] = NSNumber(bool: false)
|
||||
@ -19,7 +19,7 @@ public extension CoreData {
|
||||
return options
|
||||
case .Migration:
|
||||
var sqliteOptions: [String: String] = [String: String] ()
|
||||
sqliteOptions["WAL"] = "journal_mode"
|
||||
sqliteOptions["journal_mode"] = "DELETE"
|
||||
var options: [NSObject: AnyObject] = [NSObject: AnyObject] ()
|
||||
options[NSMigratePersistentStoresAutomaticallyOption] = NSNumber(bool: true)
|
||||
options[NSInferMappingModelAutomaticallyOption] = NSNumber(bool: true)
|
||||
|
@ -73,6 +73,9 @@ public class CoreDataDefaultStorage: Storage {
|
||||
|
||||
public func removeStore() throws {
|
||||
try NSFileManager.defaultManager().removeItemAtURL(store.path())
|
||||
_ = try? NSFileManager.defaultManager().removeItemAtPath("\(store.path().absoluteString)-shm")
|
||||
_ = try? NSFileManager.defaultManager().removeItemAtPath("\(store.path().absoluteString)-wal")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -90,9 +93,9 @@ public class CoreDataDefaultStorage: Storage {
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
// public func observable<T: NSManagedObject>(request: Request<T>) -> Observable<T> {
|
||||
// return CoreDataObservable(request: request, context: self.mainContext as! NSManagedObjectContext)
|
||||
// }
|
||||
public func observable<T: NSManagedObject where T:Equatable>(request: Request<T>) -> Observable<T> {
|
||||
return CoreDataObservable(request: request, context: self.mainContext as! NSManagedObjectContext)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -92,10 +92,10 @@ public class CoreDataiCloudStorage: Storage {
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
// public func observable<T: NSManagedObject>(request: Request<T>) -> Observable<T> {
|
||||
// return CoreDataObservable(request: request, context: self.mainContext as! NSManagedObjectContext)
|
||||
// }
|
||||
//
|
||||
public func observable<T: NSManagedObject where T:Equatable>(request: Request<T>) -> Observable<T> {
|
||||
return CoreDataObservable(request: request, context: self.mainContext as! NSManagedObjectContext)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
|
@ -2,7 +2,7 @@ import Foundation
|
||||
|
||||
public enum ObservableChange<T> {
|
||||
case Initial(T)
|
||||
case Update(T, deletions: [Int], insertions: [Int], modifications: [Int])
|
||||
case Update(deletions: T, insertions: T, modifications: T)
|
||||
case Error(NSError)
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ public struct Request<T: Entity>: Equatable {
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
public func ==<T>(lhs: Request<T>, rhs: Request<T>) -> Bool {
|
||||
public func == <T>(lhs: Request<T>, rhs: Request<T>) -> Bool {
|
||||
return lhs.sortDescriptor == rhs.sortDescriptor &&
|
||||
lhs.predicate == rhs.predicate
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ public enum StorageType {
|
||||
case Realm
|
||||
}
|
||||
|
||||
typealias StorageOperation = ((context: Context, save: () -> Void) throws -> Void) throws -> Void
|
||||
|
||||
public protocol Storage: CustomStringConvertible, Requestable {
|
||||
|
||||
var type: StorageType { get }
|
||||
|
@ -1,15 +1,15 @@
|
||||
import Foundation
|
||||
|
||||
extension Array {
|
||||
// TODO: - Test
|
||||
func filterAndMapIndex(include: Element -> Bool) -> [Int] {
|
||||
var indexes: [Int] = []
|
||||
self.enumerate().forEach { (element) in
|
||||
if include(element.element) {
|
||||
indexes.append(element.index)
|
||||
|
||||
func filter(closure: (index: Int, element: Element) -> Bool) -> [Element] {
|
||||
var filtered: [Element] = []
|
||||
var index: Int = 0
|
||||
self.forEach { (element) in
|
||||
if closure(index: index, element: element) {
|
||||
filtered.append(element)
|
||||
}
|
||||
index = index + 1
|
||||
}
|
||||
return indexes
|
||||
return filtered
|
||||
}
|
||||
|
||||
}
|
@ -5,9 +5,9 @@ public extension Observable {
|
||||
|
||||
public func rx_observe() -> RxSwift.Observable<ObservableChange<[T]>> {
|
||||
return RxSwift.Observable.create { (observer) -> Disposable in
|
||||
self.observe({ (change) in
|
||||
self.observe { change in
|
||||
observer.onNext(change)
|
||||
})
|
||||
}
|
||||
return AnonymousDisposable {
|
||||
self.dispose()
|
||||
observer.onCompleted()
|
||||
|
@ -47,7 +47,10 @@ public class RealmObservable<T: Object>: Observable<T> {
|
||||
case .Initial(let initial):
|
||||
return ObservableChange.Initial(initial.toArray())
|
||||
case .Update(let objects, let deletions, let insertions, let modifications):
|
||||
return ObservableChange.Update(objects.toArray(), deletions: deletions, insertions: insertions, modifications: modifications)
|
||||
let deletions = objects.toArray().filter { deletions.indexOf($0.0) != nil }
|
||||
let insertions = objects.toArray().filter { insertions.indexOf($0.0) != nil }
|
||||
let modifications = objects.toArray().filter { modifications.indexOf($0.0) != nil }
|
||||
return ObservableChange.Update(deletions: deletions, insertions: insertions, modifications: modifications)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,110 @@
|
||||
import Foundation
|
||||
import Quick
|
||||
import Nimble
|
||||
|
||||
@testable import SugarRecordCoreData
|
||||
|
||||
class CoreDataChangeTests: QuickSpec {
|
||||
|
||||
override func spec() {
|
||||
|
||||
context("Insert") {
|
||||
var change: CoreDataChange<String>!
|
||||
|
||||
beforeSuite {
|
||||
change = .Insert("insert")
|
||||
}
|
||||
|
||||
describe("-object") {
|
||||
it("should return the correct object") {
|
||||
expect(change.object()) == "insert"
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isDeletion") {
|
||||
it("should return false") {
|
||||
expect(change.isDeletion()) == false
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isUpdate") {
|
||||
it("should return false") {
|
||||
expect(change.isUpdate()) == false
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isInsertion") {
|
||||
it("should return true") {
|
||||
expect(change.isInsertion()) == true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context("Update") {
|
||||
var change: CoreDataChange<String>!
|
||||
|
||||
beforeSuite {
|
||||
change = .Update("update")
|
||||
}
|
||||
|
||||
describe("-object") {
|
||||
it("should return the correct object") {
|
||||
expect(change.object()) == "update"
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isDeletion") {
|
||||
it("should return false") {
|
||||
expect(change.isDeletion()) == false
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isUpdate") {
|
||||
it("should return true") {
|
||||
expect(change.isUpdate()) == true
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isInsertion") {
|
||||
it("should return false") {
|
||||
expect(change.isInsertion()) == false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context("Delete") {
|
||||
|
||||
var change: CoreDataChange<String>!
|
||||
|
||||
beforeSuite {
|
||||
change = .Delete("delete")
|
||||
}
|
||||
|
||||
describe("-object") {
|
||||
it("should return the correct object") {
|
||||
expect(change.object()) == "delete"
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isDeletion") {
|
||||
it("should return true") {
|
||||
expect(change.isDeletion()) == true
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isUpdate") {
|
||||
it("should return false") {
|
||||
expect(change.isUpdate()) == false
|
||||
}
|
||||
}
|
||||
|
||||
describe("-isInsertion") {
|
||||
it("should return false") {
|
||||
expect(change.isInsertion()) == false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
import Foundation
|
||||
import Quick
|
||||
import Nimble
|
||||
import CoreData
|
||||
|
||||
@testable import SugarRecordCoreData
|
||||
|
||||
class CoreDataObservableTests: QuickSpec {
|
||||
|
||||
override func spec() {
|
||||
|
||||
var request: Request<Track>!
|
||||
var subject: CoreDataObservable<Track>!
|
||||
var storage: CoreDataDefaultStorage!
|
||||
|
||||
beforeEach {
|
||||
let store: CoreData.Store = CoreData.Store.Named("test")
|
||||
let bundle = NSBundle(forClass: self.classForCoder)
|
||||
let model = CoreData.ObjectModel.Merged([bundle])
|
||||
storage = try! CoreDataDefaultStorage(store: store, model: model)
|
||||
_ = try? storage.removeStore()
|
||||
request = Request<Track>().sortedWith("name", ascending: true)
|
||||
let context: NSManagedObjectContext = storage.mainContext as! NSManagedObjectContext
|
||||
subject = CoreDataObservable(request: request, context: context)
|
||||
context.performBlock({
|
||||
let track: Track = try! context.create()
|
||||
track.name = "test"
|
||||
track.artist = "pedro"
|
||||
try! context.save()
|
||||
})
|
||||
}
|
||||
|
||||
afterEach {
|
||||
_ = try? storage.removeStore()
|
||||
}
|
||||
|
||||
describe("-observe:") {
|
||||
it("should report the initial state") {
|
||||
waitUntil(action: { (done) in
|
||||
subject.observe({ (change) in
|
||||
switch change {
|
||||
case .Initial(let values):
|
||||
expect(values.first?.name) == "test"
|
||||
expect(values.first?.artist) == "pedro"
|
||||
done()
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
it("should report updates") {
|
||||
waitUntil(action: { (done) in
|
||||
subject.observe({ (change) in
|
||||
switch change {
|
||||
case .Update(_, let insertions, _):
|
||||
expect(insertions[0].name) == "test2"
|
||||
expect(insertions[0].artist) == "pedro"
|
||||
done()
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
let context: NSManagedObjectContext = storage.mainContext as! NSManagedObjectContext
|
||||
context.performBlockAndWait {
|
||||
let track: Track = try! context.create()
|
||||
track.name = "test2"
|
||||
track.artist = "pedro"
|
||||
try! context.save()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@ class OptionsTests: QuickSpec {
|
||||
it("should return the right data for default options") {
|
||||
let options = CoreData.Options.Default.dict()
|
||||
let sqliteOptions = options[NSSQLitePragmasOption] as! [String: String]
|
||||
expect(sqliteOptions["WAL"]) == "journal_mode"
|
||||
expect(sqliteOptions["journal_mode"]) == "DELETE"
|
||||
expect(options[NSMigratePersistentStoresAutomaticallyOption] as? NSNumber) == NSNumber(bool: true)
|
||||
expect(options[NSInferMappingModelAutomaticallyOption] as? NSNumber) == NSNumber(bool: false)
|
||||
}
|
||||
@ -22,7 +22,7 @@ class OptionsTests: QuickSpec {
|
||||
it("should return the right data for migration options") {
|
||||
let options = CoreData.Options.Migration.dict()
|
||||
let sqliteOptions = options[NSSQLitePragmasOption] as! [String: String]
|
||||
expect(sqliteOptions["WAL"]) == "journal_mode"
|
||||
expect(sqliteOptions["journal_mode"]) == "DELETE"
|
||||
expect(options[NSMigratePersistentStoresAutomaticallyOption] as? NSNumber) == NSNumber(bool: true)
|
||||
expect(options[NSInferMappingModelAutomaticallyOption] as? NSNumber) == NSNumber(bool: true)
|
||||
}
|
||||
|
@ -10,19 +10,19 @@ class CoreDataDefaultStorageTests: QuickSpec {
|
||||
|
||||
describe("storage") { () -> Void in
|
||||
|
||||
var store: CoreData.Store?
|
||||
var model: CoreData.ObjectModel?
|
||||
var defaultStorage: CoreDataDefaultStorage?
|
||||
var store: CoreData.Store!
|
||||
var model: CoreData.ObjectModel!
|
||||
var subject: CoreDataDefaultStorage!
|
||||
|
||||
beforeEach {
|
||||
store = CoreData.Store.Named("test")
|
||||
let bundle = NSBundle(forClass: self.classForCoder)
|
||||
model = CoreData.ObjectModel.Merged([bundle])
|
||||
defaultStorage = try! CoreDataDefaultStorage(store: store!, model: model!)
|
||||
subject = try! CoreDataDefaultStorage(store: store!, model: model!)
|
||||
}
|
||||
|
||||
afterEach {
|
||||
_ = try? defaultStorage?.removeStore()
|
||||
_ = try? subject?.removeStore()
|
||||
}
|
||||
|
||||
context("initialization") {
|
||||
@ -33,57 +33,57 @@ class CoreDataDefaultStorageTests: QuickSpec {
|
||||
}
|
||||
|
||||
it("should have the right description") {
|
||||
expect(defaultStorage?.description) == "CoreDataDefaultStorage"
|
||||
expect(subject?.description) == "CoreDataDefaultStorage"
|
||||
}
|
||||
|
||||
it("should have the right type") {
|
||||
expect(defaultStorage?.type) == .CoreData
|
||||
expect(subject?.type) == .CoreData
|
||||
}
|
||||
|
||||
describe("root saving context") {
|
||||
it("should have the persistent store coordinator as parent") {
|
||||
expect(defaultStorage?.rootSavingContext.persistentStoreCoordinator) == defaultStorage?.persistentStoreCoordinator
|
||||
expect(subject?.rootSavingContext.persistentStoreCoordinator) == subject?.persistentStoreCoordinator
|
||||
}
|
||||
it("should have private concurrency type") {
|
||||
expect(defaultStorage?.rootSavingContext.concurrencyType) == .PrivateQueueConcurrencyType
|
||||
expect(subject?.rootSavingContext.concurrencyType) == .PrivateQueueConcurrencyType
|
||||
}
|
||||
}
|
||||
|
||||
describe("save context") {
|
||||
it("should have the root saving context as parent") {
|
||||
expect((defaultStorage?.saveContext as! NSManagedObjectContext).parentContext) == defaultStorage?.rootSavingContext
|
||||
expect((subject?.saveContext as! NSManagedObjectContext).parentContext) == subject?.rootSavingContext
|
||||
}
|
||||
|
||||
it("should have private concurrency type") {
|
||||
expect((defaultStorage?.saveContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType
|
||||
expect((subject?.saveContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
describe("memory context") {
|
||||
it("should have the root saving context as parent") {
|
||||
expect((defaultStorage?.memoryContext as! NSManagedObjectContext).parentContext) == defaultStorage?.rootSavingContext
|
||||
expect((subject?.memoryContext as! NSManagedObjectContext).parentContext) == subject?.rootSavingContext
|
||||
}
|
||||
|
||||
it("should have private concurrency type") {
|
||||
expect((defaultStorage?.memoryContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType
|
||||
expect((subject?.memoryContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType
|
||||
}
|
||||
}
|
||||
|
||||
describe("main context") {
|
||||
it("should have the root saving context as parent") {
|
||||
expect((defaultStorage?.mainContext as! NSManagedObjectContext).parentContext) == defaultStorage?.rootSavingContext
|
||||
expect((subject?.mainContext as! NSManagedObjectContext).parentContext) == subject?.rootSavingContext
|
||||
}
|
||||
|
||||
it("should have main concurrency type") {
|
||||
expect((defaultStorage?.mainContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType
|
||||
expect((subject?.mainContext as! NSManagedObjectContext).concurrencyType) == NSManagedObjectContextConcurrencyType.MainQueueConcurrencyType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context("removal") {
|
||||
it("should properly remove the store") {
|
||||
_ = try? defaultStorage?.removeStore()
|
||||
_ = try? subject?.removeStore()
|
||||
let path = store!.path().path!
|
||||
expect(NSFileManager.defaultManager().fileExistsAtPath(path)) == false
|
||||
}
|
||||
@ -93,10 +93,10 @@ class CoreDataDefaultStorageTests: QuickSpec {
|
||||
|
||||
it("shouldn't persist changes if we save the memory context") {
|
||||
waitUntil(action: { (done) -> Void in
|
||||
let memoryContext = defaultStorage!.memoryContext as! NSManagedObjectContext!
|
||||
let memoryContext = subject!.memoryContext as! NSManagedObjectContext!
|
||||
let _: Track = try! memoryContext.create()
|
||||
try! memoryContext.save()
|
||||
_ = try? defaultStorage?.operation({ (context, save) -> Void in
|
||||
_ = try? subject?.operation({ (context, save) -> Void in
|
||||
let resultsCount = try! context.request(Track.self).fetch().count
|
||||
expect(resultsCount) == 0
|
||||
done()
|
||||
@ -106,17 +106,40 @@ class CoreDataDefaultStorageTests: QuickSpec {
|
||||
|
||||
it("should persist the changes if it's save context") {
|
||||
waitUntil(action: { (done) -> Void in
|
||||
_ = try? defaultStorage?.operation({ (context, save) -> Void in
|
||||
_ = try? subject?.operation({ (context, save) -> Void in
|
||||
let _: Track = try! context.create()
|
||||
save()
|
||||
})
|
||||
let tracksCount: Int? = try! defaultStorage?.mainContext.request(Track.self).fetch().count
|
||||
let tracksCount: Int? = try! subject?.mainContext.request(Track.self).fetch().count
|
||||
expect(tracksCount) == 1
|
||||
done()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
describe("-observable:") {
|
||||
|
||||
var request: Request<Track>!
|
||||
var observable: CoreDataObservable<Track>!
|
||||
|
||||
beforeEach {
|
||||
request = Request<Track>().filteredWith("name", equalTo: "test").sortedWith("name", ascending: true)
|
||||
observable = subject.observable(request) as! CoreDataObservable<Track>
|
||||
}
|
||||
|
||||
it("should have the correct request predicate") {
|
||||
expect(observable.fetchRequest.predicate) == request.predicate
|
||||
}
|
||||
|
||||
it("should have the correct request sort descriptor") {
|
||||
expect(observable.fetchRequest.sortDescriptors) == [request.sortDescriptor!]
|
||||
}
|
||||
|
||||
it("should have the correct context") {
|
||||
expect(observable.fetchedResultsController.managedObjectContext) == subject.mainContext! as? NSManagedObjectContext
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,9 +52,8 @@ class RealmObservableTests: QuickSpec {
|
||||
waitUntil(timeout: 5.0, action: { (done) in
|
||||
subject.observe({ (change) in
|
||||
switch change {
|
||||
case .Update(let updated, _, let insertions, _):
|
||||
expect(insertions.first) == 1
|
||||
expect(updated[1].id) == "666"
|
||||
case .Update(_, let insertions, _):
|
||||
expect(insertions[0].id) == "666"
|
||||
done()
|
||||
default:
|
||||
break
|
||||
|
Loading…
Reference in New Issue
Block a user