1

I'm building a todo list with a repeting task function.

In the core data model, I have a binary attribute that I store and array with all the repeat dates.

    e.g [NSDate date], 
        [NSDate date] + 1 week, 
        [NSDate date] + 2 week, etc... 

So each todo added will have an array with repeat dates.

I need to look at all the dates (contain inside the repeat dates array) and if any of those dates is todays date, I want to get that todo and show it in a tableview.

My first though is to get all the todo's in the database, loop throw all the dates to see if any of them match todays date... but this seems quite inefficient, especially if the database contains a lot of tods..

What's the best approach here?

Thanks

BlackMouse
  • 4,442
  • 6
  • 38
  • 65
  • 1
    What have you tried? What do you mean by repeat dates? Please elaborate on your question. – Stunner Oct 17 '13 at 08:39
  • 3
    If I were going to implement this, I would have an **event** class that knows how to calculate when it occurs. Then you query an **event** instance and it returns `YES` for any date that follows the right pattern. For example _(originalDate + [0..n] weeks)_. **event** might include sub events that specify changes to the schedule or excluded dates/times. – nielsbot Oct 17 '13 at 10:20
  • 1
    You won't have to store and maintain lots of individual events in your database. – nielsbot Oct 17 '13 at 10:22
  • 2
    I went ahead and posted a sketch of how I imagine it working... – nielsbot Oct 17 '13 at 10:41

2 Answers2

3

Not really an answer, but I wrote up what I imagine a comprehensive recurring event object API to look like. I think it would be pretty easy to implement and you can easily keep it in Core Data.

// every tuesday and thursday
// every other month
// every first tuesday


@interface Event : NSManagedObject
@property ( nonatomic, copy ) NSDate * when ;
@property ( nonatomic, copy ) NSTimeInterval duration ; // set to 24hrs for all day event

@property ( nonatomic, strong ) NSArray * repeatPatterns ; // array of EventRepeatPattern. (nil/empty means non-repeating)
@property ( nonatomic, copy ) NSDate * endDate ; // when repeats should end

@property ( nonatomic, strong ) NSArray * excludedOccurrences ; // array of Event giving times main event should *not* occur (to allow deleting individual day from repeating schedule)

-(BOOL)occursOnDay:(NSDate*)day ; // does Event have an occurrence on day?

@end

enum EventRepeatWeekdayMask
{
    EventRepeatWeekday_Monday
    , EventRepeatWeekday_Tuesday
    , EventRepeatWeekday_Wednesday
    , EventRepeatWeekday_Thursday
    , EventRepeatWeekday_Friday
    , EventRepeatWeekday_Saturday
    , EventRepeatWeekday_Sunday
} ;

enum EventRepeatOrdinal
{
    EventRepeatOrdinal_First
    , EventRepeatOrdinal_Second
    , EventRepeatOrdinal_Third
    , EventRepeatOrdinal_Fourth
    , EventRepeatOrdinal_Last = -1
} ;

@interface EventRepeatPattern
+(instancetype)every:(NSDateComponents*)interval ;
+(instancetype)on:(EventRepeatWeekdayMask)mask ;
+(instancetype)on:(EventRepeatOrdinal)ordinal weekdays:(EventRepeatWeekdayMask)mask ;

-(BOOL)occursOnDay:(NSDate*)day forEvent:(Event*)event ; // given `event`, does it occur on `day` based on this repeat pattern?

@end
nielsbot
  • 15,922
  • 4
  • 48
  • 73
1

You can do that with a predicate:

[NSPredicate predicateWithFormat:@"SUBQUERY(dates, $d, $d.date BETWEEN {%@, %@}).@count > 0", dayBeginning, dayEnd];

I've assumed that the relationship between todos and dates is named dates. Here you can find how to correctly set dayBeginning and dayEnd.

Community
  • 1
  • 1
Arek Holko
  • 8,966
  • 4
  • 28
  • 46
  • Thanks for suggestions. I get the error 'Unable to parse the format string' with this: @"ANY (dates.date >= %@ AND dates.date <= %@)" – BlackMouse Oct 17 '13 at 09:55
  • 1
    @user1251004: are you performing this fetch request on a `Todo` entity? – Arek Holko Oct 17 '13 at 10:11
  • Yes, that is correct. Todo have a to-many-relationship to another entity called RepeateDates, where I store all the upcoming repeate dates – BlackMouse Oct 17 '13 at 10:13
  • Figure it out, had to do this: @"(ANY dates.date >= %@) AND (ANY dates.date <= %@)". Thanks – BlackMouse Oct 17 '13 at 10:21
  • @user1251004: I've fixed my answer by following [this answer](http://stackoverflow.com/a/2631457/1990236). – Arek Holko Oct 17 '13 at 12:58