Skip to content

Commit 74a41e1

Browse files
authored
Merge pull request ResearchKit#140 from dephillipsmichael/feature/FPHS-702
feature/FPHS-702
2 parents 3c8f9a9 + c01f063 commit 74a41e1

7 files changed

Lines changed: 369 additions & 0 deletions

File tree

APCAppCore/APCAppCore.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@
309309
A7CFE4B61A8B05F4009A171C /* APCStudyOverviewCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A7CFE4B21A8B05F4009A171C /* APCStudyOverviewCollectionViewCell.m */; };
310310
A7CFE4B71A8B05F4009A171C /* APCStudyOverviewCollectionViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = A7CFE4B31A8B05F4009A171C /* APCStudyOverviewCollectionViewController.h */; };
311311
A7CFE4B81A8B05F4009A171C /* APCStudyOverviewCollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A7CFE4B41A8B05F4009A171C /* APCStudyOverviewCollectionViewController.m */; };
312+
CB37461B1D36CC3600263F34 /* NSDateCategoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CB37461A1D36CC3600263F34 /* NSDateCategoryTests.m */; };
312313
CBC2593A1C58077A0091308E /* MockAPCTasksReminderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CBC259391C58077A0091308E /* MockAPCTasksReminderManager.h */; };
313314
CBC2593B1C5838940091308E /* APCScheduleExpressionEnumeratorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F129DF1A2F78490015982C /* APCScheduleExpressionEnumeratorTests.m */; };
314315
CBD5DBF21C57FFB400AD654E /* MockAPCTasksReminderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CBD5DBF11C57FFB400AD654E /* MockAPCTasksReminderManager.m */; };
@@ -1065,6 +1066,7 @@
10651066
A7CFE4B21A8B05F4009A171C /* APCStudyOverviewCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = APCStudyOverviewCollectionViewCell.m; sourceTree = "<group>"; };
10661067
A7CFE4B31A8B05F4009A171C /* APCStudyOverviewCollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APCStudyOverviewCollectionViewController.h; sourceTree = "<group>"; };
10671068
A7CFE4B41A8B05F4009A171C /* APCStudyOverviewCollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = APCStudyOverviewCollectionViewController.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
1069+
CB37461A1D36CC3600263F34 /* NSDateCategoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDateCategoryTests.m; sourceTree = "<group>"; };
10681070
CBC259391C58077A0091308E /* MockAPCTasksReminderManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MockAPCTasksReminderManager.h; path = "Reminder Tests/MockAPCTasksReminderManager.h"; sourceTree = "<group>"; };
10691071
CBD5DBF11C57FFB400AD654E /* MockAPCTasksReminderManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MockAPCTasksReminderManager.m; path = "Reminder Tests/MockAPCTasksReminderManager.m"; sourceTree = "<group>"; };
10701072
CBD5DBF51C5806AD00AD654E /* APCTasksReminderManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = APCTasksReminderManagerTests.m; path = "Reminder Tests/APCTasksReminderManagerTests.m"; sourceTree = "<group>"; };
@@ -3074,6 +3076,7 @@
30743076
F5F129D91A2F78490015982C /* APCAppCoreTests */ = {
30753077
isa = PBXGroup;
30763078
children = (
3079+
CB37461A1D36CC3600263F34 /* NSDateCategoryTests.m */,
30773080
803237A51C6E8A6E00208365 /* APCFudgeTestsToKnowAboutSwiftByAddingASwiftTestCase.swift */,
30783081
803237A41C6E8A6900208365 /* APCAppCoreTests-Bridging-Header.h */,
30793082
CB1B241F1C57FE5A009DD367 /* Reminder Tests */,
@@ -3950,6 +3953,7 @@
39503953
FF94698E1C1A2F0D00CF7075 /* NSDateComponentsHelperTests.m in Sources */,
39513954
FF51F7D21D11F309005B64C2 /* APCUserInfoViewControllerTests.m in Sources */,
39523955
FF44E51B1C1B94A700F07DA9 /* APCTaskResultArchiverTests.m in Sources */,
3956+
CB37461B1D36CC3600263F34 /* NSDateCategoryTests.m in Sources */,
39533957
FF94698A1C1A2F0900CF7075 /* APCScheduleExpressionListSelectorTests.m in Sources */,
39543958
CBC2593B1C5838940091308E /* APCScheduleExpressionEnumeratorTests.m in Sources */,
39553959
803237A61C6E8A6E00208365 /* APCFudgeTestsToKnowAboutSwiftByAddingASwiftTestCase.swift in Sources */,

APCAppCore/APCAppCore/Library/Categories/NSDate+Helper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,9 @@ static NSUInteger const kDateHelperDaysInAWeek = 7;
245245
*/
246246
- (NSDate *) dateBySubtractingISO8601Duration: (NSString *) durationString;
247247

248+
/*
249+
* Determines the number of days between two dates
250+
*/
251+
+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime;
252+
248253
@end

APCAppCore/APCAppCore/Library/Categories/NSDate+Helper.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,5 +591,22 @@ - (NSDate *) dateBySubtractingISO8601Duration: (NSString *) durationString
591591
return result;
592592
}
593593

594+
+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
595+
{
596+
NSDate *fromDate;
597+
NSDate *toDate;
598+
599+
NSCalendar *calendar = [NSCalendar currentCalendar];
600+
601+
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
602+
interval:NULL forDate:fromDateTime];
603+
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
604+
interval:NULL forDate:toDateTime];
605+
606+
NSDateComponents *difference = [calendar components:NSCalendarUnitDay
607+
fromDate:fromDate toDate:toDate options:0];
608+
609+
return [difference day];
610+
}
594611

