2
votes

I have followed following tutorial to fetch events from google calendar which is working fine. https://developers.google.com/google-apps/calendar/quickstart/ios

Now I am stuck in insert event from my iOS app so that it can be synced with web as well. Please guide me in the right direction or post some sample code.

I am using this code for authorization in viewDidLoad

// Initialize the Google Calendar API service & load existing credentials from the keychain if available.
self.service = [[GTLServiceCalendar alloc] init];
self.service.authorizer =
[GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
                                                      clientID:kClientID
                                                  clientSecret:kClientSecret];

Authorization seems fine because fetch events is working perfectly fine. But I am using following code to add an event

- (void)addAnEvent {
    // Make a new event, and show it to the user to edit
    GTLCalendarEvent *newEvent = [GTLCalendarEvent object];
    newEvent.summary = @"Sample Added Event";
    newEvent.descriptionProperty = @"Description of sample added event";

    // We'll set the start time to now, and the end time to an hour from now,
    // with a reminder 10 minutes before
    NSDate *anHourFromNow = [NSDate dateWithTimeIntervalSinceNow:60*60];
    GTLDateTime *startDateTime = [GTLDateTime dateTimeWithDate:[NSDate date]
                                                  timeZone:[NSTimeZone systemTimeZone]];
    GTLDateTime *endDateTime = [GTLDateTime dateTimeWithDate:anHourFromNow
                                                timeZone:[NSTimeZone systemTimeZone]];

    newEvent.start = [GTLCalendarEventDateTime object];
    newEvent.start.dateTime = startDateTime;

    newEvent.end = [GTLCalendarEventDateTime object];
    newEvent.end.dateTime = endDateTime;

    GTLCalendarEventReminder *reminder = [GTLCalendarEventReminder object];
    reminder.minutes = [NSNumber numberWithInteger:10];
    reminder.method = @"email";

    newEvent.reminders = [GTLCalendarEventReminders object];
    newEvent.reminders.overrides = [NSArray arrayWithObject:reminder];
    newEvent.reminders.useDefault = [NSNumber numberWithBool:NO];

    [self addEvent:newEvent];
}


- (void)addEvent:(GTLCalendarEvent *)event {
    GTLQueryCalendar *query = [GTLQueryCalendar queryForEventsInsertWithObject:event
                                                                calendarId:@"primary"];
    [self.service executeQuery:query
                  delegate:self
         didFinishSelector:@selector(displayAddEventResultWithTicket:finishedWithObject:error:)];
}

- (void)displayAddEventResultWithTicket:(GTLServiceTicket *)ticket
                 finishedWithObject:(GTLCalendarEvents *)events
                              error:(NSError *)error {
    if (error == nil) {
        NSLog(@"I think event has been added successfully!");

    } else {
        NSLog(@"ERROR : %@", error.localizedDescription);
    }
}

But I am getting the error in response "The operation couldn’t be completed. (Insufficient Permission)"

Thanks,

3
What scope do you use for authorization?Andrey Kuznetsov
Authorization code added in postMalik Boy
Do you use kGTLAuthScopeCalendarReadonly or kGTLAuthScopeCalendar somewhere in your code?Andrey Kuznetsov
Yes. For the very first time in viewDidAppear when GTMOAuth2ViewControllerTouch is created, kGTLAuthScopeCalendarReadonly is passed as scope which I think it saves for use later on.Malik Boy
See updated answer. kGTLAuthScopeCalendarReadonly - means you won't have write access. Use kGTLAuthScopeCalendar insteadAndrey Kuznetsov

3 Answers

2
votes

To add event to calendar use following method

[GTLQueryCalendar queryForEventsInsertWithObject:yourEventObject calendarId:yourCalendarId]

Also note, that you have to authorize with scope kGTLAuthScopeCalendar to have read/write access.

0
votes

I have managed to make this work. The problem is in your service authorizer.

Every time your user logs into your app the accesstoken and refreshtoken are updated, due to this you have to create a function that gets the updated values of the authorizer before sending any kind of request.

I have created a function to retrieve the updated Service Authorizer every time I need it.

Give it a try.

Cheers.

-(GTLServiceCalendar *) updateAuthService{

    GTLServiceCalendar *service = [GTLServiceCalendar new];

    GTMOAuth2Authentication *auth = [[GTMOAuth2Authentication alloc] init];

    [auth setClientID:kClientID];
    [auth setClientSecret:kClientSecret];
    [auth setUserEmail:[GIDSignIn sharedInstance].currentUser.profile.email];
    [auth setUserID:[GIDSignIn sharedInstance].currentUser.userID];
    [auth setAccessToken:[GIDSignIn sharedInstance].currentUser.authentication.accessToken];
    [auth setRefreshToken:[GIDSignIn sharedInstance].currentUser.authentication.refreshToken];
    [auth setExpirationDate: [GIDSignIn sharedInstance].currentUser.authentication.accessTokenExpirationDate];

    service.authorizer = auth;

    return service;

}
0
votes
 GTLRCalendar_Event *newEvent = [GTLRCalendar_Event new];

        newEvent.summary = [NSString stringWithFormat:@"%@(%@)", model.listingName, model.listingType];

        newEvent.colorId = @"11";

        newEvent.reminders.useDefault = [NSNumber numberWithInt:1];
  GTLRDateTime *startDateTime = [GTLRDateTime dateTimeWithDate:timingModel.availableTime];

            GTLRCalendar_EventDateTime *startEventDateTime = [GTLRCalendar_EventDateTime new];

            startEventDateTime.dateTime = startDateTime;

            newEvent.start = startEventDateTime;



            GTLRDateTime *endDateTime = [GTLRDateTime dateTimeWithDate:timingModel.closingTime];

            GTLRCalendar_EventDateTime *endEventDateTime = [GTLRCalendar_EventDateTime new];

            endEventDateTime.dateTime = endDateTime;

            newEvent.end = endEventDateTime;



            GTLRCalendarService *service = [GTLRCalendarService new];

            service.authorizer = user.authentication.fetcherAuthorizer;

            GTLRCalendarQuery_EventsInsert *query = [GTLRCalendarQuery_EventsInsert queryWithObject:newEvent calendarId:@"primary"];

            [service executeQuery:query completionHandler:^(GTLRServiceTicket * _Nonnull callbackTicket, id  _Nullable object, NSError * _Nullable callbackError) {

                NSLog(@"%@", @"executed query");

                if(callbackError  == nil)
                {
                    NSLog(@"%@", newEvent.summary);
                }
                else
                {
                    NSLog(@"%@", callbackError);
                }

            }];