I am making a call to syncWithCalendar and after events are successfully added, I get low memory warning and app terminates with "Received Low Memory" warning. The events generated and saved in calendar are more than 50. I tried using instruments but I am not able to find the code where memory leak occurs and also through live bytes that show in instruments I am not able to track the code that is causing the leak. Can anyone please help me solve this issue.
- (void)syncWithCalendar
{
#autoreleasepool {
[self deleteEventsIfExist];
NSMutableDictionary *dictionary = [util readPListData];
NSMutableArray *courses = [util getCourses];
__block NSMutableArray *lessons;
__block NSMutableDictionary *lesson;
NSString *studentID = [util getProgramDetails].studentId;
NSString *programName = [util getProgramDetails].programName;
double offset[] = {0, 0, -300, -900, -1800, -3600, -7200, -86400, -172800};
__block NSString *startDateString = #"", *endDateString = #"";
NSTimeInterval relativeOffsetValue = 0;
int index = [[dictionary objectForKey:#"event-alert-option"] intValue];
relativeOffsetValue = offset[index];
NSDateFormatter *formatter;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSString *currentDateString = [NSString stringWithFormat:#"%# 09:00:00", [formatter stringFromDate:[NSDate date]]];
[formatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
NSDate *currentDate = [formatter dateFromString:currentDateString];
EKEventStore *eventStore = [[EKEventStore alloc] init];
if([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted){
//---- codes here when user allow your app to access theirs' calendar.
dispatch_async(dispatch_get_main_queue(), ^{
// Event creation code here.
for (int i=0; i<[courses count]; i++)
{
#autoreleasepool {
lessons = [[courses objectAtIndex:i] objectForKey:#"lessons"];
for (int j=0; j<[lessons count]; j++)
{
#autoreleasepool {
lesson = [lessons objectAtIndex:j];
NSString *title = nil;
title = [NSString stringWithFormat:#"%# %#-Complete %# lesson",studentID,programName,[lesson objectForKey:#"lesson-name"]];
if ([[lesson objectForKey:#"actual-exam-date"] isEqualToString:#"00/00/0000"])
{
startDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"plan-exam-date"], #"09:00:00"];
endDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"plan-exam-date"], #"18:00:00"];
}
else
{
if ([[lesson objectForKey:#"retake-actual-date"] isEqualToString:#"00/00/0000"])
{
startDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"retake-plan-date"], #"09:00:00"];
endDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"retake-plan-date"], #"18:00:00"];
}
}
if (!([startDateString isEqualToString:#""] && [endDateString isEqualToString:#""]))
{
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title=title;
event.startDate = [formatter dateFromString:startDateString];
event.endDate = [formatter dateFromString:endDateString];
event.allDay = NO;
if (index != 0)
{
event.alarms = [NSArray arrayWithObjects:[EKAlarm alarmWithRelativeOffset:relativeOffsetValue], nil];
}
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
// Compare current date to event start date, if start date has been passed then preventing to sync with calendar
NSComparisonResult result = [event.startDate compare:currentDate];
if (result != NSOrderedAscending)
{
NSError *err = nil;
[eventStore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
if (err) {
NSLog(#"event not saved .. error = %#",err);
} else {
NSLog(#"event added successfully");
}
}
}
} // autoreleasepool
} // lessons for loop
} // autoreleasepool
} // courses for loop
[self hideModal];
});
}else
{
//----- codes here when user NOT allow your app to access the calendar.
// [self performSelectorOnMainThread:#selector(hideModal) withObject:nil waitUntilDone:NO];
}
}];
} else {
// sync calendar for <iOS6
}
} // autoreleasepool
}
- (void)deleteEventsIfExist
{
#autoreleasepool {
NSMutableArray *courses = [util getCourses];
__block NSMutableArray *lessons;
__block NSMutableDictionary *lesson;
NSString *studentID = [util getProgramDetails].studentId;
NSString *programName = [util getProgramDetails].programName;
EKEventStore* store = [[EKEventStore alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
// Event creation code here.
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow:[[NSDate distantFuture] timeIntervalSinceReferenceDate]];
NSPredicate *fetchCalendarEvents = [store predicateForEventsWithStartDate:[NSDate date] endDate:endDate calendars:store.calendars];
NSArray *allEvents = [store eventsMatchingPredicate:fetchCalendarEvents];
for (int i=0; i<[courses count]; i++)
{
#autoreleasepool {
lessons = [[courses objectAtIndex:i] objectForKey:#"lessons"];
for (int j=0; j<[lessons count]; j++)
{
#autoreleasepool {
lesson = [lessons objectAtIndex:j];
NSString *oldEventSubtitle = [NSString stringWithFormat:#"%# %#-Complete %# lesson",studentID,programName,[lesson objectForKey:#"lesson-name"]];
for (EKEvent *e in allEvents)
{
if ( [oldEventSubtitle isEqualToString:e.title])
{
NSError* error = nil;
[store removeEvent:e span:EKSpanThisEvent commit:YES error:&error];
NSLog(#"deleting events");
}
}
} // autoreleasepool
} // lessons
} // autoreleasepool
} // courses
});
} // autoreleasepool
}
It's a rough guess, but it seems the asynchronous invocations may lead to troubles.
In order to test this, just use dispatch_sync instead of dispatch_async and examine the memory consumption. If this leads to an improvement, then a solution is in sight, which involves to re-factor your current asynchronous "parallel" approach and turn it into an appropriate asynchronous "serial" approach or an complete synchronous approach.
This may also require to "serialize" all invocations of this asynchronous method:
[eventStore requestAccessToEntityType:EKEntityTypeEvent
completion:^(BOOL granted, NSError *error) {
...
}]
This is how I made a call to syncWithCalendar function
if([eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)]) {
// iOS 6 and later
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted,
NSError *error) {
if (granted){
dispatch_async(dispatch_get_main_queue(), ^{
[self syncWithCalendar];
});
} else {
// calendar access not granted
}
}];
}
And in syncWithCalendar function everything remains same except the line of code that
was creating the crash/memory issue. Below is the incorrect line of code that I was
using earlier
// wrong
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
The correct way to save event: (Note: I didn't require event identifier in my case)
// correct
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:NO error:&err];
and then use [self.eventstore commit:NULL] after all the events are saved. This stopped the crash in my case. Hope this post will
help other get the solution. Thanks !!!!
You need to clear the cache when you are receiving memory warning, use this method it will help you.
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
Related
I am working on an app, that gets a student's school lessons online and saves it to the iPhone's calendar.
Every time the lessons get updated, I want to delete all events from the calendar of the week, and then put in the updated lessons for the whole week.
I got no problems in adding the events, but sometimes the events don't get removed?
dispatch_queue_t queue = dispatch_queue_create("com.xxxxr.xxxxxx.calendar", NULL);
dispatch_async(queue, ^{
EKEventStore *eventStore = [[EKEventStore alloc] init];
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted){
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
EKCalendar *calendarIdentifier;
if ([defaults objectForKey:#"Calendar"] == nil || ![eventStore calendarWithIdentifier:[defaults objectForKey:#"Calendar"]]){
// Create Calendar if Needed
EKSource *theSource = nil;
for (EKSource *source in eventStore.sources) {
if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:#"iCloud"]) {
theSource = source;
NSLog(#"iCloud Store Source");
break;
} else {
for (EKSource *source in eventStore.sources) {
if (source.sourceType == EKSourceTypeLocal) {
theSource = source;
NSLog(#"iPhone Local Store Source");
break;
}
}
}
}
EKCalendar *cal;
cal = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
cal.title = #"xxxxxxx";
cal.source = theSource;
[eventStore saveCalendar:cal commit:YES error:nil];
NSString *calendar_id = cal.calendarIdentifier;
[defaults setObject:calendar_id forKey:#"Calendar"];
calendarIdentifier = cal;
} else {
calendarIdentifier = [eventStore calendarWithIdentifier:[defaults objectForKey:#"Calendar"]];
NSLog(#"Calendar Existed");
}
/* NOW TO WHERE THE PROBLEM LIES! */
/* FIRST DELETE ALL EVENTS OF THIS WEEK */
NSArray *arrayOfIdentitiesToDelete = [defaults objectForKey:#"eventIdentities"];
for(NSString *identifierOfEventToDelete in arrayOfIdentitiesToDelete){
EKEvent *eventToRemove = [eventStore eventWithIdentifier:identifierOfEventToDelete];
NSError *error;
[eventStore removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
}
/* Then create new events from my 'arrayOfLessons' array */
NSMutableArray *arrayOfEventIdentities = [[NSMutableArray alloc] init];
for(int dayAddingToCalendar = 0; dayAddingToCalendar < 5; dayAddingToCalendar++){
for(NSArray *arrayOfDayAddingToCalendar in [[arrayOfLessons objectAtIndex:dayAddingToCalendar] objectAtIndex:3]){
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.calendar = calendarIdentifier;
event.title = [arrayOfDayAddingToCalendar objectAtIndex:4];
event.location = [arrayOfDayAddingToCalendar objectAtIndex:1];
event.notes = [arrayOfDayAddingToCalendar objectAtIndex:0];
event.startDate = [arrayOfDayAddingToCalendar objectAtIndex:12];
event.endDate = [arrayOfDayAddingToCalendar objectAtIndex:13];
event.allDay = NO;
[eventStore saveEvent:event span:EKSpanThisEvent error:nil];
[arrayOfEventIdentities addObject:event.eventIdentifier];
}
}
[defaults setObject:arrayOfEventIdentities forKey:#"eventIdentities"];
} else {
NSLog(#"Not Granted");
}
}];
});
You are saying:
NSError *error;
[eventStore removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
So you are throwing away error-checking. Don't. Look at the error! That's what it's for. Like this:
NSError *error;
BOOL ok = [eventStore removeEvent:eventToRemove span:EKSpanThisEvent error:&error];
if (!ok)
NSLog(#"%#", error);
I am working on IOS application.Integrated Dropbox successfully and saving data as record in datastores in DropBox as well.It was fine till here.But I am unable to get data after deleting application and reinstalling it.But in one scenario I am getting data i.e,"I inserted a record in any one of the tables in datastores,after inserting that when I am trying to get data Its coming successfully".But I need to get for the first time as the app installs.If any one worked on it please help me.Thanks in advance.
-(void)dropBoxScuccessLogin:(NSString *)successString
{
if ([successString isEqualToString:#"scuccess"])
{
//appdelegate.window.rootViewController = appdelegate.splitview;
NSArray *array1=[appdelegate.datastoreManager listDatastores:nil];
NSLog(#"array is %#",array1);
if (self.account)
{
NSDate *mydate=[NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM-DD-yyyy hh:mm:ss a"];
NSString *stringFromDate = [formatter stringFromDate:mydate];
DBTable *customerTbl = [self.store getTable:#"DataSyncedOndate"];
DBRecord *task = [customerTbl insert:#{ #"SyncedDate": stringFromDate} ];
__weak DropBoxViewController *slf = self;
[self.store addObserver:self block:^ {
if (slf.store.status & (DBDatastoreIncoming | DBDatastoreOutgoing))
{
[self syncTasks];
}
}];
[self.store sync:nil];
}
}
else
{
NSLog(#"Dropbox Login faild");
}
}
- (void)syncTasks
{
NSLog(#"Self Account is in syncTasks is %#",self.account);
if (self.account)
{
NSDictionary *changed = [self.store sync:nil];
NSLog(#" Data is Synced");
// [self getDataSync];
dispatch_async(dispatch_get_main_queue(), ^{
[self retriveDataFromDB];
});
// [self performSelector:#selector(getDataSync) withObject:nil afterDelay:2.0];
}
else
{
// [alertView show];
}
}
in retriveDataFromDB method
-(void)retriveDataFromDB
{
NSLog(#"retrive from DB method called");
///////////Admin details///////////
NSMutableArray *tasks = [NSMutableArray arrayWithArray:[[self.store getTable:#"PriceList"] query:nil error:nil]];
NSLog(#"tasks count is %d",[tasks count]);
for (int k=0; k<[tasks count]; k++)
{
DBRecord *recordObj=[tasks objectAtIndex:k];
NSString *Tier1_Id =recordObj[#"Tier1"];
NSString *Tier2_Id =recordObj[#"Tier2"];
NSString *Tier3_Id =recordObj[#"Tier3"];
NSString *Code_Id =recordObj[#"Code"];
NSString *CRV_Id =recordObj[#"CRV"];
NSString *insertAdminString = [NSString stringWithFormat:#"INSERT INTO admin_Tbl(Code,Tier1,Tier2,Tier3,CRV) VALUES(\"%#\",\"%#\",\"%#\",\"%#\",\"%#\")",Code_Id,Tier1_Id,Tier2_Id,Tier3_Id,CRV_Id];
BOOL isDataadded = [appdelegate executeInsertQuery:insertAdminString];
if (isDataadded == YES)
{
NSLog(#"admin table insertrd successfully");
}
else
{
NSLog(#"admin table not insertrd successfully");
}
}
}
In Log I am getting tasks count is "0".
- (void)syncWithCalendar
{
NSMutableDictionary *dictionary = [util readPListData];
NSMutableArray *courses = [util getCourses];
__block NSMutableArray *lessons;
__block NSMutableDictionary *lesson;
NSString *studentID = [util getProgramDetails].studentId;
NSString *programName = [util getProgramDetails].programName;
__block NSString *startDateString = #"", *endDateString = #"";
NSDateFormatter *formatter;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSString *currentDateString = [NSString stringWithFormat:#"%# 09:00:00", [formatter stringFromDate:[NSDate date]]];
[formatter setDateFormat:#"MM/dd/yyyy HH:mm:ss"];
NSDate *currentDate = [formatter dateFromString:currentDateString];
self.eventstore = [[EKEventStore alloc] init];
[self.eventstore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error)
{
if (granted) {
NSLog(#"calendar access granted");
for (int i=0; i<[courses count]; i++)
{
lessons = [[courses objectAtIndex:i] objectForKey:#"lessons"];
for (int j=0; j<[lessons count]; j++)
{
lesson = [lessons objectAtIndex:j];
NSString *title = nil;
title = [NSString stringWithFormat:#"%# %#-Complete %# lesson",studentID,programName,[lesson objectForKey:#"lesson-name"]];
startDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"exam-date"], #"09:00:00"];
endDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"exam-date"], #"18:00:00"];
if (!([startDateString isEqualToString:#""] && [endDateString isEqualToString:#""]))
{
EKEvent *event = [EKEvent eventWithEventStore:self.eventstore];
event.title=title;
event.startDate = [formatter dateFromString:startDateString];
event.endDate = [formatter dateFromString:endDateString];
event.allDay = NO;
[event setCalendar:[self.eventstore defaultCalendarForNewEvents]];
NSError *err = nil;
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
//[self.eventstore saveEvent:event span:EKSpanThisEvent error:&err];
if (err) {
NSLog(#"event not saved .. error = %#",err);
} else {
NSLog(#"event added successfully");
}
}
} // lessons for loop
} // courses for loop
} else {
NSLog(#"Access not granted");
}
}];
[self.eventstore release];
[formatter release];
}
After events gets successfully added it shows:
"Received Memory Warning. Terminating in response to SpringBoard's termination"
and the app terminates. This is happening in iOS 7 device. I haven't checked it yet in iOS 6 and below. The code works fine if there are only a few events saved (30 or less) but it shows memory issue for 80 events or more on saving.
Finally I found the answer to my question. I would like to share my solution so that it can help others ....
I was specially getting the crash in iOS 7 and it was because of the below line
// wrong
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
The correct way to save event: (Note: I didn't require event identifier for my case)
// correct
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:NO error:&err];
and then use
[self.eventstore commit:NULL]
after all the events are saved.
This stopped the crash in my case.
Switching to ARC may solve the problem with memory but problems may still occur with large amount of data.
Try using #autorelease pools inside for loop as in example
for (int i=0; i<[courses count]; i++)
{
#autoreleasepool {
lessons = [[courses objectAtIndex:i] objectForKey:#"lessons"];
for (int j=0; j<[lessons count]; j++)
{
lesson = [lessons objectAtIndex:j];
NSString *title = nil;
title = [NSString stringWithFormat:#"%# %#-Complete %# lesson",studentID,programName,[lesson objectForKey:#"lesson-name"]];
startDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"exam-date"], #"09:00:00"];
endDateString = [NSString stringWithFormat:#"%# %#", [lesson objectForKey:#"exam-date"], #"18:00:00"];
if (!([startDateString isEqualToString:#""] && [endDateString isEqualToString:#""]))
{
EKEvent *event = [EKEvent eventWithEventStore:self.eventstore];
event.title=title;
event.startDate = [formatter dateFromString:startDateString];
event.endDate = [formatter dateFromString:endDateString];
event.allDay = NO;
[event setCalendar:[self.eventstore defaultCalendarForNewEvents]];
NSError *err = nil;
[self.eventstore saveEvent:event span:EKSpanThisEvent commit:YES error:&err];
//[self.eventstore saveEvent:event span:EKSpanThisEvent error:&err];
if (err) {
NSLog(#"event not saved .. error = %#",err);
} else {
NSLog(#"event added successfully");
}
}
} // lessons for loop
}//autoreleasepool
} // courses for loop
This way each for loop step will release all autorelease objects.
#upendar I also have same scenario but i am split into small chunks, I.E. Like if you have 80 events to sync take 20-20 and pause 2-5sec. between them.
autoreleasepool is good to use, But it Calendar took too much memory to execute. It will take more then 100% some time.
I bared with this issue. Really interesting one!!!
I am using the below two methods to create Events in the device calendar, Events is my managedObject class.
+ (void)createCalendarEvents:(NSArray *)eventsArray
{
EKEventStore *eventStore = [[SharedLoader sharedInstance] eventStore];
NSLog(#"eventStore: %#",eventStore);
BOOL needsToRequestAccessToEventStore = NO; // iOS 5 behavior
if ([[EKEventStore class] respondsToSelector:#selector(authorizationStatusForEntityType:)])
needsToRequestAccessToEventStore = ([EKEventStore authorizationStatusForEntityType:EKEntityTypeEvent] == EKAuthorizationStatusNotDetermined);
if (needsToRequestAccessToEventStore) {
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
for(Events *eventObject in eventsArray)
[self addEventToCalendar:eventObject forEventStoreObject:eventStore];
NSError *commitError;
if([eventStore commit:&commitError])
{
NSLog(#"Events commited to device calendar");
}
else
{
NSLog(#"Events could not be commited to device calendar: %#",[commitError localizedDescription]);
}
});
}
}];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
for(Events *eventObject in eventsArray)
[self addEventToCalendar:eventObject forEventStoreObject:eventStore];
NSError *commitError;
if([eventStore commit:&commitError])
{
NSLog(#"Events commited to device calendar");
}
else
{
NSLog(#"Events could not be commited to device calendar: %#",[commitError localizedDescription]);
}
});
}
}
+ (BOOL)addEventToCalendar:(Events *)eventObject forEventStoreObject:(EKEventStore *)eventStore
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setLocale:[NSLocale currentLocale]];
NSString *date =[NSString stringWithFormat:#"%#", eventObject.eventStartDate];
NSPredicate *predicateForEventsOndate = [eventStore predicateForEventsWithStartDate: eventObject.eventStartDate endDate:[[NSDate alloc] initWithTimeInterval:600 sinceDate:[dateFormatter dateFromString:date]] calendars:nil]; // nil will search through all calendars
NSArray *eventsOnDate = [eventStore eventsMatchingPredicate:predicateForEventsOndate];
BOOL eventExists = NO;
EKEvent *existingEvent = nil;
for (EKEvent *eventToCheck in eventsOnDate) {
if ([eventToCheck.title isEqualToString:eventObject.eventTitle]) {
eventExists = YES;
existingEvent=eventToCheck;
break;
}
}
if (eventExists == NO) {
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title =[NSString stringWithFormat:#"%#",eventObject.eventTitle];
NSLog(#"calendar event: %#", event.title);
NSDateFormatter *tempFormatter = [[NSDateFormatter alloc]init];
[tempFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[tempFormatter setLocale:[NSLocale currentLocale]];
NSString *dateandtime =[NSString stringWithFormat:#"%#",eventObject.eventStartDate];
NSLog(#"dateandtime: %#",dateandtime);
NSString *dateandtimeend =[NSString stringWithFormat:#"%#",eventObject.eventEndDate];
NSLog(#"dateandtime: %#",dateandtimeend);
event.location = [NSString stringWithFormat:#"%#",eventObject.eventVenue];;
event.startDate =[tempFormatter dateFromString:dateandtime];
event.endDate = [tempFormatter dateFromString:dateandtimeend];
event.notes =eventObject.eventPurpose;
/*[event addAlarm:[EKAlarm alarmWithAbsoluteDate:event.startDate]];
[event addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -60.0f * 24]];
[event addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -15.0f]];*/
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
if([eventStore saveEvent:event span:EKSpanThisEvent error:&err])
{
NSLog(#"New Event Saved Successfully");
return YES;
}
else
{
NSLog(#"New Event could not be saved: %# %#",[err localizedDescription],err);
return NO;
}
}
else
{
existingEvent.title =[NSString stringWithFormat:#"%#",eventObject.eventTitle];
NSLog(#"calendar event: %#", existingEvent.title);
NSDateFormatter *tempFormatter = [[NSDateFormatter alloc]init];
[tempFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[tempFormatter setLocale:[NSLocale currentLocale]];
NSString *dateandtime =[NSString stringWithFormat:#"%#",eventObject.eventStartDate];
NSLog(#"dateandtime: %#",dateandtime);
NSString *dateandtimeend =[NSString stringWithFormat:#"%#",eventObject.eventEndDate];
NSLog(#"dateandtime: %#",dateandtimeend);
existingEvent.location = [NSString stringWithFormat:#"%#",eventObject.eventVenue];;
existingEvent.startDate =[tempFormatter dateFromString:dateandtime];
existingEvent.endDate = [tempFormatter dateFromString:dateandtimeend];
existingEvent.notes =eventObject.eventPurpose;
/*[existingEvent addAlarm:[EKAlarm alarmWithAbsoluteDate:existingEvent.startDate]];
[existingEvent addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -60.0f * 24]];
[existingEvent addAlarm:[EKAlarm alarmWithRelativeOffset:60.0f * -15.0f]];*/
[existingEvent setCalendar:[eventStore defaultCalendarForNewEvents]];
NSError *err;
if([eventStore saveEvent:existingEvent span:EKSpanThisEvent error:&err])
{
NSLog(#"Old Event Updated & Saved Successfully");
return YES;
}
else
{
NSLog(#"Existing Event could not be saved: %#",[err localizedDescription]);
return NO;
}
}
}
My events are saved successfully and also I see them on the device calendar but the events are in 2001 and the events disappear after some doing some scroll in the list of events. Need help in this.
My EKEvent is not saving in my iphone 5 ios 6.1 but its saved on my ipod 6.0. and When I update my event and save it , the event is deleted.
Please help me fix it. Its it a ios bug? or just in the code?
this is my code:
- (IBAction)submitButtonPressed:(id)sender {
if (!self.eventStore) {
self.eventStore = [[[EKEventStore alloc]init]autorelease];
}
if (!self.event) {
self.event = [EKEvent eventWithEventStore:self.eventStore];
}
if ([self.eventStore respondsToSelector:#selector(requestAccessToEntityType:completion:)])
{
// the selector is available, so we must be on iOS 6 or newer
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error)
{
NSLog(#"error: %#",error);
// display error message here
}
else if (!granted)
{
NSLog(#"error: Access Denied");
// display access denied error message here
}
else
{
// access granted
if (!self.isEditing) {
[self.event setCalendar:[self.eventStore defaultCalendarForNewEvents]];
}
[self sendEvent];
}
});
}];
}
else
{
[self.event setCalendar:[self.eventStore defaultCalendarForNewEvents]];
[self sendEvent];
}
}
-(void)sendEvent {
self.event.title = self.eventModel.eventName;
self.event.location = self.eventModel.eventLocation;
self.event.notes = self.eventModel.eventDescription;
self.eventModel.date = self.datePicked;
NSString *fromTime = [NSString string];
NSString *toTime = [NSString string];
if (self.eventModel.fromTime) {
fromTime = [NSString stringWithFormat:#"%#:%#",[ self.eventModel.fromTime objectForKey:#"hour"],[self.eventModel.fromTime objectForKey:#"minute"]];
}
if (self.eventModel.toTime) {
toTime = [NSString stringWithFormat:#"%#:%#",[ self.eventModel.toTime objectForKey:#"hour"],[self.eventModel.toTime objectForKey:#"minute"]];
}
//set start date and time
NSDateFormatter *tempFormatter = [[[NSDateFormatter alloc]init] autorelease];
[tempFormatter setDateFormat:#"yyyy-MM-dd hh:mm"];
NSString *dateandtime =[NSString stringWithFormat:#"%#%#%#",self.eventModel.fromDate,#" ", fromTime];
//set end date and time
NSDateFormatter *tempFormatterTo = [[[NSDateFormatter alloc]init] autorelease];
[tempFormatterTo setDateFormat:#"yyyy-MM-dd hh:mm"];
NSString *dateandtimeTo =[NSString stringWithFormat:#"%#%#%#",self.eventModel.toDate,#" ", toTime];
self.event.startDate = [tempFormatter dateFromString:dateandtime];
self.event.endDate = [tempFormatterTo dateFromString:dateandtimeTo];
self.event.allDay = self.eventModel.allDay;
[self.eventStore saveEvent:self.event span:EKSpanFutureEvents error:&err];
}