Skip to content

Commit

Permalink
add ability to set items, headers and footers for selected section.
Browse files Browse the repository at this point in the history
  • Loading branch information
DenTelezhkin committed Oct 12, 2014
1 parent 2a5627d commit 1550645
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 42 deletions.
33 changes: 33 additions & 0 deletions DTModelStorage/Core/DTBaseStorage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// DTBaseStorage.h
// DTModelStorageTests
//
// Created by Denys Telezhkin on 12.10.14.
// Copyright (c) 2014 Denys Telezhkin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DTStorageProtocol.h"

/**
DTBaseStorage is a base class for storage classes.
*/

@interface DTBaseStorage : NSObject

/**
Supplementary header kind, that is used for registration and mapping. For example, for UICollectionView this should be UICollectionElementKindHeader.
*/
@property (nonatomic, strong) NSString * supplementaryHeaderKind;

/**
Supplementary footer kind, that is used for registration and mapping. For example, for UICollectionView this should be UICollectionElementKindFooter.
*/
@property (nonatomic, strong) NSString * supplementaryFooterKind;

/**
Delegate property used to transfer current data storage changes.
*/
@property (nonatomic, weak) id <DTStorageUpdating> delegate;

@end
13 changes: 13 additions & 0 deletions DTModelStorage/Core/DTBaseStorage.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// DTBaseStorage.m
// DTModelStorageTests
//
// Created by Denys Telezhkin on 12.10.14.
// Copyright (c) 2014 Denys Telezhkin. All rights reserved.
//

#import "DTBaseStorage.h"

@implementation DTBaseStorage

@end
2 changes: 1 addition & 1 deletion DTModelStorage/Core/DTSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// THE SOFTWARE.

/**
`DTSection` protocol defines an interface for sections returned by DTModelStorage object. For `DTMemoryStorage`, `DTSectionModel` is the object, conforming to current protocol. For `DTCoreDataStorage` NSFetchedResultsController returns `NSFetchedResultsSectionInfo` object, that also conform to current protocol.
`DTSection` protocol defines an interface for sections returned by DTModelStorage object. For `DTMemoryStorage`, `DTSectionModel` is the object, conforming to current protocol. For `DTCoreDataStorage` NSFetchedResultsController returns `NSFetchedResultsSectionInfo` object, that also conforms to current protocol.
*/

@protocol DTSection <NSObject>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,13 @@
// THE SOFTWARE.

#import "DTStorageUpdate.h"

/**
`DTStorageUpdating` protocol is used to transfer data storage updates.
*/

@protocol DTStorageUpdating <NSObject>

@optional

/**
This method transfers data storage updates. Controller, that implements this method, may react to received update by updating it's UI.
@param update `DTStorageUpdate` instance, that incapsulates all changes, happened in data storage.
*/
- (void)storageDidPerformUpdate:(DTStorageUpdate *)update;

@end
#import "DTStorageUpdating.h"

/**
`DTStorage` protocol is used to define common interface for storage classes.
*/

@protocol DTStorage <NSObject>
@protocol DTStorageProtocol <NSObject>

/**
Array of sections, conforming to `DTSection` protocol. Depending on data storage used, section objects may be different.
Expand All @@ -57,7 +41,7 @@
- (NSArray*)sections;

/**
Returns item at concrete indexPath. This method is used for perfomance reasons. For example, when DTCoreDataStorage is used, calling objects method will fetch all the objects from fetchRequest, bu we want to fetch only one.
Returns item at concrete indexPath. This method is used for perfomance reasons. For example, when DTCoreDataStorage is used, calling objects method will fetch all the objects from fetchRequest, but we want to fetch only one.
@param indexPath indexPath of desired item
Expand All @@ -72,6 +56,28 @@

@optional

///-----------------------------------------------------------
/// @name Setting and getting supplementary models
///-----------------------------------------------------------

/**
Getter method for header model for current section.
@param index Number of section.
@return Header model for section at index.
*/
- (id)headerModelForSectionIndex:(NSInteger)index;

/**
Getter method for footer model for current section.
@param index Number of section.
@return Footer model for section at index.
*/
- (id)footerModelForSectionIndex:(NSInteger)index;

