Skip to content

Commit 0fd62cd

Browse files
committed
[Objects] Prevent updating when nothing changes
1 parent 16431af commit 0fd62cd

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

RxQueryKit/RxQueryKit.swift

+28-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,34 @@ extension QuerySet {
99
/// Performs a query for all objects matching the set predicate ordered by any set sort descriptors.
1010
/// Emits a value with an array of all objects when the managed object context is changed.
1111
public func objects() throws -> Observable<[ModelType]> {
12-
return context.qk_objectsDidChange().map { notification in
13-
return try self.array()
14-
}.startWith(try self.array())
12+
let initial = try self.array()
13+
14+
return Observable.create { observer in
15+
observer.on(.Next(initial))
16+
17+
return self.context.qk_objectsDidChange().subscribeNext { notification in
18+
let insertedObjects = notification.insertedObjects.filter {
19+
$0.entity.name == self.entityName
20+
}
21+
let updatedObjects = notification.updatedObjects.filter {
22+
$0.entity.name == self.entityName
23+
}
24+
let deletedObjects = notification.deletedObjects.filter {
25+
$0.entity.name == self.entityName
26+
}
27+
28+
if insertedObjects.isEmpty && updatedObjects.isEmpty && deletedObjects.isEmpty {
29+
return
30+
}
31+
32+
do {
33+
let objects = try self.array()
34+
observer.onNext(objects)
35+
} catch {
36+
observer.onError(error)
37+
}
38+
}
39+
}
1540
}
1641

1742
/// Performs a query for the count of all objects matching the set predicate.

RxQueryKitTests/RxQueryKitTests.swift

+45
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,55 @@ class RxQueryKitTests: XCTestCase {
5252

5353
disposable.dispose()
5454
}
55+
56+
func testObjects() {
57+
var objects: [[Person]] = []
58+
59+
let disposable = try! Person.queryset(context)
60+
.orderBy { $0.name.ascending() }
61+
.objects()
62+
.subscribeNext {
63+
objects.append($0)
64+
}
65+
66+
// Initial value
67+
XCTAssertEqual(objects, [[]])
68+
69+
// Created
70+
let p1 = Person.create(context, name: "kyle1")
71+
let p2 = Person.create(context, name: "kyle2")
72+
let p3 = Person.create(context, name: "kyle3")
73+
try! context.save()
74+
XCTAssertEqual(objects, [[], [p1, p2, p3]])
75+
76+
// Deleted
77+
context.deleteObject(p1)
78+
context.deleteObject(p3)
79+
try! context.save()
80+
XCTAssertEqual(objects, [[], [p1, p2, p3], [p2]])
81+
82+
// Modified Object
83+
context.deleteObject(p1)
84+
context.deleteObject(p3)
85+
p2.name = "kyle updated"
86+
try! context.save()
87+
XCTAssertEqual(objects, [[], [p1, p2, p3], [p2], [p2]])
88+
89+
// Doesn't update when nothing changes
90+
Comment.create(context, text: "Hello World")
91+
try! context.save()
92+
XCTAssertEqual(objects, [[], [p1, p2, p3], [p2], [p2]])
93+
94+
disposable.dispose()
95+
}
5596
}
5697

5798

5899
@objc(Person) class Person : NSManagedObject {
100+
class var name:Attribute<String> {
101+
return Attribute("name")
102+
}
103+
59104
class func createEntityDescription() -> NSEntityDescription {
60105
let name = NSAttributeDescription()
61106
name.name = "name"

0 commit comments

Comments
 (0)