splinesoft / SSDataSources

Flexible data sources for your UITableView and UICollectionView.
Other
199 stars 23 forks source link

Add array data source that receives updates via KVO #28

Closed andrewsardone closed 10 years ago

andrewsardone commented 10 years ago

This pull request adds a new object, SSArrayKeyPathDataSource. I think the name sucks, but I like what it does.

You initialize this object with some object and key path, and SSArrayKeyPathDataSource will monitor the targeted NSArray for changes and keep the UITableView/UICollectionView up to date. It's subtllely different from SSArrayDataSource – it allows changes to bubble up to the view while users solely manipulate an array of data.

Through the magic of KVO, any manipulation through the collection's proxy object will result in row insertions/deletions/updates – no need to explicitly send a message to SSArrayKeyPathDataSource:

self.department = [Department new];
self.dataSource = [[SSArrayKeyPathDataSource alloc] initWithSource:self.department
                                                           keyPath:@"employees"];

// someone, somewhere (think via the UI *or* via a background
// service), adds a new employee
NSMutableArray *employees = [self.department mutableArrayValueForKey:@"employees"];
[employees addObject:@"Shelley T. Bunny"];

// The UITableView/UICollectionView tied to SSArrayKeyPathDataSource
// inserts a new row without an explicit…
//     [self.dataSource appendItem:@"Shelley T. Bunny"];

It's not for every scenario, but I find many situations where I just want to manipulate an array and have those changes bubble up.

jhersh commented 10 years ago

This looks really great, thanks!

I'm wondering if this could be modified to support both single- and multi-sectioned data in the same class, perhaps by examining whether the items in the target keypath's array are, themselves, arrays?

I'm also wondering whether, if this new datasource were a subclass of SSArrayDataSource (rather than SSBaseDataSource, that might allow us to simplify and/or remove some of the logic. (To wit: if the private itemsAtKeyPath array can instead reuse the items array, then this data source may not need to provide an implementation of e.g. indexPathForItemWithId:.

Then again, the above are probably mutually exclusive :) Thoughts?

jhersh commented 10 years ago

On second thoughts, it's simpler and perhaps better for now to stick with a single section

andrewsardone commented 10 years ago

I think multi-sectioned data would be a little tricky. In order to receive granular observation updates on the inner arrays, users would have to manipulate the proxy returned from mutableArrayValueForKey:, but I don't know how they're targetable via a key path. It seems like a nice to have, though.

As for subclassing SSArrayDataSource, that could work and would definitely make the implementation simpler – I do hate the duplicate logic. But we wouldn't want SSArrayKeyPathDataSource to have the entire interface of `SSArrayDataSource. For example, we don't want any of the array content manipulation.

…Or do we? Originally SSArrayKeyPathDataSource was all about reacting to changes that others make to the array, but it could easily make those same changes and react to itself.

From there, it really seems like we might solely want SSArrayDataSource. If you initialize it with a target and key path, then it will observe that array for changes. Otherwise, you could initialize it by having it own an array.

Thoughts? Perhaps I'll get some code down first.

jhersh commented 10 years ago

Yup, that was my thought - the KVO bits could be merged into the array data source and be exposed as a second initializer. Under the hood it could still use the same internal array.

You've a good point about modifying the data. Should the array manipulation functions do a no-op when used with target/keypath, or can we safely modify the array we are observing? If so, that'd be really slick :)

andrewsardone commented 10 years ago

Cool, @jhersh: I think you should take a look at splinesoft/SSDataSources#29 and see if that's the way to go.

segiddins commented 10 years ago

@jhersh I believe this is basically a better implementation of my first PR?

andrewsardone commented 10 years ago

Closing this PR in favor of the SSArrayDataSource functionality introduced in splinesoft/SSDataSources#28.