/**
Storage class may implement this method to define supplementary models for section.
Expand All @@ -85,6 +91,10 @@
- (id)supplementaryModelOfKind:(NSString *)kind
forSectionIndex:(NSUInteger)sectionNumber;

///-----------------------------------------------------------
/// @name Searching
///-----------------------------------------------------------

/**
Method to create filtered data storage, based on current data storage and passed searchString and searchScope.
Expand Down
30 changes: 30 additions & 0 deletions DTModelStorage/Core/DTStorageUpdating.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// DTStorageUpdating.h
// DTModelStorageTests
//
// Created by Denys Telezhkin on 12.10.14.
// Copyright (c) 2014 Denys Telezhkin. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "DTStorageUpdate.h"

/**
`DTStorageUpdating` protocol is used to transfer data storage updates.
*/

@protocol DTStorageUpdating <NSObject>

/**
Transfers data storage updates. Controller, that implements this method, may react to received update by updating it's UI.
@param update `DTStorageUpdate` instance, that incapsulates all changes, happened in data storage.
*/
- (void)storageDidPerformUpdate:(DTStorageUpdate *)update;

/**
Method is called when UI needs to be fully updated for data storage changes.
*/
- (void)storageNeedsReload;

@end
9 changes: 2 additions & 7 deletions DTModelStorage/CoreData/DTCoreDataStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "DTStorage.h"
#import "DTBaseStorage.h"
#import <CoreData/CoreData.h>

/**
This class is used to provide CoreData storage. Storage object will automatically react to NSFetchResultsController changes and will call delegate with appropriate DTStorageUpdate object.
*/

@interface DTCoreDataStorage : NSObject <DTStorage,NSFetchedResultsControllerDelegate>
@interface DTCoreDataStorage : DTBaseStorage <NSFetchedResultsControllerDelegate,DTStorageProtocol>

/**
Use this method to create `DTCoreDataStorage` object with your NSFetchedResultsController.
Expand All @@ -42,11 +42,6 @@

+(instancetype)storageWithFetchResultsController:(NSFetchedResultsController *)controller;

/**
Delegate object, that gets notified about data storage updates, in this scenario - NSFetchedResultsController updates. If delegate does not implement `DTStorageUpdating` protocol, it will not get called.
*/
@property (nonatomic, weak) id <DTStorageUpdating> delegate;

/**
NSFetchedResultsController of current `DTCoreDataStorage` object.
*/
Expand Down
6 changes: 6 additions & 0 deletions DTModelStorage/CoreData/DTCoreDataStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ - (id)objectAtIndexPath:(NSIndexPath *)indexPath
return [self.fetchedResultsController objectAtIndexPath:indexPath];
}

-(id)headerModelForSectionIndex:(NSInteger)index
{
id <NSFetchedResultsSectionInfo> section = [self.fetchedResultsController sections][index];
return section.name;
}

#pragma mark - NSFetchedResultsControllerDelegate methods

- (void)startUpdate
Expand Down
40 changes: 28 additions & 12 deletions DTModelStorage/Memory/DTMemoryStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "DTStorage.h"
#import "DTBaseStorage.h"
#import "DTSectionModel.h"

/**
Expand All @@ -32,7 +32,7 @@
`DTMemoryStorage` stores data models like array of `DTSectionModel` instances. So it's basically array of sections, where each section has an array of objects, and any supplementary models, that further describe current section, and can be used, for example, like section headers and footers.
*/

@interface DTMemoryStorage : NSObject <DTStorage>
@interface DTMemoryStorage : DTBaseStorage <DTStorageProtocol>

/**
Creates `DTMemoryStorage` with default configuration.
Expand All @@ -49,10 +49,9 @@
@property (nonatomic, strong) NSMutableArray * sections;

/**
Delegate object, that gets notified about data storage updates. If delegate does not respond to optional `DTStorageUpdating` methods, it will not get called.
Property to enable/disable logging. Logging is on by default, and will print out any critical messages, that DTMemoryStorage is encountering.
*/
@property (nonatomic, weak) id <DTStorageUpdating> delegate;

@property (nonatomic, assign) BOOL loggingEnabled;
///---------------------------------------
/// @name Add items
///---------------------------------------
Expand Down Expand Up @@ -171,7 +170,30 @@
@param kind Kind of supplementary models
*/
-(void)setSupplementaries:(NSArray *)supplementaryModels forKind:(NSString *)kind;
- (void)setSupplementaries:(NSArray *)supplementaryModels forKind:(NSString *)kind;