595612
@end

APCAppCore/APCAppCore/Library/Objects/APCTasksReminderManager.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#import <Foundation/Foundation.h>
3535
#import "APCTaskReminder.h"
36+
#import "APCTask.h"
3637

3738
// These must be reflected by NSCalendar NSCalendarUnitWeekday, except for the EveryDay value
3839
static NSUInteger const kAPCTaskReminderDayOfWeekEveryDay = 0;
@@ -81,4 +82,25 @@ static NSUInteger const kAPCTaskReminderDayOfWeekSaturday = 7;
8182
*/
8283
+ (NSString *)studyName;
8384

85+
/*
86+
* Right now there are a few conditions for determining if a task should be reminded about...
87+
*
88+
* 1) for any task, if the taskId was not in the old list, and is now in the new list
89+
* 2) for activities, if the task was completed in old, but is incomplete in new
90+
* 3) for activities, if the task is incomplete, old task is less than 3 days old, and new
91+
* task is more than 3 days old
92+
*
93+
* @param oldTaskGroups the result from reading cache BEFORE sycning from the web
94+
* @param newTaskGroups the result from reading cache AFTER sycning from the web
95+
* @param daysIncompleteToRemind the number of days that an activity can remain incomplete before it is considered "new"
96+
*
97+
* @return an array of task group objects that are considered "new" per the 3 conditions above
98+
*/
99+
+ (NSArray*)findNewTasksFromOld:(NSArray*) oldTaskGroups
100+
toNewTaskGroups:(NSArray*) newTaskGroups
101+
withActivityReminderDuration:(NSInteger) daysIncomplete;
102+
103+
+ (BOOL) isTask:(APCTask*) task
104+
olderThan:(NSInteger) days;
105+
84106
@end

APCAppCore/APCAppCore/Library/Objects/APCTasksReminderManager.m

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,4 +672,63 @@ -(BOOL)includeTaskInReminder:(APCTaskReminder *)taskReminder{
672672
return includeTask;
673673
}
674674

