0

Scenario:

I have an expense tracking iOS Application and I am storing expenses from a expense detail view controller into a table view (with fetched results controller) that shows the list of expenses along with the category and amount and date. I do have a date attribute in my entity "Money" which is a parent entity for either an expense or an income.

Question:

What I want is to basically categorize my expenses for a given week, a month, or year and display it as the section header title for example : (Oct 1- Oct 7, 2012) and it shows expenses amount and related stuff according to that particular week. Two buttons are provided in that view, if I would press the right button, it will increment the week by a week (Oct 1- Oct 7, 2012 now shows Oct8 - Oct 15, 2012) and similarly the left button would decrement the week by a week.

My question is how would I achieve the above mentioned. I have some pseudo code written - Any help would be appreciated.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date == %@)", dateToFilterFor];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Expense" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"SomeCacheName"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

What should be the predicate in order to filter it by a week? Also, I am thinking to have a section name in fetched result controller, but what would it be?

iDev
  • 23,310
  • 7
  • 60
  • 85
Angad Manchanda
  • 183
  • 5
  • 17
  • NSPredicate *tomorrowsData = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", day1, day2]; – iDev Nov 08 '12 at 08:16
  • @ACB thanks but that doesn't really answer my question. I need to know how do we calculate the week and put it in the predicate. You gave me a rough idea of a predicate. – Angad Manchanda Nov 08 '12 at 08:20
  • You can use NSDate and associated methods for that right? Add/Remove 7 days from both days when button is pressed. Is it there you are facing issues? – iDev Nov 08 '12 at 08:22
  • @acb I am not able to figure out how shall I accomplish that, like displaying a week (starting day - sunday in NSCalendar) and then how to increment the week by another week on press of a button and then displaying that in a predicate. Can you please answer all of that inside the code I wrote above. – Angad Manchanda Nov 08 '12 at 08:25
  • @ACB In your answer, what is day1, day2? I mean that should be a week, like start date of the week and end date of the week, right? – Angad Manchanda Nov 08 '12 at 08:27
  • Yes, that is true. I just gave a sample code. You will get a lot of them via google or SO itself. – iDev Nov 08 '12 at 08:27
  • Honestly, I couldn't find that. If you do, then post me here please unless you don't want to answer it yourself. – Angad Manchanda Nov 08 '12 at 08:29

1 Answers1

0

Assuming that user has selected Oct 1 and Oct 7,

NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"MM/dd/yyyy"];

NSString *str1 = @"10/01/2012";
NSDate *date1 = [formatter dateFromString:str1];

NSString *str2 = @"10/07/2012";
NSDate *date2 = [formatter dateFromString:str2];

Use it as,

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", date1, date2];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Expense" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"SomeCacheName"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

In order to add the dates,

int addDaysCount = 7; //try with negative values for fetching previous week.

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:addDaysCount];

NSDate *newDate1 = [[NSCalendar currentCalendar] 
                              dateByAddingComponents:dateComponents 
                                              toDate:date1 options:0];
NSDate *newDate2 = [[NSCalendar currentCalendar] 
                              dateByAddingComponents:dateComponents 
                                              toDate:date2 options:0];

Use the above predicate with newDate1 and newDate2 to fetch new expense corresponding to these dates.

If you want to get the sunday of a particular week, use NSDateComponents.

NSDateComponents *components = [NSDateComponents new]; 
components.weekday = 1;//represents sunday 
components.year = 2012; 
components.weekOfMonth = 1;
components.month = 10; //etc..

NSDate *date1 = [[NSCalendar currentCalendar] dateFromComponents: components]; 

For more details on NSDateComponents and its properties check

iDev
  • 23,310
  • 7
  • 60
  • 85
  • Thanks. I will just implement what you wrote and see if that works. – Angad Manchanda Nov 08 '12 at 08:44
  • In order to get the monday of week you can use NSDateComponents. NSDateComponents *components = [NSDateComponents new]; components.weekday = 2;//represents monday components.year = 2012; components.month = etc.. NSDate *date = [[NSCalendar currentCalendar] dateFromComponents: components]; For more details check, https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/Reference/Reference.html – iDev Nov 08 '12 at 08:46
  • My week would start from Sunday so I use setDay:1 for Sunday. – Angad Manchanda Nov 08 '12 at 08:50
  • By using the last block you can get different week start/end dates when left or right button is pressed. – iDev Nov 08 '12 at 08:55
  • I tested the code with the above, it works. I am testing it now with the increment and decrement buttons. Can you tell me how would I display the section header with the titles like this (Oct1- Oct7, 2012) ? Do I have to fill the section name key path in FRC, but with what name? – Angad Manchanda Nov 08 '12 at 08:56
  • You can get that from date1 and date2 right? Isn't it same as the current week start/end date? You can just convert to string and show as section header right? – iDev Nov 08 '12 at 08:57
  • that makes sense.I was thinking to put the section name key path in FRC because this is why it is provided, right? Like I can have income and expense sections(2 sections) in same table view with corresponding rows. Just thinking what's the right approach. – Angad Manchanda Nov 08 '12 at 09:03
  • You can do that as well. It is all about the convenience. – iDev Nov 08 '12 at 09:44
  • I am still trying it. The section name gives a confusion. As I am using two entities (expense and income). My section can be red in color displaying expense dates and another section in green color displaying income dates. Any thoughts? – Angad Manchanda Nov 09 '12 at 01:53
  • You can use the same above logic and just replace expense with income right? That should give you the income details. You can show these two details in table view as two different sections. If you are facing issues with that, post as a new question. You will get lot of solutions. – iDev Nov 09 '12 at 03:15
  • Suppose the week shows like this (Nov4, 2012 - Nov10, 2012) and I press the increment button, I see in the console, date changes to Nov11,2012 and Nov.17, 2012 which is right but if I press the increment button again, it shows the same date again (Nov 11, 2012 and Nov.17, 2012). – Angad Manchanda Nov 09 '12 at 07:31
  • Are you adding 14 in that case when you press twice? – iDev Nov 09 '12 at 07:37
  • The code should be dynamic, right. I mean I keep on pressing increment button, it should increment it by a week, right. Why would I add 14 to it, it shouldn't be hard coded. – Angad Manchanda Nov 09 '12 at 07:43
  • see this : http://stackoverflow.com/questions/13303909/display-nsdates-in-terms-of-week – Angad Manchanda Nov 09 '12 at 07:43
  • Can you tell me a solution for that? – Angad Manchanda Nov 09 '12 at 07:57