/**
Set header models for UITableView sections. `DTSectionModel` objects are created automatically, if they don't exist already. Pass nil or empty array to this method to clear all section header models.
@param headerModels Section header models to use.
*/
- (void)setSectionHeaderModels:(NSArray *)headerModels;

/**
Set footer models for sections. `headerKind` property is used to define kind of header supplementary. `DTSectionModel` objects are created automatically, if they don't exist already. Pass nil or empty array to this method to clear all section footer models.
@param footerModels Section footer models to use.
*/
- (void)setSectionFooterModels:(NSArray *)footerModels;

/**
Remove all items in section and replace them with array of items. After replacement is done, storageNeedsReload delegate method is called.
@param items Array of models to replace current section contents
@param sectionNumber number of section
*/
- (void)setItems:(NSArray *)items forSectionIndex:(NSUInteger)sectionIndex;

///---------------------------------------
/// @name Search
Expand Down Expand Up @@ -217,10 +239,4 @@ typedef BOOL (^DTModelSearchingBlock)(id model, NSString * searchString, NSInteg
*/
-(NSIndexPath *)indexPathForItem:(id)item;

/**
Property to enable/disable logging. Logging is on by default, and will print out any critical messages, that DTMemoryStorage is encountering.
*/

@property (nonatomic, assign) BOOL loggingEnabled;

@end
38 changes: 38 additions & 0 deletions DTModelStorage/Memory/DTMemoryStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,22 @@ - (id)supplementaryModelOfKind:(NSString *)kind forSectionIndex:(NSUInteger)sect
return [sectionModel supplementaryModelOfKind:kind];
}

-(id)headerModelForSectionIndex:(NSInteger)index
{
NSAssert(self.supplementaryHeaderKind, @"supplementaryHeaderKind property was not set before calling headerModelForSectionIndex: method");

return [self supplementaryModelOfKind:self.supplementaryHeaderKind
forSectionIndex:index];
}

-(id)footerModelForSectionIndex:(NSInteger)index
{
NSAssert(self.supplementaryFooterKind, @"supplementaryFooterKind property was not set before calling footerModelForSectionIndex: method");

return [self supplementaryModelOfKind:self.supplementaryFooterKind
forSectionIndex:index];
}

- (void)setSupplementaries:(NSArray *)supplementaryModels forKind:(NSString *)kind
{
[self startUpdate];
Expand All @@ -110,6 +126,28 @@ - (void)setSupplementaries:(NSArray *)supplementaryModels forKind:(NSString *)ki
[self finishUpdate];
}

- (void)setItems:(NSArray *)items forSectionIndex:(NSUInteger)sectionIndex
{
DTSectionModel * section = [self sectionAtIndex:sectionIndex];
[section.objects removeAllObjects];
[section.objects addObjectsFromArray:items];
[self.delegate storageNeedsReload];
}

-(void)setSectionHeaderModels:(NSArray *)headerModels
{
NSAssert(self.supplementaryHeaderKind, @"Please set supplementaryHeaderKind property before setting section header models");

[self setSupplementaries:headerModels forKind:self.supplementaryHeaderKind];
}

-(void)setSectionFooterModels:(NSArray *)footerModels
{
NSAssert(self.supplementaryFooterKind, @"Please set supplementaryFooterKind property before setting section header models");

[self setSupplementaries:footerModels forKind:self.supplementaryFooterKind];
}

#pragma mark - search

- (void)setSearchingBlock:(DTModelSearchingBlock)searchingBlock
Expand Down
12 changes: 10 additions & 2 deletions DTModelStorageTests/DTModelStorageTests.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
9A7D5BC419D8A0DA0083673D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A7D5BC319D8A0DA0083673D /* UIKit.framework */; };
9A7D5BC619D8A16E0083673D /* MemoryStorageAddTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A7D5BC519D8A16E0083673D /* MemoryStorageAddTests.m */; };
9A7D5BC819D8A22C0083673D /* MemoryStorageEditTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A7D5BC719D8A22C0083673D /* MemoryStorageEditTests.m */; };
9A88F5A419EAAEFE008436C9 /* DTBaseStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A88F5A319EAAEFE008436C9 /* DTBaseStorage.m */; };
C22A88696901596441D3AB3D /* libPods-XCTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E3B33D6FFCD9F4C66024650B /* libPods-XCTests.a */; };
/* End PBXBuildFile section */