675+
/*********************************************************************************/
676+
#pragma mark - Task Reminder Helper For Determining "new tasks"
677+
/*********************************************************************************/
678+
679+
+ (NSArray*)findNewTasksFromOld:(NSArray*) oldTaskGroups
680+
toNewTaskGroups:(NSArray*) newTaskGroups
681+
withActivityReminderDuration:(NSInteger) daysIncomplete {
682+
683+
NSArray* oldTasks = [oldTaskGroups valueForKey:@"task"];
684+
NSMutableArray* oldTaskIds = [[oldTasks valueForKey:@"taskID"] mutableCopy];
685+
686+
NSMutableDictionary* oldTaskCompletedStatusById = [NSMutableDictionary dictionary];
687+
NSMutableDictionary* oldTaskById = [NSMutableDictionary dictionary];
688+
689+
for (APCTaskGroup* taskGroup in oldTaskGroups) {
690+
oldTaskCompletedStatusById[taskGroup.task.taskID] = @(taskGroup.isFullyCompleted);
691+
oldTaskById[taskGroup.task.taskID] = taskGroup.task;
692+
}
693+
694+
// Right now there are a few conditions for determining if a task should be reminded about...
695+
// 1) for any task, if the taskId was not in the old list, and is now in the new list
696+
// 2) for any task, if the task was completed in old, but is incomplete in new
697+
// 3) for activities, if the task is incomplete, old task is less than 3 days old, and new
698+
// task is more than 3 days old
699+
NSMutableArray* newTasks = [NSMutableArray array];
700+
for (APCTaskGroup* taskGroup in newTaskGroups) {
701+
702+
APCTask* task = taskGroup.task;
703+
704+
// Condition 1)
705+
if (![oldTaskIds containsObject:task.taskID]) {
706+
[newTasks addObject:task];
707+
}
708+
// Condition 2)
709+
else if ([oldTaskCompletedStatusById[task.taskID] boolValue] == YES &&
710+
taskGroup.isFullyCompleted == NO) {
711+
[newTasks addObject:task];
712+
}
713+
else if ([task.taskType isEqualToNumber:@(APCTaskTypeActivityTask)]) {
714+
APCTask* oldTask = oldTaskById[task.taskID];
715+
// Condition 3)
716+
if(taskGroup.isFullyCompleted == NO &&
717+
[self isTask:oldTask olderThan:daysIncomplete] == NO &&
718+
[self isTask:task olderThan:daysIncomplete] == YES) {
719+
[newTasks addObject:task];
720+
}
721+
}
722+
}
723+
724+
return newTasks;
725+
}
726+
727+
+ (BOOL) isTask:(APCTask*) task
728+
olderThan:(NSInteger) days {
729+
730+
NSInteger daysBetweenFromNow = [NSDate daysBetweenDate:task.updatedAt andDate:[NSDate date]];
731+
return daysBetweenFromNow > days;
732+
}
733+
675734
@end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// NSDateCategoryTests.m
3+
// AppCore
4+
//
5+
// Copyright (c) 2014 Apple Inc. All rights reserved.
6+
//
7+
8+
#import <UIKit/UIKit.h>
9+
#import <XCTest/XCTest.h>
10+
#import "NSDate+Helper.h"
11+
12+
13+
@interface NSDateCategoryTests : XCTestCase
14+
15+
@end
16+
17+
18+
@implementation NSDateCategoryTests
19+
20+
/** Put setup code here. This method is called before the invocation of each test method in the class. */
21+
- (void) setUp
22+
{
23+
[super setUp];
24+
}
25+
26+
/** Put teardown code here. This method is called after the invocation of each test method in the class. */
27+
- (void) tearDown
28+
{
29+
[super tearDown];
30+
}
31+
32+
- (void) testDaysBetweenDates
33+
{
34+
NSInteger daysBetween = [NSDate daysBetweenDate:[[NSDate date] dateByAddingDays:-5]
35+
andDate:[NSDate date]];
36+
XCTAssertEqual(5, daysBetween);
37+
38+
daysBetween = [NSDate daysBetweenDate:[[NSDate date] dateByAddingDays:5]
39+
andDate:[NSDate date]];
40+
XCTAssertEqual(-5, daysBetween);
41+
42+
daysBetween = [NSDate daysBetweenDate:[NSDate date]
43+
andDate:[NSDate date]];
44+
XCTAssertEqual(0, daysBetween);
45+
}
46+
47+
@end

0 commit comments

Comments
 (0)