Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Using NSFetchedResultsController to replace our BehaviorRepository

  • Loading branch information...
commit cff2d5909dbe5ad56ad5a958c5bdb12cf5d8c963 1 parent 222e18f
Long Sun authored
View
86 DailyReview.xcodeproj/project.pbxproj
@@ -54,12 +54,13 @@
49EBB43A1537D4A5002BBF3C /* UIView+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB4391537D4A5002BBF3C /* UIView+Additions.m */; };
49EBB43D1537D4BE002BBF3C /* IntrospectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43C1537D4BE002BBF3C /* IntrospectManager.m */; };
49EBB43D1537D4BE002BBF44 /* BindingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF43 /* BindingManager.m */; };
- 49EBB43D1537D4BE002BBF4A /* BehaviorRepository.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF49 /* BehaviorRepository.m */; };
+ 49EBB43D1537D4BE002BBF4A /* BehaviorResultsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF49 /* BehaviorResultsController.m */; };
49EBB43D1537D4BE002BBF51 /* NSError+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF50 /* NSError+Additions.m */; };
49EBB43D1537D4BE002BBF54 /* NSManagedObjectContext+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF53 /* NSManagedObjectContext+Additions.m */; };
49EBB43D1537D4BE002BBF5C /* DatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF5B /* DatabaseManager.m */; };
49EBB43D1537D4BE002BBF5F /* NSDate+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF5E /* NSDate+Additions.m */; };
49EBB43D1537D4BE002BBF62 /* NSArray+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF61 /* NSArray+Additions.m */; };
+ 49EBB43D1537D4BE002BBF65 /* NSFetchedResultsController+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EBB43D1537D4BE002BBF64 /* NSFetchedResultsController+Additions.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -170,8 +171,8 @@
49EBB43D1537D4BE002BBF43 /* BindingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BindingManager.m; path = src/BindingManager.m; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF45 /* BindingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BindingManager.h; path = src/BindingManager.h; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF48 /* Macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Macros.h; path = src/Macros.h; sourceTree = "<group>"; };
- 49EBB43D1537D4BE002BBF49 /* BehaviorRepository.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BehaviorRepository.m; path = src/BehaviorRepository.m; sourceTree = "<group>"; };
- 49EBB43D1537D4BE002BBF4B /* BehaviorRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BehaviorRepository.h; path = src/BehaviorRepository.h; sourceTree = "<group>"; };
+ 49EBB43D1537D4BE002BBF49 /* BehaviorResultsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BehaviorResultsController.m; path = src/BehaviorResultsController.m; sourceTree = "<group>"; };
+ 49EBB43D1537D4BE002BBF4B /* BehaviorResultsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BehaviorResultsController.h; path = src/BehaviorResultsController.h; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF50 /* NSError+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSError+Additions.m"; path = "src/NSError+Additions.m"; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF52 /* NSError+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSError+Additions.h"; path = "src/NSError+Additions.h"; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF53 /* NSManagedObjectContext+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSManagedObjectContext+Additions.m"; path = "src/NSManagedObjectContext+Additions.m"; sourceTree = "<group>"; };
@@ -182,6 +183,8 @@
49EBB43D1537D4BE002BBF60 /* NSDate+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDate+Additions.h"; path = "src/NSDate+Additions.h"; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF61 /* NSArray+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSArray+Additions.m"; path = "src/NSArray+Additions.m"; sourceTree = "<group>"; };
49EBB43D1537D4BE002BBF63 /* NSArray+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSArray+Additions.h"; path = "src/NSArray+Additions.h"; sourceTree = "<group>"; };
+ 49EBB43D1537D4BE002BBF64 /* NSFetchedResultsController+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFetchedResultsController+Additions.m"; path = "src/NSFetchedResultsController+Additions.m"; sourceTree = "<group>"; };
+ 49EBB43D1537D4BE002BBF66 /* NSFetchedResultsController+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFetchedResultsController+Additions.h"; path = "src/NSFetchedResultsController+Additions.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -255,6 +258,8 @@
4973162515345C8F00E3E5DC /* controllers */ = {
isa = PBXGroup;
children = (
+ 49EBB43D1537D4BE002BBF49 /* BehaviorResultsController.m */,
+ 49EBB43D1537D4BE002BBF4B /* BehaviorResultsController.h */,
49A04A9715344CD90092DC4A /* AppDelegate.h */,
49A04A9815344CD90092DC4A /* AppDelegate.m */,
49CE19BE153D221E00C31041 /* MainViewController.h */,
@@ -323,7 +328,6 @@
isa = PBXGroup;
children = (
4973162615345CA000E3E5DC /* domains */,
- 49A64D0A153E8FDB0064CF90 /* repositories */,
4973162515345C8F00E3E5DC /* controllers */,
49EBB43D1537D4BE002BBF5D /* views */,
49EBB43D1537D4BE002BBF56 /* managers */,
@@ -365,15 +369,6 @@
name = others;
sourceTree = "<group>";
};
- 49A64D0A153E8FDB0064CF90 /* repositories */ = {
- isa = PBXGroup;
- children = (
- 49EBB43D1537D4BE002BBF4B /* BehaviorRepository.h */,
- 49EBB43D1537D4BE002BBF49 /* BehaviorRepository.m */,
- );
- name = repositories;
- sourceTree = "<group>";
- };
49EBB4261537D1D3002BBF3C /* lib */ = {
isa = PBXGroup;
children = (
@@ -402,24 +397,9 @@
49EBB4381537D452002BBF3C /* additions */ = {
isa = PBXGroup;
children = (
- 49EBB43D1537D4BE002BBF63 /* NSArray+Additions.h */,
- 49EBB43D1537D4BE002BBF61 /* NSArray+Additions.m */,
- 49939773153EEEF200A91E7B /* NSSet+Additions.h */,
- 49939774153EEEF200A91E7B /* NSSet+Additions.m */,
- 49EBB43D1537D4BE002BBF60 /* NSDate+Additions.h */,
- 49EBB43D1537D4BE002BBF5E /* NSDate+Additions.m */,
- 49EBB43D1537D4BE002BBF55 /* NSManagedObjectContext+Additions.h */,
- 49EBB43D1537D4BE002BBF53 /* NSManagedObjectContext+Additions.m */,
- 49CE19CC153D607E00C31041 /* NSNumber+Additions.h */,
- 49CE19CD153D607E00C31041 /* NSNumber+Additions.m */,
- 49EBB43D1537D4BE002BBF52 /* NSError+Additions.h */,
- 49EBB43D1537D4BE002BBF50 /* NSError+Additions.m */,
- 495C97FC1535ABF200EEDAFB /* UIGestureRecognizer+Blocks.h */,
- 495C97FD1535ABF200EEDAFB /* UIGestureRecognizer+Blocks.m */,
- 49EBB4141536C8B4002BBF3C /* UIView+Additions.h */,
- 49EBB4391537D4A5002BBF3C /* UIView+Additions.m */,
- 49340A8A153E8B1A006C11A1 /* UITableView+Additions.h */,
- 49340A8B153E8B1A006C11A1 /* UITableView+Additions.m */,
+ 49EBB43D1537D4BE002BBF67 /* Foundation */,
+ 49EBB43D1537D4BE002BBF68 /* UIKit */,
+ 49EBB43D1537D4BE002BBF69 /* CoreData */,
);
name = additions;
sourceTree = "<group>";
@@ -448,6 +428,47 @@
name = views;
sourceTree = "<group>";
};
+ 49EBB43D1537D4BE002BBF67 /* Foundation */ = {
+ isa = PBXGroup;
+ children = (
+ 49939774153EEEF200A91E7B /* NSSet+Additions.m */,
+ 49939773153EEEF200A91E7B /* NSSet+Additions.h */,
+ 49CE19CD153D607E00C31041 /* NSNumber+Additions.m */,
+ 49CE19CC153D607E00C31041 /* NSNumber+Additions.h */,
+ 49EBB43D1537D4BE002BBF50 /* NSError+Additions.m */,
+ 49EBB43D1537D4BE002BBF52 /* NSError+Additions.h */,
+ 49EBB43D1537D4BE002BBF5E /* NSDate+Additions.m */,
+ 49EBB43D1537D4BE002BBF60 /* NSDate+Additions.h */,
+ 49EBB43D1537D4BE002BBF61 /* NSArray+Additions.m */,
+ 49EBB43D1537D4BE002BBF63 /* NSArray+Additions.h */,
+ );
+ name = Foundation;
+ sourceTree = "<group>";
+ };
+ 49EBB43D1537D4BE002BBF68 /* UIKit */ = {
+ isa = PBXGroup;
+ children = (
+ 49EBB4391537D4A5002BBF3C /* UIView+Additions.m */,
+ 49EBB4141536C8B4002BBF3C /* UIView+Additions.h */,
+ 49340A8B153E8B1A006C11A1 /* UITableView+Additions.m */,
+ 49340A8A153E8B1A006C11A1 /* UITableView+Additions.h */,
+ 495C97FD1535ABF200EEDAFB /* UIGestureRecognizer+Blocks.m */,
+ 495C97FC1535ABF200EEDAFB /* UIGestureRecognizer+Blocks.h */,
+ );
+ name = UIKit;
+ sourceTree = "<group>";
+ };
+ 49EBB43D1537D4BE002BBF69 /* CoreData */ = {
+ isa = PBXGroup;
+ children = (
+ 49EBB43D1537D4BE002BBF53 /* NSManagedObjectContext+Additions.m */,
+ 49EBB43D1537D4BE002BBF55 /* NSManagedObjectContext+Additions.h */,
+ 49EBB43D1537D4BE002BBF64 /* NSFetchedResultsController+Additions.m */,
+ 49EBB43D1537D4BE002BBF66 /* NSFetchedResultsController+Additions.h */,
+ );
+ name = CoreData;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -603,7 +624,7 @@
49EBB43D1537D4BE002BBF44 /* BindingManager.m in Sources */,
4943CECB153AA2A600B823E7 /* DataModel.xcdatamodeld in Sources */,
4943CECF153AA48700B823E7 /* Event.m in Sources */,
- 49EBB43D1537D4BE002BBF4A /* BehaviorRepository.m in Sources */,
+ 49EBB43D1537D4BE002BBF4A /* BehaviorResultsController.m in Sources */,
497659CD153BB8DB00E0D533 /* Binding.m in Sources */,
49EBB43D1537D4BE002BBF51 /* NSError+Additions.m in Sources */,
49EBB43D1537D4BE002BBF54 /* NSManagedObjectContext+Additions.m in Sources */,
@@ -619,6 +640,7 @@
49412AA3153EA07900450C3B /* Behavior.m in Sources */,
49939775153EEEF200A91E7B /* NSSet+Additions.m in Sources */,
494B97F1153EDCDE002801F7 /* SummaryController.m in Sources */,
+ 49EBB43D1537D4BE002BBF65 /* NSFetchedResultsController+Additions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
13 src/Behavior.h
@@ -13,10 +13,12 @@
@interface Behavior : NSManagedObject
-@property (nonatomic, retain) NSString * name;
-@property (nonatomic, retain) NSNumber * rank;
-@property (nonatomic, retain) NSDate * timestamp;
-@property (nonatomic, retain) NSSet *events;
+@property(nonatomic, retain) NSString *name;
+@property(nonatomic, retain) NSNumber *rank;
+@property(nonatomic, retain) NSDate *timestamp;
+@property(nonatomic, retain) NSSet *events;
+
+@property(nonatomic, readonly) NSString *category;
- (Event *)eventForDate:(NSDate *)date;
@@ -25,8 +27,11 @@
@interface Behavior (CoreDataGeneratedAccessors)
- (void)addEventsObject:(Event *)value;
+
- (void)removeEventsObject:(Event *)value;
+
- (void)addEvents:(NSSet *)values;
+
- (void)removeEvents:(NSSet *)values;
@end
View
39 src/Behavior.m
@@ -1,15 +1,9 @@
-//
-// Behavior.m
-// DailyReview
-//
-// Created by Long Sun on 18/04/12.
-// Copyright (c) 2012 ThoughtWorks. All rights reserved.
-//
-
#import "Behavior.h"
#import "Event.h"
#import "NSSet+Additions.h"
+static NSDictionary *categoryNamesDict = nil;
+
@implementation Behavior
@dynamic name;
@@ -17,10 +11,37 @@ @implementation Behavior
@dynamic timestamp;
@dynamic events;
+@dynamic category;
+
++ (void)initialize {
+ if (!categoryNamesDict) {
+ categoryNamesDict = DICT(
+ [NSNumber numberWithInt:1], @"准一功",
+ [NSNumber numberWithInt:3], @"准三功",
+ [NSNumber numberWithInt:5], @"准五功",
+ [NSNumber numberWithInt:10], @"准十功",
+ [NSNumber numberWithInt:30], @"准三十功",
+ [NSNumber numberWithInt:50], @"准五十功",
+ [NSNumber numberWithInt:100], @"准百功",
+ [NSNumber numberWithInt:-1], @"准一过",
+ [NSNumber numberWithInt:-3], @"准三过",
+ [NSNumber numberWithInt:-5], @"准五过",
+ [NSNumber numberWithInt:-10], @"准十过",
+ [NSNumber numberWithInt:-30], @"准三十过",
+ [NSNumber numberWithInt:-50], @"准五十过",
+ [NSNumber numberWithInt:-100], @"准百过"
+ );
+ }
+}
+
- (Event *)eventForDate:(NSDate *)date {
- return [self.events first:^BOOL(Event *event) {
+ return [self.events first:^BOOL(Event *event) {
return [[event date] isEqualToDate:date];
}];
}
+- (NSString *)category {
+ return [categoryNamesDict objectForKey:self.rank];
+}
+
@end
View
19 src/BehaviorRepository.h
@@ -1,19 +0,0 @@
-#import "Behavior.h"
-
-@interface BehaviorRepository : NSObject
-
-+ (BehaviorRepository *)merits;
-
-+ (BehaviorRepository *)demerits;
-
-- (NSUInteger)categoryCount;
-
-- (NSString *)categoryForSection:(NSUInteger)section;
-
-- (NSUInteger)behaviorCountForSection:(NSUInteger)section;
-
-- (Behavior *)behaviorForIndexPath:(NSIndexPath *)indexPath;
-
-- (NSNumber *)totalRank;
-
-@end
View
139 src/BehaviorRepository.m
@@ -1,139 +0,0 @@
-#import "BehaviorRepository.h"
-#import "NSManagedObjectContext+Additions.m"
-#import "NSArray+Additions.h"
-#import "Event.h"
-
-static NSDictionary *categoryNamesDict = nil;
-
-@implementation BehaviorRepository {
- NSMutableArray *arrayOfBehaviors_;
- NSArray *categories_;
-}
-
-+ (void)initialize {
- if (!categoryNamesDict) {
- categoryNamesDict = DICT(
- [NSNumber numberWithInt:1], @"准一功",
- [NSNumber numberWithInt:3], @"准三功",
- [NSNumber numberWithInt:5], @"准五功",
- [NSNumber numberWithInt:10], @"准十功",
- [NSNumber numberWithInt:30], @"准三十功",
- [NSNumber numberWithInt:50], @"准五十功",
- [NSNumber numberWithInt:100], @"准百功",
- [NSNumber numberWithInt:-1], @"准一过",
- [NSNumber numberWithInt:-3], @"准三过",
- [NSNumber numberWithInt:-5], @"准五过",
- [NSNumber numberWithInt:-10], @"准十过",
- [NSNumber numberWithInt:-30], @"准三十过",
- [NSNumber numberWithInt:-50], @"准五十过",
- [NSNumber numberWithInt:-100], @"准百过"
- );
- }
-}
-
-+ (BehaviorRepository *)repositoryFromPredicate:(NSString *)predicate {
- NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
-
- NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Behavior"];
-
- [request setPredicate:[NSPredicate predicateWithFormat:predicate]];
- [request setSortDescriptors:Array([NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES])];
-
- __block NSArray *results;
-
- [context performBlockAndWait:^{
- results = [context executeFetchRequest:request error:nil];
- }];
-
- return [[BehaviorRepository alloc] initWithBehaviors:results];
-}
-
-+ (BehaviorRepository *)merits {
- static BehaviorRepository *merits;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- merits = [self repositoryFromPredicate:@"rank > 0"];
- });
- return merits;
-}
-
-+ (BehaviorRepository *)demerits {
- static BehaviorRepository *demerits;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- demerits = [self repositoryFromPredicate:@"rank < 0"];
- });
- return demerits;
-}
-
-- (BehaviorRepository *)initWithBehaviors:(NSArray *)behaviors {
- self = [super init];
- if (self) {
- NSArray *ranks = [behaviors valueForKeyPath:@"@distinctUnionOfObjects.rank"];
- ranks = [ranks sortedArrayUsingDescriptors:[NSArray arrayWithObject:
- [NSSortDescriptor sortDescriptorWithKey:@"absInt" ascending:YES]]];
- //TODO: I need NSArray#sortAscending NSArray#reverse
-
- categories_ = [categoryNamesDict objectsForKeys:ranks notFoundMarker:@"未知"];
-
- arrayOfBehaviors_ = [NSMutableArray new];
- for (NSNumber *rank in ranks) {
- NSArray *behaviorsInSameRank = [behaviors filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"rank = %@", rank]];
- [arrayOfBehaviors_ addObject:behaviorsInSameRank];
- }
- }
-
- return self;
-}
-
-- (NSUInteger)categoryCount {
- return [categories_ count];
-}
-
-- (NSString *)categoryForSection:(NSUInteger)section {
- return [categories_ objectAtIndex:section];
-}
-
-- (NSUInteger)behaviorCountForSection:(NSUInteger)section {
- return [(NSArray *)[arrayOfBehaviors_ objectAtIndex:section] count];
-}
-
-- (Behavior *)behaviorForIndexPath:(NSIndexPath *)indexPath {
- return [[arrayOfBehaviors_ objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
-}
-
-- (NSNumber *)totalRank {
- __block NSInteger result = 0;
- [arrayOfBehaviors_ each:^(NSArray *behaviors) {
- [behaviors each:^(id item) {
- result = result + [self totalRankForBehavior:item];
- }];
- }];
- return [NSNumber numberWithInt:result];
-}
-
-- (NSInteger)totalRankForBehavior:(Behavior *)behavior {
-
- NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
-
- NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Event"];
-
- // TODO: (Lei & Shengtao) use behavior in behavior_list, https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pCreating.html
- [request setPredicate:[NSPredicate predicateWithFormat:@"behavior=%@", behavior]];
-
- __block NSArray *results = nil;
-
- [context performBlockAndWait:^{
- results = [context executeFetchRequest:request error:nil];
- }];
-
- __block NSInteger totalRank = 0;
- [results each:^(Event * event) {
- totalRank = event.countValue * [[behavior rank] intValue];
- }];
-
- return totalRank;
-}
-
-
-@end
View
11 src/BehaviorResultsController.h
@@ -0,0 +1,11 @@
+#import "Behavior.h"
+
+@interface BehaviorResultsController : NSFetchedResultsController
+
++ (BehaviorResultsController *)sharedMeritResultsController;
+
++ (BehaviorResultsController *)sharedDemeritResultsController;
+
+- (NSNumber *)totalRank;
+
+@end
View
80 src/BehaviorResultsController.m
@@ -0,0 +1,80 @@
+#import "BehaviorResultsController.h"
+#import "NSManagedObjectContext+Additions.m"
+#import "NSArray+Additions.h"
+#import "Event.h"
+
+@implementation BehaviorResultsController
+
++ (BehaviorResultsController *)sharedMeritResultsController {
+ static dispatch_once_t onceToken;
+ static BehaviorResultsController *instance = nil;
+ dispatch_once(&onceToken, ^{
+ instance = [[self alloc] initWithPredicate:[NSPredicate predicateWithFormat:@"rank > 0"]
+ sorter:[NSSortDescriptor sortDescriptorWithKey:@"rank" ascending:YES]
+ cacheName:@"meritCache"];
+ });
+
+ return instance;
+}
+
++ (BehaviorResultsController *)sharedDemeritResultsController {
+ static dispatch_once_t onceToken;
+ static BehaviorResultsController *instance = nil;
+ dispatch_once(&onceToken, ^{
+ instance = [[self alloc] initWithPredicate:[NSPredicate predicateWithFormat:@"rank < 0"]
+ sorter:[NSSortDescriptor sortDescriptorWithKey:@"rank" ascending:NO]
+ cacheName:@"demeritCache"];
+ });
+
+ return instance;
+}
+
+- (id)initWithPredicate:(NSPredicate *)predicate sorter:(NSSortDescriptor *)sorter cacheName:(NSString *)cacheName {
+ NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Behavior"];
+ [fetchRequest setSortDescriptors:Array(sorter, [NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES])];
+ [fetchRequest setPredicate:predicate];
+
+ self = [super initWithFetchRequest:fetchRequest
+ managedObjectContext:[NSManagedObjectContext defaultContext]
+ sectionNameKeyPath:@"category"
+ cacheName:cacheName];
+ if (self) {
+ NSError *error = nil;
+ [self performFetch:&error];
+ [error handleWithDescription:@"Failed to initialize BehaviorResultsController"];
+ }
+
+ return self;
+}
+
+- (NSNumber *)totalRank {
+ __block NSInteger result = 0;
+ [[self fetchedObjects] each:^(Behavior *behavior) {
+ result = result + [self totalRankForBehavior:behavior];
+ }];
+ return [NSNumber numberWithInt:result];
+}
+
+- (NSInteger)totalRankForBehavior:(Behavior *)behavior {
+ NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
+
+ NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Event"];
+
+ // TODO: (Lei) use behavior in behavior_list, https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pCreating.html
+ [request setPredicate:[NSPredicate predicateWithFormat:@"behavior=%@", behavior]];
+
+ __block NSArray *results = nil;
+
+ [context performBlockAndWait:^{
+ results = [context executeFetchRequest:request error:nil];
+ }];
+
+ __block NSInteger totalRank = 0;
+ [results each:^(Event *event) {
+ totalRank = event.countValue * [[behavior rank] intValue];
+ }];
+
+ return totalRank;
+}
+
+@end
View
6 src/BehaviorTableViewController.h
@@ -1,8 +1,8 @@
-#import "BehaviorRepository.h"
+#import "BehaviorResultsController.h"
@interface BehaviorTableViewController : UITableViewController {
- @protected
- BehaviorRepository *repository_;
+@protected
+ BehaviorResultsController *resultsController_;
}
@end
View
29 src/BehaviorTableViewController.m
@@ -9,6 +9,7 @@
#import "NSArray+Additions.h"
#import "UITableView+Additions.h"
#import "NSDate+Additions.h"
+#import "NSFetchedResultsController+Additions.h"
@interface BehaviorTableViewController () <UITableViewAdditionDelegate>
@@ -30,9 +31,9 @@ - (void)viewDidLoad {
[super viewDidLoad];
bindingManager_ = [BindingManager new];
sectionHeaderViews_ = [NSMutableArray new];
- for (NSUInteger section = 0; section < [repository_ categoryCount]; section++) {
+ [[resultsController_ sections] each:^(id <NSFetchedResultsSectionInfo> section) {
[sectionHeaderViews_ addObject:[self buildHeaderForSection:section]];
- }
+ }];
}
- (void)viewDidUnLoad {
@@ -51,9 +52,8 @@ - (void)viewWillAppear:(BOOL)animated {
}
}
-- (BehaviorSectionHeaderView *)buildHeaderForSection:(NSUInteger)section {
- NSString *title = [repository_ categoryForSection:section];
- BehaviorSectionHeaderView *headerView = [BehaviorSectionHeaderView viewWithTitle:title];
+- (BehaviorSectionHeaderView *)buildHeaderForSection:(id <NSFetchedResultsSectionInfo>)section {
+ BehaviorSectionHeaderView *headerView = [BehaviorSectionHeaderView viewWithTitle:[section name]];
UIGestureRecognizer *recognizer = [UITapGestureRecognizer recognizerWithActionBlock:^(id theRecognizer) {
[self toggleSection:section headerView:headerView];
@@ -63,15 +63,10 @@ - (BehaviorSectionHeaderView *)buildHeaderForSection:(NSUInteger)section {
return headerView;
}
-- (void)toggleSection:(NSUInteger)section headerView:(BehaviorSectionHeaderView *)headerView {
- NSMutableArray *indexPaths = [NSMutableArray array];
- for (NSInteger i = 0; i < [repository_ behaviorCountForSection:section]; i++) {
- [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:section]];
- }
+- (void)toggleSection:(id <NSFetchedResultsSectionInfo>)section headerView:(BehaviorSectionHeaderView *)headerView {
headerView.expanded ^= YES;
-
UITableViewRowAnimation animation = UITableViewRowAnimationTop;
-
+ NSArray *indexPaths = [resultsController_ indexPathsForSection:section];
if (headerView.expanded) {
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:animation];
} else {
@@ -88,7 +83,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [BehaviorTableViewCell cell];
}
- Behavior *behavior = [repository_ behaviorForIndexPath:indexPath];
+ Behavior *behavior = [resultsController_ objectAtIndexPath:indexPath];
cell.textLabel.text = behavior.name;
Event *event = [self buildEventForBehavior:behavior];
@@ -105,11 +100,11 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
- (void)tableView:(UITableView *)tableView willRemoveCell:(UITableViewCell *)cell {
[cell removeAllGestureRecognizers];
- Behavior *behavior = [repository_ behaviorForIndexPath:[tableView indexPathForCell:cell]];
+ Behavior *behavior = [resultsController_ objectAtIndexPath:[tableView indexPathForCell:cell]];
[bindingManager_ unbindSource:[behavior eventForDate:currentDate_]];
}
- //TODO: move to domain?
+//TODO: move to domain?
- (Event *)buildEventForBehavior:(Behavior *)behavior {
if (nil == [behavior eventForDate:currentDate_]) {
NSManagedObjectContext *context = [NSManagedObjectContext defaultContext];
@@ -162,12 +157,12 @@ - (void)changeBehaviorCountFrom:(NSNumber *)oldValue to:(NSNumber *)newValue inC
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- return [repository_ categoryCount];
+ return [[resultsController_ sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([[sectionHeaderViews_ objectAtIndex:section] expanded]) {
- return [repository_ behaviorCountForSection:section];
+ return [resultsController_ numberOfObjectsInSection:section];
} else {
return 0;
}
View
6 src/DemeritController.m
@@ -5,13 +5,13 @@ @implementation DemeritController
#pragma mark - LifeCycles
- (void)viewDidLoad {
- repository_ = [BehaviorRepository demerits];
+ resultsController_ = [BehaviorResultsController sharedDemeritResultsController];
[super viewDidLoad];
}
- (void)viewDidUnload {
- repository_ = nil;
- [super viewDidUnload];
+ resultsController_ = nil;
+ [super viewDidUnload];
}
@end
View
4 src/MeritController.m
@@ -5,12 +5,12 @@ @implementation MeritController
#pragma mark - LifeCycles
- (void)viewDidLoad {
- repository_ = [BehaviorRepository merits];
+ resultsController_ = [BehaviorResultsController sharedMeritResultsController];
[super viewDidLoad];
}
- (void)viewDidUnload {
- repository_ = nil;
+ resultsController_ = nil;
[super viewDidUnload];
}
View
8 src/NSFetchedResultsController+Additions.h
@@ -0,0 +1,8 @@
+#import <CoreData/CoreData.h>
+
+@interface NSFetchedResultsController (Additions)
+
+- (NSArray *)indexPathsForSection:(id <NSFetchedResultsSectionInfo>)section;
+
+- (NSUInteger)numberOfObjectsInSection:(NSUInteger)sectionIndex;
+@end
View
16 src/NSFetchedResultsController+Additions.m
@@ -0,0 +1,16 @@
+#import "NSFetchedResultsController+Additions.h"
+#import "NSArray+Additions.h"
+
+@implementation NSFetchedResultsController (Additions)
+- (NSArray *)indexPathsForSection:(id <NSFetchedResultsSectionInfo>)section {
+ return [[section objects] map:^NSIndexPath *(id object) {
+ return [self indexPathForObject:object];
+ }];
+}
+
+- (NSUInteger)numberOfObjectsInSection:(NSUInteger)sectionIndex {
+ return [(id <NSFetchedResultsSectionInfo>) [[self sections] objectAtIndex:sectionIndex] numberOfObjects];
+}
+
+
+@end
View
16 src/SummaryController.h
@@ -1,16 +1,6 @@
-//
-// SummaryController.h
-// DailyReview
-//
-// Created by Shengtao Lei on 4/18/12.
-// Copyright (c) 2012 ThoughtWorks. All rights reserved.
-//
-
-#import <UIKit/UIKit.h>
-
@interface SummaryController : UIViewController
-@property (nonatomic, strong) IBOutlet UILabel *meritRankView;
-@property (nonatomic, strong) IBOutlet UILabel *demeritRankView;
-@property (nonatomic, strong) IBOutlet UILabel *totalRankView;
+@property(nonatomic, strong) IBOutlet UILabel *meritRankView;
+@property(nonatomic, strong) IBOutlet UILabel *demeritRankView;
+@property(nonatomic, strong) IBOutlet UILabel *totalRankView;
@end
View
20 src/SummaryController.m
@@ -1,12 +1,4 @@
-//
-// SummaryController.m
-// DailyReview
-//
-// Created by Shengtao Lei on 4/18/12.
-// Copyright (c) 2012 ThoughtWorks. All rights reserved.
-//
-
-#import "BehaviorRepository.h"
+#import "BehaviorResultsController.h"
#import "SummaryController.h"
@interface SummaryController ()
@@ -21,11 +13,11 @@ @implementation SummaryController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
- NSNumber *totalMeritRank = [[BehaviorRepository merits] totalRank];
- NSNumber *totalDemritRank = [[BehaviorRepository demerits] totalRank];
-
+ NSNumber *totalMeritRank = [[BehaviorResultsController sharedMeritResultsController] totalRank];
+ NSNumber *totalDemeritRank = [[BehaviorResultsController sharedDemeritResultsController] totalRank];
+
[meritRankView_ setText:[totalMeritRank stringValue]];
- [demeritRankView_ setText:[totalDemritRank stringValue]];
- [totalRankView_ setText:[NSString stringWithFormat:@"%d", [totalMeritRank intValue] + [totalDemritRank intValue]]];
+ [demeritRankView_ setText:[totalDemeritRank stringValue]];
+ [totalRankView_ setText:[NSString stringWithFormat:@"%d", [totalMeritRank intValue] + [totalDemeritRank intValue]]];
}
@end
View
7 todo
@@ -35,3 +35,10 @@
* swipe animation could be more fancy highlight finger touch path
* weibo?
* detail for behavior?
+
+* do we need save all coredata changes during applicationWillTerminate or applicationDidEnterBackground?
+* use NSFetchedResultsController for cache
+
+* performance testing for performance after use it half year
+
+* refactor to workspace style. extract common

0 comments on commit cff2d59

Please sign in to comment.
Something went wrong with that request. Please try again.