Expand All @@ -32,7 +33,7 @@
95B30BAC1861E6E300AB82AC /* [email protected] */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "[email protected]"; sourceTree = "<group>"; };
9A222BBD18670B88004481BA /* DTModelStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTModelStorage.h; sourceTree = "<group>"; };
9A222BC1186732E0004481BA /* DTSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTSection.h; sourceTree = "<group>"; };
9A222BC2186732E0004481BA /* DTStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStorage.h; sourceTree = "<group>"; };
9A222BC2186732E0004481BA /* DTStorageProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStorageProtocol.h; sourceTree = "<group>"; };
9A222BC3186732E0004481BA /* DTStorageUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStorageUpdate.h; sourceTree = "<group>"; };
9A222BC4186732E0004481BA /* DTStorageUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTStorageUpdate.m; sourceTree = "<group>"; };
9A222BC6186732E0004481BA /* DTCoreDataStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTCoreDataStorage.h; sourceTree = "<group>"; };
Expand All @@ -57,6 +58,9 @@
9A7D5BC319D8A0DA0083673D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
9A7D5BC519D8A16E0083673D /* MemoryStorageAddTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MemoryStorageAddTests.m; path = Specs/MemoryStorageAddTests.m; sourceTree = "<group>"; };
9A7D5BC719D8A22C0083673D /* MemoryStorageEditTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MemoryStorageEditTests.m; path = Specs/MemoryStorageEditTests.m; sourceTree = "<group>"; };
9A88F5A119EAA4AF008436C9 /* DTStorageUpdating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStorageUpdating.h; sourceTree = "<group>"; };
9A88F5A219EAAEFE008436C9 /* DTBaseStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTBaseStorage.h; sourceTree = "<group>"; };
9A88F5A319EAAEFE008436C9 /* DTBaseStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTBaseStorage.m; sourceTree = "<group>"; };
AA35CA2E18C483B3003858F8 /* DTMemoryStorage+UpdateWithoutAnimations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "DTMemoryStorage+UpdateWithoutAnimations.h"; path = "Utilities/DTMemoryStorage+UpdateWithoutAnimations.h"; sourceTree = "<group>"; };
AA35CA2F18C483B3003858F8 /* DTMemoryStorage+UpdateWithoutAnimations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "DTMemoryStorage+UpdateWithoutAnimations.m"; path = "Utilities/DTMemoryStorage+UpdateWithoutAnimations.m"; sourceTree = "<group>"; };
AA478957187FEFB900E51667 /* DTModelTransfer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTModelTransfer.h; path = Utilities/DTModelTransfer.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -101,10 +105,13 @@
9A222BC0186732E0004481BA /* Core */ = {
isa = PBXGroup;
children = (
9A222BC2186732E0004481BA /* DTStorage.h */,
9A88F5A119EAA4AF008436C9 /* DTStorageUpdating.h */,
9A222BC2186732E0004481BA /* DTStorageProtocol.h */,
9A222BC1186732E0004481BA /* DTSection.h */,
9A222BC3186732E0004481BA /* DTStorageUpdate.h */,
9A222BC4186732E0004481BA /* DTStorageUpdate.m */,
9A88F5A219EAAEFE008436C9 /* DTBaseStorage.h */,
9A88F5A319EAAEFE008436C9 /* DTBaseStorage.m */,
);
path = Core;
sourceTree = "<group>";
Expand Down Expand Up @@ -334,6 +341,7 @@
9A7D5BB519D860830083673D /* DTRuntimeHelper.m in Sources */,
9A7D5BC619D8A16E0083673D /* MemoryStorageAddTests.m in Sources */,
9A24F69919D949A4009DE5D4 /* SwiftClass.swift in Sources */,
9A88F5A419EAAEFE008436C9 /* DTBaseStorage.m in Sources */,
9A7D5BB419D860830083673D /* DTMemoryStorage+UpdateWithoutAnimations.m in Sources */,
9A24F69B19D94AFD009DE5D4 /* SwiftProvider.swift in Sources */,
9A24F69219D9405E009DE5D4 /* RuntimeHelperObjectiveCTests.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#import "DTMemoryStorage.h"
#import "OCMock.h"
#import "DTSectionModel.h"
#import "DTStorage.h"
#import "DTBaseStorage.h"

@interface MemoryStorageTests : XCTestCase
{
Expand Down

0 comments on commit 1550645

Please sign in to comment.