Loading dates from core data - iphone

I have a view with lots of labels, each one corresponding to a week day and a type of task. I want to load information from core data and use that information to set each label's text.
#import "WeekViewController.h"
#implementation WeekViewController
- (void) viewDidLoad {
gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setFirstWeekday:2];
mondayMeetings = 0;
mondayPhoneCalls = 0;
mondayToDos = 0;
tuesdayMeetings = 0;
tuesdayPhoneCalls = 0;
tuesdayToDos = 0;
wednesdayMeetings = 0;
wednesdayPhoneCalls = 0;
wednesdayToDos = 0;
thursdayMeetings = 0;
thursdayPhoneCalls = 0;
thursdayToDos = 0;
fridayMeetings = 0;
fridayPhoneCalls = 0;
fridayToDos = 0;
saturdayMeetings = 0;
saturdayPhoneCalls = 0;
saturdayToDos = 0;
sundayMeetings = 0;
sundayPhoneCalls = 0;
sundayToDos = 0;
[self loadInfo:[NSDate date]];
}
- (void) loadInfo:(NSDate *)date {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(Date >= %#) AND (Date <= %#)", [self dateByMovingToBeginningOfWeek:self.selectedDate], [self dateByMovingToEndOfWeek:self.selectedDate]];
request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Task" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Date" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error = nil;
mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
}
for (int i = 0; i < [mutableFetchResults count]; i++) {
Task *aTask = (Task *)[mutableFetchResults objectAtIndex:i];
NSDateComponents *comps = [gregorian components:NSWeekdayCalendarUnit fromDate:aTask.Date];
int weekday = [comps weekday];
if (weekday == 1 && [aTask.Type isEqualToString:#"PhoneCall"]) {
mondayPhoneCalls ++;
}
}
NSLog(#"%d", mondayPhoneCalls);
for (UILabel *go in [self.view subviews]) {
if (go.tag == 1) {
go.text = [NSString stringWithFormat:#"%i", mondayPhoneCalls];
}
}
}
- (NSDate *) dateByMovingToEndOfWeek:(NSDate *)date {
unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekdayCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *parts = [gregorian components:flags fromDate:date];
[parts setWeekday:7];
[parts setHour:23];
[parts setMinute:59];
[parts setSecond:59];
return [gregorian dateFromComponents:parts];
}
- (NSDate *) dateByMovingToBeginningOfWeek:(NSDate *)date {
unsigned int flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekdayCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *parts = [gregorian components:flags fromDate:date];
[parts setWeekday:0];
[parts setHour:0];
[parts setMinute:0];
[parts setSecond:0];
return [gregorian dateFromComponents:parts];
}
#end
But it only registers a task if it's date is the current date(sunday by the way). Also can anyone think of a more efficient way to set each label's text than either having an outlet for each one, or looping through all of the view's subviews and checking their tags?
Any help much appreciated.

Your predicate is now saying "objects whose date is today's date or later AND whose date is today's date or earlier". The only objects who fulfill that requirement are the ones with today date.
For your other question, you can look at an IBOutletCollection. They are used for collections of similar objects (in your case UILabel). It's basically an NSArray of IB objects, which you can loop over and easily set their values.

Related

How to compare curent time lie between two time slot

I hava an array of NSDictionary like this.
{
id = 12;
"time_from" = "12:00";
"time_to" = "16:00";
"timing_name" = Lunch;
},
{
id = 11;
"time_from" = "08:00";
"time_to" = "12:00";
"timing_name" = BreakFast;
},
{
id = 13;
"time_from" = "09:00";
"time_to" = "10:00";
"timing_name" = Dinner;
}
Suppose my current time is 8:45 then how can we find exact dictionary using predicate if current time exit between time_from and time_to.
Actully i need a predicate.
You can try this,
NSMutableArray *testArray = [NSMutableArray array];
NSMutableDictionary *testDict = [NSMutableDictionary dictionary];
[testDict setObject:#"12:45" forKey:#"time-from"];
[testDict setObject:#"14:45" forKey:#"time-to"];
[testArray addObject:testDict];
NSPredicate *timePredicate = [NSPredicate predicateWithBlock:^BOOL(NSMutableDictionary *dict, NSDictionary *bindings) {
NSString *timeFromString = [dict objectForKey:#"time-from"];
NSString *timeToString = [dict objectForKey:#"time-from"];
// find minutes from 00-0
//get current time minutes from 00-00
return (currentTimeMinutes>startimeMinutes) && (currentTimeMinutes<=endtimeMinutes)
}];
[testArray filterUsingPredicate:timePredicate];
-(void)makeCalculation
{
NSMutableDictionary *temp=[[NSMutableDictionary alloc]init];
[temp setObject:#"13" forKey:#"id"];
[temp setObject:#"12:00" forKey:#"timeFrom"];
[temp setObject:#"16:00" forKey:#"timeTo"];
NSMutableDictionary *temp1=[[NSMutableDictionary alloc]init];
[temp1 setObject:#"13" forKey:#"id"];
[temp1 setObject:#"08:00" forKey:#"timeFrom"];
[temp1 setObject:#"12:00" forKey:#"timeTo"];
NSMutableDictionary *temp2=[[NSMutableDictionary alloc]init];
[temp2 setObject:#"13" forKey:#"id"];
[temp2 setObject:#"09:00" forKey:#"timeFrom"];
[temp2 setObject:#"10:00" forKey:#"timeTo"];
NSMutableArray *arrayOfDict=[[NSMutableArray alloc]init];
[arrayOfDict addObject:temp];
[arrayOfDict addObject:temp1];
[arrayOfDict addObject:temp2];
NSMutableArray *timeToCompare=[[NSMutableArray alloc]initWithObjects:#"8:45",#"8:45", nil];
for(int k=0;k<[arrayOfDict count];k++)
{
NSMutableDictionary *temp=[arrayOfDict objectAtIndex:k];
NSString *timeFrom=[temp objectForKey:#"timeFrom"];
NSString *timeTo=[temp objectForKey:#"timeTo"];
NSMutableArray *tempTocheck=[[NSMutableArray alloc]initWithObjects:timeFrom,timeTo, nil];
if([self isTimeClash:timeToCompare compareWith:tempTocheck])
{
NSLog(#"Time Belong in id:%#",[temp objectForKey:#"id"]);
}
}
}
-(BOOL)isTimeClash:(NSMutableArray *)timeToCheck compareWith:(NSMutableArray *)timeToCompare
{
int Start1=[self getMinitesFromTime:[timeToCheck objectAtIndex:0]];
int end1=[self getMinitesFromTime:[timeToCheck objectAtIndex:1]];
int start2=[self getMinitesFromTime:[timeToCompare objectAtIndex:0]];
int end2=[self getMinitesFromTime:[timeToCompare objectAtIndex:1]];
if(start2>=end1 || end2<=Start1)
{
NSLog(#"Clash not happeed");
return NO;
}
else
{
NSLog(#"clash hapens ");
return YES;
}
}
-(int)getMinitesFromTime:(NSString *)timeINHours
{
NSInteger hrVal1 = [(timeINHours) intValue] ;
NSArray *array1 = [timeINHours componentsSeparatedByString:#":"];
int minVal1 = [[array1 lastObject]intValue];
hrVal1 = hrVal1 *60;
minVal1 = hrVal1 + minVal1;
return minVal1;
}
Try to use this one...
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger currHr = [components hour];
NSInteger currtMin = [components minute];
NSString *startTime = #"10:00";
NSString *endTime = #"16:00";
int stHr = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int stMin = [[[startTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int enHr = [[[endTime componentsSeparatedByString:#":"] objectAtIndex:0] intValue];
int enMin = [[[endTime componentsSeparatedByString:#":"] objectAtIndex:1] intValue];
int formStTime = (stHr*60)+stMin;
int formEnTime = (enHr*60)+enMin;
int nowTime = (currHr*60)+currtMin;
if(nowTime >= formStTime && nowTime <= formEnTime)
{
// Do Some Stuff..
}
The array timings contains you array. You may want to include the time in 24 hour format for uniformity.
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"HH:mm"];
NSDate *now = [NSDate date];
__block NSString *status = nil;
[timings enumerateObjectsUsingBlock:^(NSDictionary * dict, NSUInteger idx, BOOL *stop)
{
NSDate *date1 = [dateFormatter dateFromString:dict[#"time_from"]];
NSDate *date2 = [dateFormatter dateFromString:dict[#"time_to"]];
NSDateComponents *date1Components = [[NSCalendar currentCalendar]components:NSHourCalendarUnit|NSMinuteCalendarUnit
fromDate:date1];
NSDateComponents *date2Components = [[NSCalendar currentCalendar]components:NSHourCalendarUnit|NSMinuteCalendarUnit
fromDate:date2];
NSDateComponents *nowDateComponents = [[NSCalendar currentCalendar]components:NSHourCalendarUnit|NSMinuteCalendarUnit
fromDate:now];
NSInteger fromMinutes = date1Components.hour*60+date1Components.minute;
NSInteger toMinutes = date2Components.hour*60+date2Components.minute;
NSInteger nowMinutes = nowDateComponents.hour*60+nowDateComponents.minute;
if (nowMinutes>fromMinutes && nowMinutes<toMinutes) {
status = dict[#"timing_name"];
}
}];
NSLog(#"%#",status);

How to set Alarm Every Monday, Tuesday, Wednesday

i want set alarm every day please help me
i am so confused about it from many days.
i am using this code
-(void)localNotificationWithData:(NSDate *)firDate timeinterval:(int)interval{
NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *pickerDate = firDate;
NSLog(#"%#",pickerDate);
NSDateComponents *dateComponents = [calender components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSWeekCalendarUnit)fromDate:pickerDate];
/*... here we get Weekdays throug loop....*/
int rand = arc4random()%100;
NSLog(#"%d",rand);
for (int i=0; i<[strMarkList length]; i++) {
NSString *getselectedCell=[strMarkList substringWithRange:(NSRange){i,1}];
NSLog(#"%i",[getselectedCell intValue]);
if ([getselectedCell intValue]== 0) {
[dateComponents setDay:1];
[dateComponents setWeekday:1];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 1) {
[dateComponents setDay:2];
[dateComponents setWeekday:2];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 2) {
[dateComponents setDay:3];
[dateComponents setWeekday:3];
localNofi.repeatInterval = kCFCalendarUnitWeekday+7;
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 3) {
[dateComponents setDay:4];
[dateComponents setWeekday:4];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 4) {
[dateComponents setDay:5];
[dateComponents setWeekday:5];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 5) {
[dateComponents setDay:6];
[dateComponents setWeekday:6];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}else if ([getselectedCell intValue]== 6) {
[dateComponents setDay:7];
[dateComponents setWeekday:7];
NSDate *itemDate = [calender dateFromComponents:dateComponents];
[self repeatWeekDayInterval:itemDate rand:rand];
}
}
/*.....end.....*/
// NOW LOCALNOTIFICATION FIRE
}
-(void)repeatWeekDayInterval:(NSDate *)itemDate rand:(int)rand{
if (localNofi == nil)
return;
localNofi.fireDate = itemDate;
NSLog(#"%#",itemDate);
localNofi.timeZone = [NSTimeZone defaultTimeZone];
localNofi.alertBody = #"Time To Weak Up";
localNofi.alertAction = #"View";
localNofi.soundName = #"alarm-clock-bell.caf";
localNofi.applicationIconBadgeNumber = 1;
localNofi.repeatInterval = NSWeekCalendarUnit;
identifiLclNoti = rand;
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%d",identifiLclNoti] forKey:#"identifyKey"];
localNofi.userInfo = infoDict;
NSLog(#"%#",localNofi);
[[UIApplication sharedApplication] scheduleLocalNotification:localNofi];
}
please tell me what is wrong or i stuck in this problem for many day i search many time on google but can't find any good way please do something for me
please please help me......thanks
i just saw your schedule notification code, its fine and working. Just you need to change the below to pop up local notification every week.
localNofi.repeatInterval = NSWeekdayCalendarUnit;
I have tested it on iOS 6.0 simulator, got the required results, let me know if it didn't worked you.

Manage Multiple UILocal Notification

I have created multiple UI local Notifications , say 100. I have an array of UILocalNotifications which are scheduled as:
-(void) scheduleNotification{
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self.notifications removeAllObjects];
for (int i = 0; i< [delegate.viewController.contactList count] ; i++) {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSString *name = [[delegate.viewController.contactList objectAtIndex:i]objectForKey:NAME_KEY];
NSString *birthday = [[delegate.viewController.contactList objectAtIndex:i]objectForKey:BIRTHDAY_KEY];
if (birthday) {
[formatter setDateFormat:#"MM/dd/yyyy"];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *date = [formatter dateFromString:birthday];
if (date == nil) {
[formatter setDateFormat:#"MM/dd"];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setTimeZone:[NSTimeZone systemTimeZone]];
date = [formatter dateFromString:birthday];
}
NSCalendar *gregorianEnd = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *componentsEnd = [gregorianEnd components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
componentsEnd.year = [[NSDate date] year];
date = [gregorianEnd dateFromComponents:componentsEnd];
self.alarmTime = [date dateByAddingTimeInterval:self.mTimeInterval];
localNotification.fireDate = _alarmTime;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.applicationIconBadgeNumber = 1;
NSString *itemName = #"B'day Alert!!!";
NSString *msgName = [NSString stringWithFormat:#"Celebrate %#'s B'day",name];
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:itemName,MessageKey, msgName,TitleKey, nil];
localNotification.userInfo = userDict;
localNotification.soundName = self.soundName;
localNotification.alertBody = [NSString stringWithFormat:#"Celebrate %#'s B'day",name];
[self.notifications addObject:localNotification];
}
}
}
}
I have implemented my applicationDidEnterBackground delegate as:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UILocalNotification* notification;
for (int i = 0; i< [self.settingVC.notifications count]; i++) {
notification = [self.settingVC.notifications objectAtIndex:i];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
}
Also, in didReceiveLocalNotification delegate I have this:
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSString *itemName = [notification.userInfo objectForKey:TitleKey];
NSString *messageTitle = [notification.userInfo objectForKey:MessageKey];
[self _showAlert:itemName withTitle:messageTitle];
application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
}
But the problem is that i'm not getting desired output.Any help would be appreciated. I know that at an application can have only a limited number of scheduled notifications; the system keeps the soonest-firing 64 notifications and discards the rest. So, how I will handle those 100 or more UILocalNotification?

How to use NSPredicate for fetching property having NSDate type?

I have a column in core data that stores a date (eg:2006-01-26). I used an array to store all the years by using NSDateComponents on these stored dates.(e.g.: on above date if i use NSDateComponents, I get 2006 as a year). These years are NSNumbers, and using them in my predicate I want to fetch the column which is NSDate with all Date components. And fetched records should be only of particular year. I am now confused about how I could match a year components with one of those in array, and create predicate.
- (void)viewDidLoad
{
[super viewDidLoad];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSError *error;
//AppDelegate *app = [[UIApplication sharedApplication]delegate];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Movies" inManagedObjectContext:self.managedObjectContxt];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"releaseDate" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil];
[request setSortDescriptors:sortDescriptors];
//[request setReturnsDistinctResults:YES ];
// [request setEntity:entity];
[sortDescriptors release];
[sortDescriptor release];
[request setPropertiesToFetch:[NSArray arrayWithObject:#"releaseDate"]];
NSMutableArray *arrOfdMovies = [[self.managedObjectContxt executeFetchRequest:request error:&error]mutableCopy];
[self setArrOfFetchdMovies:arrOfdMovies];
arrOfDistinctYr = [[NSMutableArray alloc]init];
NSMutableArray *temp = [[NSMutableArray alloc]init];
for (int i = 0; i<[arrOfdMovies count]; i++) {
// NSLog(#"%#",[[arrOfdMovies objectAtIndex:i] valueForKey:#"releaseDate"]);
//date to its components
NSDate *now = [[arrOfdMovies objectAtIndex:i]valueForKey:#"releaseDate"];
// Specify which units we would like to use
unsigned units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *component_s = [calendar components:units fromDate:now];
NSInteger year = [component_s year];
NSLog(#"%i", year);
// NSInteger month = [components month];
// NSInteger day = [components day];
NSNumber *num= [NSNumber numberWithInteger:year];
[temp addObject:num];
}
[self setArrOfDistinctYr:temp];
//distinct value logic.
NSSet *uniqueYrs = [NSSet setWithArray:arrOfDistinctYr];
arr = [[NSArray alloc]initWithArray:[uniqueYrs allObjects]];
//sorting
NSArray *ar = [arr sortedArrayUsingSelector:#selector(compare:)];
self.arr = ar;
[self.managedObjectContxt retain];
[request release];
}
the array "ar" contains only years in distinct and sorted manner. But data types of this array elements are "NSNumbr"
Now How can i form a predicate which will make use of this array to display records for the particular year(how to check year from date field of core data [which has date say- 2006-01-26]).
I tried in following way -
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return 2;
NSFetchRequest *requst=[[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Movies" inManagedObjectContext:self.managedObjectContxt];
[requst setEntity:entity];
requst.predicate = [NSPredicate predicateWithFormat:#"releaseDate CONTAINS%#", [arr objectAtIndex:section]];
NSError *error = nil;
NSMutableArray *array = [[self.managedObjectContxt executeFetchRequest:requst error:&error]mutableCopy];
[requst release];
return [array count];
}
Once i get this, i can display records n my viewController.
One of the way is - Knowing the year, you could get start of the year 2006-01-01 and end of the year 2006-12-31. And then filter for dates that are between them.
For creating predicates - Have a look at Predicate Guide
It has few good example, including some dealing with NSDate predicates.

How To Search For NSDate?

I have an NSDate I want to search for in my predicate. However, the timing may not be 2009-12-06 00:00:00 +0000 but may look more like 2009-12-06 3:05:90 +0000. So how can I search for any date that fits within the bounds of that day (24 hours).
Edit:
These are the related methods to the crash:
Crash is happening in this method related to the Calendar's API framework
- (void) reactToTouch:(UITouch*)touch down:(BOOL)down
{
...
if ([marks count] > 0) {
if([[marks objectAtIndex: row * 7 + column] boolValue])
[self.selectedImageView addSubview:self.dot];
else
[self.dot removeFromSuperview];
}else{
[self.dot removeFromSuperview];
}
...
}
This graph sets the graph's date and dots for the date if there is data for that date
- (NSArray*)calendarMonthView:(TKCalendarMonthView *)monthView marksFromDate:(NSDate *)startDate toDate:(NSDate *)lastDate {
NSLog(#"calendarMonthView marksFromDate toDate");
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
[request setResultType:NSDictionaryResultType];
[request setReturnsDistinctResults:YES];
[request setPropertiesToFetch :[NSArray arrayWithObject:#"timeStamp"]];
NSError *error;
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];
NSArray *tempData = [objects valueForKey:#"timeStamp"];
NSMutableArray * data1 = [NSMutableArray array];
NSCalendar * gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
[gregorian setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
NSUInteger flags = ( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit );
NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"YYYY-MM-dd HH:mm:ss Z"];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
[tempData enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSDate * date = [gregorian dateFromComponents:[gregorian components:flags fromDate:obj]];
[data1 addObject:[formatter stringFromDate:date]];
}];
self.data = data1;
// Initialise empty marks array, this will be populated with TRUE/FALSE in order for each day a marker should be placed on.
NSMutableArray *marks = [NSMutableArray array];
// Initialise calendar to current type and set the timezone to never have daylight saving
NSCalendar *cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDateComponents *comp = [cal components:(NSMonthCalendarUnit | NSMinuteCalendarUnit | NSYearCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSSecondCalendarUnit) fromDate:startDate];
NSDate *d = [cal dateFromComponents:comp];
// Init offset components to increment days in the loop by one each time
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setDay:1];
// for each date between start date and end date check if they exist in the data array
while (YES) {
// Is the date beyond the last date? If so, exit the loop.
// NSOrderedDescending = the left value is greater than the right
if ([d compare:lastDate] == NSOrderedDescending) {
break;
}
// If the date is in the data array, add it to the marks array, else don't
if ([data containsObject:[d description]]) {
[marks addObject:[NSNumber numberWithBool:YES]];
} else {
[marks addObject:[NSNumber numberWithBool:NO]];
}
// Increment day using offset components (ie, 1 day in this instance)
d = [cal dateByAddingComponents:offsetComponents toDate:d options:0];
}
[offsetComponents release];
[request release];
return [NSArray arrayWithArray:marks];
}
And finally, this is the method we came up with, that pushes to the detail view when a date is selected:
- (void)calendarMonthView:(TKCalendarMonthView *)monthView didSelectDate:(NSDate *)d {
NSLog(#"calendarMonthView didSelectDate");
NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
NSString * dateString = [formatter stringFromDate:d];
if ( [data containsObject:dateString] )
{
NSDate * searchDate = [formatter dateFromString:dateString];
NSCalendar * calendar1 = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents * dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setDay:1];
NSDate * searchDateEnd = [calendar1 dateByAddingComponents:dateComponents toDate:searchDate options:0];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Session" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate * predicate1 = [NSPredicate predicateWithFormat:#"timeStamp >= %# AND timeStamp < %#", searchDate, searchDateEnd];
[request setPredicate: predicate1];
[request setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"xxx array: %#", array);
SessionViewController *sessionViewController = [[SessionViewController alloc] initWithNibName:#"SessionViewController" bundle:nil];
self.selectedSession = (Session *)[array objectAtIndex:0];
sessionViewController.selectedSession = self.selectedSession;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM d, y"];
NSString *dateString = [dateFormatter stringFromDate:selectedSession.timeStamp];
sessionViewController.title = dateString;
sessionViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:sessionViewController animated:YES];
[sessionViewController release];
[dateFormatter release];
[sortDescriptor release];
[request release];
[sortDescriptors release];
}
}
Edit:
When I log the the dates,
The rawDate is straight session.timeStamp and dateString has a date formatter of [dateFormatter setDateFormat:#"eeee, MMM d, y"];
2011-06-27 20:13:44.936 Curl[18714:707] dateString: Monday, Jun 27, 2011
2011-06-27 20:13:44.941 Curl[18714:707] rawString: 2011-06-27 07:05:01 +0000
2011-06-27 20:13:44.961 Curl[18714:707] dateString: Thursday, Jun 23, 2011
2011-06-27 20:13:44.965 Curl[18714:707] rawString: 2011-06-23 08:12:49 +0000
2011-06-27 20:13:44.977 Curl[18714:707] dateString: Wednesday, Jun 22, 2011
2011-06-27 20:13:44.983 Curl[18714:707] rawString: 2011-06-22 21:23:08 +0000
2011-06-27 20:13:44.993 Curl[18714:707] dateString: Tuesday, Jun 21, 2011
2011-06-27 20:13:44.997 Curl[18714:707] rawString: 2011-06-22 03:23:51 +0000
2011-06-27 20:13:45.007 Curl[18714:707] dateString: Monday, Jun 20, 2011
2011-06-27 20:13:45.011 Curl[18714:707] rawString: 2011-06-21 01:03:53 +0000
2011-06-27 20:13:45.020 Curl[18714:707] dateString: Friday, Jun 17, 2011
2011-06-27 20:13:45.024 Curl[18714:707] rawString: 2011-06-18 01:03:53 +0000
Adding a day to searchDate can be done with NSDateComponents using the code below.
NSCalendar * calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents * dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setDay:1];
NSDate * searchDateEnd = [calendar dateByAddingComponents:dateComponents
toDate:searchDate
options:0];
Add this after you get the searchDate.
You might also want to change the predicate to
NSPredicate * predicate1 = [NSPredicate predicateWithFormat:#"timeStamp >= %# AND timeStamp < %#", searchDate, searchDateEnd];
Don't check for equality with the upper limit.
Edit
If you look at the code below,
if ([marks count] > 0) {
if([[marks objectAtIndex: row * 7 + column] boolValue])
[self.selectedImageView addSubview:self.dot];
else
[self.dot removeFromSuperview];
}
You don't have checks on the index and since this seems to represent values pertaining to days in a month, I would suggest you check if there is a valid value.
int size = [marks count];
if ((size > 0) && ((row * 7 + column) < size)) {
if([[marks objectAtIndex: row * 7 + column] boolValue])
[self.selectedImageView addSubview:self.dot];
else
[self.dot removeFromSuperview];
}