3

I have to update calendar based on response(events) from the server. I made an array to hold all the event objects and iterating it to save the events on the calendar. Its working but problem is its creating only one random event not all.

  1. I have to show all the events(most important right now).
  2. How to use background queue to update the calendar.
  3. I have to update calendar on every 5minutes, so methods must be execute on every 5 minutes in background.
  4. Making call to the server to create events when my user will loggedIn to the app, in home-page viewDidLoad method. Does calendar takes time to create events, what ll happen if user loggedIn and instantly quit the app. Calendar would be updated or not? I think the Home-page won't be load until all the events on calendar is created?

Here is the code.

- (void)calUpdateWebService
{
    NSString *urlString = @"http://www.xxxx.com";

    NSURL *url = [NSURL URLWithString:urlString];

    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];

    NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (!error)
        {
            NSDictionary *responseJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];

            NSMutableArray *eventArray = responseJson[@"result"];

            eventData = [NSMutableArray new];
            for(NSDictionary *eventDict in eventArray)
            {
                NSDictionary *eventDic =@{@"startDate":[eventDict valueForKey:@"start_date"],@"endDate":[eventDict valueForKey:@"end_date"],@"eventSlot":[eventDict valueForKey:@"slot"],@"eventTitle":[eventDict valueForKey:@"package_title"]};

                [eventData addObject:eventDic] ;
            }
            /** call method to create events**/
            [self addBooking];
        }

    }];
    [dataTask resume];
}

/** method to create events **/
-(void)addBooking
{
    EKEventStore *eventStore = [[EKEventStore alloc]init];
    [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
        if (granted)
        {
            addEventGranted =1;

            EKEvent *event =[EKEvent eventWithEventStore:eventStore];
            for (int i = 0; i<[eventData count]; ++i)
            {
                [event setTitle:[[eventData objectAtIndex:i] valueForKey:@"eventTitle"]];
                NSString *startDate = [[eventData objectAtIndex:i] valueForKey:@"startDate"];
                NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
                [dateFormatter setDateFormat:@"yyyy-MM-dd"];
                NSDate *eventStrtdate = [dateFormatter dateFromString:startDate];
                [event setStartDate:eventStrtdate];
                [event setEndDate:[[NSDate alloc]initWithTimeInterval:1200 sinceDate:event.startDate]];
                [event setCalendar:[eventStore defaultCalendarForNewEvents]];
                NSError *err;
                [eventStore saveEvent:event span:EKSpanThisEvent error:&err];
            }
        }
    }];
}@end
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Kunal Kumar
  • 1,722
  • 1
  • 17
  • 32

1 Answers1

0

The key issue is that you're instantiating your event once, before the loop, therefore updating the same event repeatedly, and you instead want to instantiate a new event within the loop:

// don't instantiate this here
//
// EKEvent *event =[EKEvent eventWithEventStore:eventStore];

for (int i = 0; i<[eventData count]; ++i) {
    // but rather do it here

    EKEvent *event = [EKEvent eventWithEventStore:eventStore];

    // now carry on updating the event and saving it
}

In terms of setting up a process whether this runs every five minutes in the background (I assume you mean while the app is not running), this is not a pattern generally possible in iOS. Apple only allows this sort of continuous background operation in a very narrow set of circumstances (navigation apps, VoIP, music apps, etc.), because this sort of pattern will kill a user's battery (imagine if all apps did this!).

See the Background Execution chapter from the App Programming Guide for iOS.

There are, though, two approaches that you can use to accomplish what you need.

  1. Background Fetch: This is discussed in the aforementioned app programming guide. You don't have control over the frequency with which the OS performs the background fetch, but it's certainly not every five minutes (more likely daily). The OS looks at how often the user uses your app, how often new data is available, whether the device is plugged in and on wifi, etc., to determine the frequency with which it checks for updates. But it accomplishes something similar to what you asked for, albeit far less frequently.

  2. Push Notifications. If you refer to the Local and Remote Notification Programming Guide, you'll see you could configure your server to push notifications to the client app, rather than the app constantly polling the server for updates every five minutes. This is more efficient design, avoiding wasteful inquiries with the server when there might not be any data.

Rob
  • 415,655
  • 72
  • 787
  • 1,044