-
Notifications
You must be signed in to change notification settings - Fork 364
/
YapDatabaseViewConnection.h
218 lines (206 loc) · 8.59 KB
/
YapDatabaseViewConnection.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#import <Foundation/Foundation.h>
#import "YapDatabaseExtensionConnection.h"
#import "YapDatabaseViewChange.h"
#import "YapDatabaseViewMappings.h"
@class YapDatabaseView;
NS_ASSUME_NONNULL_BEGIN
/**
* Welcome to YapDatabase!
*
* https://github.com/yapstudios/YapDatabase
*
* The project wiki has a wealth of documentation if you have any questions.
* https://github.com/yapstudios/YapDatabase/wiki
*
* YapDatabaseView is an extension designed to work with YapDatabase.
* It gives you a persistent sorted "view" of a configurable subset of your data.
*
* For the full documentation on Views, please see the related wiki article:
* https://github.com/yapstudios/YapDatabase/wiki/Views
*
*
* As a extension, YapDatabaseViewConnection is automatically created by YapDatabaseConnnection.
* You can access this object via:
*
* [databaseConnection extension:@"myRegisteredViewName"]
*
* @see YapDatabaseView
* @see YapDatabaseViewTransaction
**/
@interface YapDatabaseViewConnection : YapDatabaseExtensionConnection
/**
* Returns the parent view instance.
**/
@property (nonatomic, strong, readonly) YapDatabaseView *view;
/**
* Want to easily animate a tableView or collectionView when the view changes?
* Want an exact list of changes that happend to the view?
*
* You're in luck!
*
* Here's an overview of how it works:
*
* - (void)yapDatabaseModified:(NSNotification *)notification
* {
* // Jump to the most recent commit.
* // End & Re-Begin the long-lived transaction atomically.
* // Also grab all the notifications for all the commits that I jump.
* NSArray *notifications = [roDatabaseConnection beginLongLivedReadTransaction];
*
* // What changed in my tableView?
*
* NSArray *sectionChanges = nil;
* NSArray *rowChanges = nil;
*
* [[databaseConnection extension:@"sales"] getSectionChanges:§ionChanges
* rowChanges:&rowChanges
* forNotifications:notifications
* withMappings:mappings];
*
* if ([sectionChanges count] == 0 && [rowChanges count] == 0)
* {
* // There aren't any changes that affect our tableView!
* return;
* }
*
* // Familiar with NSFetchedResultsController?
* // Then this should look pretty familiar
*
* [self.tableView beginUpdates];
*
* for (YapDatabaseViewSectionChange *sectionChange in sectionChanges)
* {
* switch (sectionChange.type)
* {
* case YapDatabaseViewChangeDelete :
* {
* [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionChange.index]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeInsert :
* {
* [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionChange.index]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* }
* }
* for (YapDatabaseViewRowChange *rowChange in rowChanges)
* {
* switch (rowChange.type)
* {
* case YapDatabaseViewChangeDelete :
* {
* [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeInsert :
* {
* [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeMove :
* {
* [self.tableView deleteRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* [self.tableView insertRowsAtIndexPaths:@[ rowChange.newIndexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* case YapDatabaseViewChangeUpdate :
* {
* [self.tableView reloadRowsAtIndexPaths:@[ rowChange.indexPath ]
* withRowAnimation:UITableViewRowAnimationAutomatic];
* break;
* }
* }
* }
*
* [self.tableView endUpdates];
* }
**/
- (void)getSectionChanges:(NSArray<YapDatabaseViewSectionChange *> * _Nonnull * _Nullable)sectionChangesPtr
rowChanges:(NSArray<YapDatabaseViewRowChange *> * _Nonnull * _Nullable)rowChangesPtr
forNotifications:(NSArray<NSNotification *> *)notifications
withMappings:(YapDatabaseViewMappings *)mappings;
/**
* A simple YES/NO query to see if the view changed at all, inclusive of all groups.
**/
- (BOOL)hasChangesForNotifications:(NSArray<NSNotification *> *)notifications;
/**
* A simple YES/NO query to see if a particular group within the view changed at all.
**/
- (BOOL)hasChangesForGroup:(NSString *)group inNotifications:(NSArray<NSNotification *> *)notifications;
/**
* A simple YES/NO query to see if any of the given groups within the view changed at all.
**/
- (BOOL)hasChangesForAnyGroups:(NSSet<NSString *> *)groups inNotifications:(NSArray<NSNotification *> *)notifications;
/**
* This method provides a rough estimate of the size of the change-set.
*
* There may be times when a huge change-set overloads the system.
* For example, imagine that 10,000 items were added to the view.
*
* Such a large change-set will likely take a bit longer to process via
* the getSectionChanges:rowChanges:forNotifications:withMappings: method.
* Not only that, but once you have the large arrays of sectionChanges & rowChanges,
* feeding them into the tableView / collectionView can potentially bog down the system
* while it attempts to calculate and perform the necessary animations.
*
* This method is very very fast, and simply returns a sum of the "raw" changes.
*
* By "raw" we mean that it includes each individual change to the view, without any processing.
* For example, if an item was deleted from one group, and inserted into another,
* then this represents 2 raw changes. During formal processing, these two raw operations
* would be consolidated into a single move operation.
* Also note that this method doesn't take a mappings parameter.
* So the sum of all raw changes may include things that would be filtered out during formal
* processing due to group restrictions or range restrictions of the mappings.
*
* However, this method is not intended to be precise.
* It is intended to be fast, and to provide a rough estimate that you might use to
* skip a potentially expensive operation.
*
* Example:
*
* - (void)yapDatabaseModified:(NSNotification *)notification
* {
* NSArray *notifications = [databaseConnection beginLongLivedReadTransaction];
*
* NSUInteger sizeEstimate = [[databaseConnection ext:@"myView"] numberOfRawChangesForNotifications:notifications];
* if (sizeEstimate > 150)
* {
* // Looks like a huge changeset, so let's just reload the tableView (faster)
*
* // We're not going to call getSectionChanges:rowChanges:forNotifications:withMappings:.
* // We don't need to know the sectionChanges & rowChanges.
* // But we do need to move our mappings to the latest commit,
* // so that it matches our databaseConnections.
* // We can take a shortcut to do this, and simply tell it to "refresh" using our databaseConnection.
* [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){
* [mappings updateWithTransaction:transaction];
* }];
*
* // And then we can reload our tableView, and return
* [tableView reloadData];
* return;
* }
*
* // Normal code stuff
*
* NSArray *sectionChanges = nil;
* NSArray *rowChanges = nil;
* [[databaseConnection ext:@"myView"] getSectionChanges:§ionChanges
* rowChanges:&rowChanges
* forNotifications:notifications
* withMappings:mappings];
*
* // Normal animation code goes here....
* }
**/
- (NSUInteger)numberOfRawChangesForNotifications:(NSArray<NSNotification *> *)notifications;
@end
NS_ASSUME_NONNULL_END