A library that provides an API for interacting with the device's system calendars, events, reminders, and associated records.
expo-calendar
provides an API for interacting with the device's system calendars, events, reminders, and associated records.
Android Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
-
npx expo install expo-calendar
If you are installing this in an existing React Native app, start by installing expo
in your project. Then, follow the additional instructions as mentioned by the library's README under "Installation in bare React Native projects" section.
You can configure expo-calendar
using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]
). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.
{
"expo": {
"plugins": [
[
"expo-calendar",
{
"calendarPermission": "The app needs to access your calendar."
}
]
]
}
}
Name | Default | Description |
---|---|---|
calendarPermission | "Allow $(PRODUCT_NAME) to access your calendar" | Only for: iOS A string to set the |
remindersPermission | "Allow $(PRODUCT_NAME) to access your reminders" | Only for: iOS A string to set the |
Learn how to configure the native projects in the installation instructions in the expo-calendar
repository.
import { useEffect } from 'react';
import { StyleSheet, View, Text, Button, Platform } from 'react-native';
import * as Calendar from 'expo-calendar';
export default function App() {
useEffect(() => {
(async () => {
const { status } = await Calendar.requestCalendarPermissionsAsync();
if (status === 'granted') {
const calendars = await Calendar.getCalendarsAsync(Calendar.EntityTypes.EVENT);
console.log('Here are all your calendars:');
console.log({ calendars });
}
})();
}, []);
return (
<View style={styles.container}>
<Text>Calendar Module Example</Text>
<Button title="Create a new calendar" onPress={createCalendar} />
</View>
);
}
async function getDefaultCalendarSource() {
const defaultCalendar = await Calendar.getDefaultCalendarAsync();
return defaultCalendar.source;
}
async function createCalendar() {
const defaultCalendarSource =
Platform.OS === 'ios'
? await getDefaultCalendarSource()
: { isLocalAccount: true, name: 'Expo Calendar' };
const newCalendarID = await Calendar.createCalendarAsync({
title: 'Expo Calendar',
color: 'blue',
entityType: Calendar.EntityTypes.EVENT,
sourceId: defaultCalendarSource.id,
source: defaultCalendarSource,
name: 'internalCalendarName',
ownerAccount: 'personal',
accessLevel: Calendar.CalendarAccessLevel.OWNER,
});
console.log(`Your new calendar ID is: ${newCalendarID}`);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'space-around',
},
});
import * as Calendar from 'expo-calendar';
Calendar.AlarmMethod
Type: {
ALARM: string,
ALERT: string,
DEFAULT: string,
EMAIL: string,
SMS: string
}
Calendar.AttendeeRole
Type: {
ATTENDEE: string,
CHAIR: string,
NONE: string,
NON_PARTICIPANT: string,
OPTIONAL: string,
ORGANIZER: string,
PERFORMER: string,
REQUIRED: string,
SPEAKER: string,
UNKNOWN: string
}
Calendar.AttendeeStatus
Type: {
ACCEPTED: string,
COMPLETED: string,
DECLINED: string,
DELEGATED: string,
INVITED: string,
IN_PROCESS: string,
NONE: string,
PENDING: string,
TENTATIVE: string,
UNKNOWN: string
}
Calendar.AttendeeType
Type: {
GROUP: string,
NONE: string,
OPTIONAL: string,
PERSON: string,
REQUIRED: string,
RESOURCE: string,
ROOM: string,
UNKNOWN: string
}
Calendar.Availability
Type: {
BUSY: string,
FREE: string,
NOT_SUPPORTED: string,
TENTATIVE: string,
UNAVAILABLE: string
}
Calendar.CalendarAccessLevel
Type: {
CONTRIBUTOR: string,
EDITOR: string,
FREEBUSY: string,
NONE: string,
OVERRIDE: string,
OWNER: string,
READ: string,
RESPOND: string,
ROOT: string
}
Calendar.CalendarType
Type: {
BIRTHDAYS: string,
CALDAV: string,
EXCHANGE: string,
LOCAL: string,
SUBSCRIBED: string,
UNKNOWN: string
}
Calendar.EntityTypes
Type: {
EVENT: string,
REMINDER: string
}
Calendar.EventAccessLevel
Type: {
CONFIDENTIAL: string,
DEFAULT: string,
PRIVATE: string,
PUBLIC: string
}
Calendar.EventStatus
Type: {
CANCELED: string,
CONFIRMED: string,
NONE: string,
TENTATIVE: string
}
Calendar.Frequency
Type: {
DAILY: string,
MONTHLY: string,
WEEKLY: string,
YEARLY: string
}
Calendar.ReminderStatus
Type: {
COMPLETED: string,
INCOMPLETE: string
}
Calendar.SourceType
Type: {
BIRTHDAYS: string,
CALDAV: string,
EXCHANGE: string,
LOCAL: string,
MOBILEME: string,
SUBSCRIBED: string
}
useCalendarPermissions(options)
Parameter | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
Check or request permissions to access the calendar.
This uses both getCalendarPermissionsAsync
and requestCalendarPermissionsAsync
to interact
with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [status, requestPermission] = Calendar.useCalendarPermissions();
useRemindersPermissions(options)
Parameter | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
Check or request permissions to access reminders.
This uses both getRemindersPermissionsAsync
and requestRemindersPermissionsAsync
to interact
with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [status, requestPermission] = Calendar.useRemindersPermissions();
Calendar.createAttendeeAsync(eventId, details)
Parameter | Type | Description |
---|---|---|
eventId | string | ID of the event to add this attendee to. |
details (optional) | Partial<Attendee> | A map of details for the attendee to be created. Default: {} |
Creates a new attendee record and adds it to the specified event. Note that if eventId
specifies
a recurring event, this will add the attendee to every instance of the event.
Promise<string>
A string representing the ID of the newly created attendee record.
Calendar.createCalendarAsync(details)
Parameter | Type | Description |
---|---|---|
details (optional) | Partial<Calendar> | A map of details for the calendar to be created. Default: {} |
Creates a new calendar on the device, allowing events to be added later and displayed in the OS Calendar app.
Promise<string>
A string representing the ID of the newly created calendar.
Calendar.createEventAsync(calendarId, eventData)
Parameter | Type | Description |
---|---|---|
calendarId | string | ID of the calendar to create this event in. |
eventData (optional) | Omit<Partial<Event>, 'id'> | A map of details for the event to be created. Default: {} |
Creates a new event on the specified calendar.
Promise<string>
A promise which fulfils with a string representing the ID of the newly created event.
Calendar.createReminderAsync(calendarId, reminder)
Parameter | Type | Description |
---|---|---|
calendarId | null | string | ID of the calendar to create this reminder in (or |
reminder (optional) | Reminder | A map of details for the reminder to be created Default: {} |
Creates a new reminder on the specified calendar.
Promise<string>
A promise which fulfils with a string representing the ID of the newly created reminder.
Calendar.deleteAttendeeAsync(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the attendee to delete. |
Deletes an existing attendee record from the device. Use with caution.
Promise<void>
Calendar.deleteCalendarAsync(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the calendar to delete. |
Deletes an existing calendar and all associated events/reminders/attendees from the device. Use with caution.
Promise<void>
Calendar.deleteEventAsync(id, recurringEventOptions)
Parameter | Type | Description |
---|---|---|
id | string | ID of the event to be deleted. |
recurringEventOptions (optional) | RecurringEventOptions | A map of options for recurring events. Default: {} |
Deletes an existing event from the device. Use with caution.
Promise<void>
Calendar.deleteReminderAsync(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the reminder to be deleted. |
Deletes an existing reminder from the device. Use with caution.
Promise<void>
Calendar.getAttendeesForEventAsync(id, recurringEventOptions)
Parameter | Type | Description |
---|---|---|
id | string | ID of the event to return attendees for. |
recurringEventOptions (optional) | RecurringEventOptions | A map of options for recurring events. Default: {} |
Gets all attendees for a given event (or instance of a recurring event).
A promise which fulfils with an array of Attendee
associated with the
specified event.
Calendar.getCalendarPermissionsAsync()
Checks user's permissions for accessing user's calendars.
A promise that resolves to an object of type PermissionResponse
.
Calendar.getCalendarsAsync(entityType)
Parameter | Type | Description |
---|---|---|
entityType (optional) | string | iOS Only. Not required, but if defined, filters the returned calendars to
a specific entity type. Possible values are
|
Gets an array of calendar objects with details about the different calendars stored on the device.
An array of calendar objects matching the provided entity type (if provided).
Calendar.getDefaultCalendarAsync()
Gets an instance of the default calendar object.
A promise resolving to the Calendar object that is the user's default calendar.
Calendar.getEventAsync(id, recurringEventOptions)
Parameter | Type | Description |
---|---|---|
id | string | ID of the event to return. |
recurringEventOptions (optional) | RecurringEventOptions | A map of options for recurring events. Default: {} |
Returns a specific event selected by ID. If a specific instance of a recurring event is desired, the start date of this instance must also be provided, as instances of recurring events do not have their own unique and stable IDs on either iOS or Android.
A promise which fulfils with an Event
object matching the provided criteria, if one exists.
Calendar.getEventsAsync(calendarIds, startDate, endDate)
Parameter | Type | Description |
---|---|---|
calendarIds | string[] | Array of IDs of calendars to search for events in. |
startDate | Date | Beginning of time period to search for events in. |
endDate | Date | End of time period to search for events in. |
Returns all events in a given set of calendars over a specified time period. The filtering has
slightly different behavior per-platform - on iOS, all events that overlap at all with the
[startDate, endDate]
interval are returned, whereas on Android, only events that begin on or
after the startDate
and end on or before the endDate
will be returned.
A promise which fulfils with an array of Event
objects matching the search criteria.
Calendar.getReminderAsync(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the reminder to return. |
Returns a specific reminder selected by ID.
A promise which fulfils with a Reminder
matching the provided ID, if one exists.
Calendar.getRemindersAsync(calendarIds, status, startDate, endDate)
Parameter | Type | Description |
---|---|---|
calendarIds | (null | string)[] | Array of IDs of calendars to search for reminders in. |
status | null | string | One of |
startDate | Date | Beginning of time period to search for reminders in. Required if |
endDate | Date | End of time period to search for reminders in. Required if |
Returns a list of reminders matching the provided criteria. If startDate
and endDate
are defined,
returns all reminders that overlap at all with the [startDate, endDate] interval - i.e. all reminders
that end after the startDate
or begin before the endDate
.
A promise which fulfils with an array of Reminder
objects matching the search criteria.
Calendar.getRemindersPermissionsAsync()
Checks user's permissions for accessing user's reminders.
A promise that resolves to an object of type PermissionResponse
.
Calendar.getSourceAsync(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the source to return. |
Returns a specific source selected by ID.
A promise which fulfils with an array of Source
object matching the provided
ID, if one exists.
Calendar.getSourcesAsync()
A promise which fulfils with an array of Source
objects all sources for
calendars stored on the device.
Calendar.isAvailableAsync()
Returns whether the Calendar API is enabled on the current device. This does not check the app permissions.
Promise<boolean>
Async boolean
, indicating whether the Calendar API is available on the current device.
Currently, this resolves true
on iOS and Android only.
Calendar.openEventInCalendar(id)
Parameter | Type | Description |
---|---|---|
id | string | ID of the event to open. |
Sends an intent to open the specified event in the OS Calendar app.
void
Calendar.requestCalendarPermissionsAsync()
Asks the user to grant permissions for accessing user's calendars.
A promise that resolves to an object of type PermissionResponse
.
Calendar.requestRemindersPermissionsAsync()
Asks the user to grant permissions for accessing user's reminders.
A promise that resolves to an object of type PermissionResponse
.
Calendar.updateAttendeeAsync(id, details)
Parameter | Type | Description |
---|---|---|
id | string | ID of the attendee record to be updated. |
details (optional) | Partial<Attendee> | A map of properties to be updated. Default: {} |
Updates an existing attendee record. To remove a property, explicitly set it to null
in details
.
Promise<string>
Calendar.updateCalendarAsync(id, details)
Parameter | Type | Description |
---|---|---|
id | string | ID of the calendar to update. |
details (optional) | Partial<Calendar> | A map of properties to be updated. Default: {} |
Updates the provided details of an existing calendar stored on the device. To remove a property,
explicitly set it to null
in details
.
Promise<string>
Calendar.updateEventAsync(id, details, recurringEventOptions)
Parameter | Type | Description |
---|---|---|
id | string | ID of the event to be updated. |
details (optional) | Omit<Partial<Event>, 'id'> | A map of properties to be updated. Default: {} |
recurringEventOptions (optional) | RecurringEventOptions | A map of options for recurring events. Default: {} |
Updates the provided details of an existing calendar stored on the device. To remove a property,
explicitly set it to null
in details
.
Promise<string>
Calendar.updateReminderAsync(id, details)
Parameter | Type | Description |
---|---|---|
id | string | ID of the reminder to be updated. |
details (optional) | Reminder | A map of properties to be updated. Default: {} |
Updates the provided details of an existing reminder stored on the device. To remove a property,
explicitly set it to null
in details
.
Promise<string>
PermissionResponse
An object obtained by permissions get and request functions.
PermissionResponse Properties
Name | Type | Description |
---|---|---|
canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
expires | PermissionExpiration | Determines time when the permission expires. |
granted | boolean | A convenience boolean that indicates if the permission is granted. |
status | PermissionStatus | Determines the status of the permission. |
Alarm
A method for having the OS automatically remind the user about an calendar item.
Name | Type | Description |
---|---|---|
absoluteDate (optional) | string | Only for: iOS Date object or string representing an absolute time the alarm should occur.
Overrides |
method (optional) | string | Only for: Android Method of alerting the user that this alarm should use; on iOS this is always a notification.
Possible values: |
relativeOffset (optional) | number | Number of minutes from the |
structuredLocation (optional) | AlarmLocation | - |
AlarmLocation
Name | Type | Description |
---|---|---|
coords (optional) | {
latitude: number,
longitude: number
} | - |
proximity (optional) | string | - |
radius (optional) | number | - |
title (optional) | string | - |
Attendee
A person or entity that is associated with an event by being invited or fulfilling some other role.
Name | Type | Description |
---|---|---|
email (optional) | string | Only for: Android Email address of the attendee. |
id (optional) | string | Only for: Android Internal ID that represents this attendee on the device. |
isCurrentUser (optional) | boolean | Only for: iOS Indicates whether or not this attendee is the current OS user. |
name | string | Displayed name of the attendee. |
role | string | Role of the attendee at the event.
Possible values: |
status | string | Status of the attendee in relation to the event.
Possible values: |
type | string | Type of the attendee.
Possible values: |
url (optional) | string | Only for: iOS URL for the attendee. |
Calendar
A calendar record upon which events (or, on iOS, reminders) can be stored. Settings here apply to the calendar as a whole and how its events are displayed in the OS calendar app.
Name | Type | Description |
---|---|---|
accessLevel (optional) | string | Only for: Android Level of access that the user has for the calendar.
Possible values: |
allowedAttendeeTypes (optional) | string[] | Only for: Android Attendee types that this calendar supports.
Possible values: Array of |
allowedAvailabilities | string[] | Availability types that this calendar supports.
Possible values: Array of |
allowedReminders (optional) | string[] | Only for: Android Alarm methods that this calendar supports.
Possible values: Array of |
allowsModifications | boolean | Boolean value that determines whether this calendar can be modified. |
color | string | Color used to display this calendar's events. |
entityType (optional) | string | Only for: iOS Whether the calendar is used in the Calendar or Reminders OS app.
Possible values: |
id | string | Internal ID that represents this calendar on the device. |
isPrimary (optional) | boolean | Only for: Android Boolean value indicating whether this is the device's primary calendar. |
isSynced (optional) | boolean | Only for: Android Indicates whether this calendar is synced and its events stored on the device.
Unexpected behavior may occur if this is not set to |
isVisible (optional) | boolean | Only for: Android Indicates whether the OS displays events on this calendar. |
name (optional) | string | null | Only for: Android Internal system name of the calendar. |
ownerAccount (optional) | string | Only for: Android Name for the account that owns this calendar. |
source | Source | Object representing the source to be used for the calendar. |
sourceId (optional) | string | Only for: iOS ID of the source to be used for the calendar. Likely the same as the source for any other locally stored calendars. |
timeZone (optional) | string | Only for: Android Time zone for the calendar. |
title | string | Visible name of the calendar. |
type (optional) | string | Only for: iOS Type of calendar this object represents.
Possible values: |
DaysOfTheWeek
Name | Type | Description |
---|---|---|
dayOfTheWeek | DayOfTheWeek | Sunday to Saturday - |
weekNumber (optional) | number |
|
Event
An event record, or a single instance of a recurring event. On iOS, used in the Calendar app.
Name | Type | Description |
---|---|---|
accessLevel (optional) | string | Only for: Android User's access level for the event.
Possible values: |
alarms | Alarm[] | Array of Alarm objects which control automated reminders to the user. |
allDay | boolean | Whether the event is displayed as an all-day event on the calendar |
availability | string | The availability setting for the event.
Possible values: |
calendarId | string | ID of the calendar that contains this event. |
creationDate (optional) | string | Date | Only for: iOS Date when the event record was created. |
endDate | string | Date | Date object or string representing the time when the event ends. |
endTimeZone (optional) | string | Only for: Android Time zone for the event end time. |
guestsCanInviteOthers (optional) | boolean | Only for: Android Whether invited guests can invite other guests. |
guestsCanModify (optional) | boolean | Only for: Android Whether invited guests can modify the details of the event. |
guestsCanSeeGuests (optional) | boolean | Only for: Android Whether invited guests can see other guests. |
id | string | Internal ID that represents this event on the device. |
instanceId (optional) | string | Only for: Android For instances of recurring events, volatile ID representing this instance. Not guaranteed to always refer to the same instance. |
isDetached (optional) | boolean | Only for: iOS Boolean value indicating whether or not the event is a detached (modified) instance of a recurring event. |
lastModifiedDate (optional) | string | Date | Only for: iOS Date when the event record was last modified. |
location | string | Location field of the event. |
notes | string | Description or notes saved with the event. |
organizer (optional) | string | Only for: iOS Organizer of the event. |
organizerEmail (optional) | string | Only for: Android Email address of the organizer of the event. |
originalId (optional) | string | Only for: Android For detached (modified) instances of recurring events, the ID of the original recurring event. |
originalStartDate (optional) | string | Date | Only for: iOS For recurring events, the start date for the first (original) instance of the event. |
recurrenceRule | RecurrenceRule | Object representing rules for recurring or repeating events. Set to |
startDate | string | Date | Date object or string representing the time when the event starts. |
status | string | Status of the event.
Possible values: |
timeZone | string | Time zone the event is scheduled in. |
title | string | Visible name of the event. |
url (optional) | string | Only for: iOS URL for the event. |
PermissionHookOptions
Literal Type: multiple types
Acceptable values are: PermissionHookBehavior
| Options
RecurrenceRule
A recurrence rule for events or reminders, allowing the same calendar item to recur multiple times. This type is based on the iOS interface which is in turn based on the iCal RFC so you can refer to those to learn more about this potentially complex interface.
Not all of the combinations make sense. For example, when frequency is DAILY
, setting daysOfTheMonth
makes no sense.
Name | Type | Description |
---|---|---|
daysOfTheMonth (optional) | number[] | Only for: iOS The days of the month this event occurs on.
|
daysOfTheWeek (optional) | DaysOfTheWeek[] | Only for: iOS The days of the week the event should recur on. An array of |
daysOfTheYear (optional) | number[] | Only for: iOS The days of the year this event occurs on.
|
endDate (optional) | string | Date | Date on which the calendar item should stop recurring; overrides |
frequency | string | How often the calendar item should recur.
Possible values: |
interval (optional) | number | Interval at which the calendar item should recur. For example, an Default: 1 |
monthsOfTheYear (optional) | MonthOfTheYear[] | Only for: iOS The months this event occurs on.
This field is only valid for |
occurrence (optional) | number | Number of times the calendar item should recur before stopping. |
setPositions (optional) | number[] | Only for: iOS TAn array of numbers that filters which recurrences to include. For example, for an event that
recurs every Monday, passing 2 here will make it recur every other Monday.
|
weeksOfTheYear (optional) | number[] | Only for: iOS The weeks of the year this event occurs on.
|
RecurringEventOptions
Name | Type | Description |
---|---|---|
futureEvents (optional) | boolean | Whether or not future events in the recurring series should also be updated. If |
instanceStartDate (optional) | string | Date | Date object representing the start time of the desired instance, if looking for a single instance of a recurring event. If this is not provided and id represents a recurring event, the first instance of that event will be returned by default. |
Reminder
A reminder record, used in the iOS Reminders app. No direct analog on Android.
Name | Type | Description |
---|---|---|
alarms (optional) | Alarm[] | Array of Alarm objects which control automated alarms to the user about the task. |
calendarId (optional) | string | ID of the calendar that contains this reminder. |
completed (optional) | boolean | Indicates whether or not the task has been completed. |
completionDate (optional) | string | Date | Date object or string representing the date of completion, if |
creationDate (optional) | string | Date | Date when the reminder record was created. |
dueDate (optional) | string | Date | Date object or string representing the time when the reminder task is due. |
id (optional) | string | Internal ID that represents this reminder on the device. |
lastModifiedDate (optional) | string | Date | Date when the reminder record was last modified. |
location (optional) | string | Location field of the reminder |
notes (optional) | string | Description or notes saved with the reminder. |
recurrenceRule (optional) | RecurrenceRule | Object representing rules for recurring or repeated reminders. Null for one-time tasks. |
startDate (optional) | string | Date | Date object or string representing the start date of the reminder task. |
timeZone (optional) | string | Time zone the reminder is scheduled in. |
title (optional) | string | Visible name of the reminder. |
url (optional) | string | URL for the reminder. |
Source
A source account that owns a particular calendar. Expo apps will typically not need to interact with Source
objects.
Name | Type | Description |
---|---|---|
id (optional) | string | Only for: iOS Internal ID that represents this source on the device. |
isLocalAccount (optional) | boolean | Only for: Android Whether this source is the local phone account. Must be |
name | string | Name for the account that owns this calendar and was used to sync the calendar to the device. |
type | string | Type of the account that owns this calendar and was used to sync it to the device.
If |
DayOfTheWeek
DayOfTheWeek Values
Sunday
DayOfTheWeek.Sunday = 1
Monday
DayOfTheWeek.Monday = 2
Tuesday
DayOfTheWeek.Tuesday = 3
Wednesday
DayOfTheWeek.Wednesday = 4
Thursday
DayOfTheWeek.Thursday = 5
Friday
DayOfTheWeek.Friday = 6
Saturday
DayOfTheWeek.Saturday = 7
MonthOfTheYear
MonthOfTheYear Values
January
MonthOfTheYear.January = 1
February
MonthOfTheYear.February = 2
March
MonthOfTheYear.March = 3
April
MonthOfTheYear.April = 4
May
MonthOfTheYear.May = 5
June
MonthOfTheYear.June = 6
July
MonthOfTheYear.July = 7
August
MonthOfTheYear.August = 8
September
MonthOfTheYear.September = 9
October
MonthOfTheYear.October = 10
November
MonthOfTheYear.November = 11
December
MonthOfTheYear.December = 12
PermissionStatus
PermissionStatus Values
UNDETERMINED
PermissionStatus.UNDETERMINED = "undetermined"
User hasn't granted or denied the permission yet.
You must add the following permissions to your app.json inside the expo.android.permissions
array.
Android Permission | Description |
---|---|
Allows an application to read the user's calendar data. | |
Allows an application to write the user's calendar data. |
The following usage description keys are used by this library:
Info.plist Key | Description |
---|---|
A message that tells the user why the app is requesting access to the user’s calendar data. | |
A message that tells the user why the app is requesting access to the user’s reminders. |