Plugin.Maui.CalendarStore 4.1.0

dotnet add package Plugin.Maui.CalendarStore --version 4.1.0
                    
NuGet\Install-Package Plugin.Maui.CalendarStore -Version 4.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Plugin.Maui.CalendarStore" Version="4.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Plugin.Maui.CalendarStore" Version="4.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Plugin.Maui.CalendarStore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Plugin.Maui.CalendarStore --version 4.1.0
                    
#r "nuget: Plugin.Maui.CalendarStore, 4.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Plugin.Maui.CalendarStore@4.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Plugin.Maui.CalendarStore&version=4.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Plugin.Maui.CalendarStore&version=4.1.0
                    
Install as a Cake Tool

alternate text is missing from this package README image

Plugin.Maui.CalendarStore

Plugin.Maui.CalendarStore provides the ability to access the device calendar information in your .NET MAUI application.

Install Plugin

NuGet

Available on NuGet.

Install with the dotnet CLI: dotnet add package Plugin.Maui.CalendarStore, or through the NuGet Package Manager in Visual Studio.

API Usage

Plugin.Maui.CalendarStore provides the CalendarStore class that has methods to retrieve calendars, events and attendee information from the device's calendar store.

You can either use it as a static class, e.g.: CalendarStore.Default.GetCalendars() or with dependency injection: builder.Services.AddSingleton<ICalendarStore>(CalendarStore.Default);

Permissions

Before you can start using CalendarStore, you will need to request the proper permissions on each platform.

The runtime permission is automatically requested by the plugin when any of the methods is called.

iOS/macOS

For more information, please refer to the official Apple documentation.

iOS 17+

As of iOS 17, Apple has introduced a new layer of security for accessing calendar data. There is now a difference between only writing data to a calendar and obtain full access to calendar data. To use these, add the following keys to your info.plist file. When declared, the permission will be requested automatically at runtime.

<key>NSCalendarsWriteOnlyAccessUsageDescription</key>
<string>This app needs your permission to write events to your calendars. This includes creating events, but not reading, modifying or deleting events.</string>

<key>NSCalendarsFullAccessUsageDescription</key>
<string>This app needs your permission to fully manage events on your calendars. This includes reading, writing, modifying and deleting events.</string>

Remember, you always want to declare the least amount of permissions that are needed for your app. Else this might look suspicious to your users when you have something declared, but you're not using it. That means: leave out any key from above that is not applicable to your situation.

Additionally, make sure that the descriptions you provide are useful and describe why you want to access this data. Failing to do so might result in your app being rejected from the App Store.

If you also still want to support older iOS versions (prior to version 17), also follow the instructions below.

For a sandboxed macOS application, additionally you will have to add an entry to the Entitlements.plist, you will need to add the com.apple.security.personal-information.calendar key with a value of true.

See an example of a complete Entitlements.plist file below.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.personal-information.calendars</key>
    <true/>
</dict>
</plist>
iOS < 17

On iOS and macOS prior to iOS 17, add the NSCalendarsUsageDescription key to your info.plist file. When declared, the permission will be requested automatically at runtime.

<key>NSCalendarsUsageDescription</key>
<string>This app wants to access your calendars</string>

If your app supports older iOS versions than iOS 17, include this key as well as the ones described above.

Android

On Android declare the READ_CALENDAR permission in your AndroidManifest.xml file for reading calendar information. If you also want to write information, also add the WRITE_CALENDAR permission.

This should be placed in the manifest node. You can also add this through the visual editor in Visual Studio.

The runtime permission is automatically requested by the plugin when any of the methods is called.

<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
Windows

On Windows declare the Appointments permission in your Package.appxmanifest file.

This should be places in the <Capabilities> node, that is under the <Package> node.

The runtime permission is automatically requested by the plugin when any of the methods is called.

<uap:Capability Name="appointments"/>

Dependency Injection

You will first need to register the Calendars with the MauiAppBuilder following the same pattern that the .NET MAUI Essentials libraries follow.

builder.Services.AddSingleton(CalendarStore.Default);

You can then enable your classes to depend on ICalendarStore as per the following example.

public class CalendarsViewModel
{
    readonly ICalendarStore calendarStore;

    public CalendarsViewModel(ICalendarStore calendarStore)
    {
        this.calendarStore = calendarStore;
    }

    public async Task ReadCalendars()
    {
        var calendars = await calendarStore.GetCalendars();

        foreach (var c in calendars)
        {
            Console.WriteLine(c.Name);
        }
    }
}

Straight usage

Alternatively if you want to skip using the dependency injection approach you can use the Calendars.Default property.

public class CalendarsViewModel
{
    public async Task ReadCalendars()
    {
        var calendars = await CalendarStore.Default.GetCalendars();

        foreach (var c in calendars)
        {
            Console.WriteLine(c.Name);
        }
    }
}

CalendarStore

Once you have created a CalendarStore instance you can interact with it in the following ways:

Methods
IEnumerable<Calendars> GetCalendars()

Retrieves all available calendars from the device.

Calendar GetCalendar(string calendarId)

Retrieves a specific calendar from the device.

string CreateCalendar(string name, Color? color = null)

Creates a new calendar on the device with the specified name and optionally color. Returns the ID of the newly created calendar.

UpdateCalendar(string calendarId, string newName, Color? newColor = null)

Updates the calendar, specified by the unique identifier, with the given values.

IEnumerable<CalendarEvent> GetEvents(string? calendarId = null, DateTimeOffset? startDate = null, DateTimeOffset? endDate = null)

Retrieves events from a specific calendar or all calendars from the device.

CalendarEvent GetEvent(string eventId)

Retrieves a specific event from the calendar store on the device.

string CreateEvent(string calendarId, string title, string description, string location, DateTimeOffset startDateTime, DateTimeOffset endDateTime, bool isAllDay = false, Reminder[]? reminders = null)

Creates an event in the specified calendar with the provided information. Optionally, one or more reminders can be attached to the event (see Reminders). Returns the ID of the newly created event.

string CreateEvent(CalendarEvent calendarEvent)

Creates an event based on the information in the CalendarEvent object. This is basically just a convenience method that calls CreateEvent with all the unpacked information from calendarEvent. Returns the ID of the newly created event.

string CreateAllDayEvent(string calendarId, string title, string description, string location, DateTimeOffset startDate, DateTimeOffset endDate)

Creates an all-day event in the specified calendar with the provided information. This is basically just a convenience method that calls CreateEvent with isAllDay set to true. Returns the ID of the newly created event.

UpdateEvent(string eventId, string title, string description, string location, DateTimeOffset startDateTime, DateTimeOffset endDateTime, bool isAllDay, Reminder[]? reminders = null)

Updates an event, specified by the unique identifier, on the device calendar. If reminders is provided, all existing reminders on the event will be replaced with the ones in the provided collection. If reminders is null, all existing reminders will be cleared.

UpdateEvent(CalendarEvent eventToUpdate)

Updates an event on the device calendar. This is basically just a convenience method that calls UpdateEvent with all the details provided from eventToUpdate.

Reminders

Events can have reminders attached to them. A Reminder represents a notification that alerts the user before an event starts. Each reminder has a DateTime property that specifies when the reminder should fire.

// Create an event with two reminders: 1 hour and 15 minutes before
var eventStart = new DateTimeOffset(2025, 6, 15, 14, 0, 0, TimeSpan.Zero);
var eventEnd = eventStart.AddHours(1);

var reminders = new[]
{
    new Reminder(eventStart.AddHours(-1)),   // 1 hour before
    new Reminder(eventStart.AddMinutes(-15)) // 15 minutes before
};

var eventId = await calendarStore.CreateEvent(
    calendarId, "Team Meeting", "Weekly sync", "Conference Room",
    eventStart, eventEnd, reminders: reminders);

Reminders attached to an event can be read back through the CalendarEvent.Reminders property:

var calendarEvent = await calendarStore.GetEvent(eventId);

foreach (var reminder in calendarEvent.Reminders)
{
    Console.WriteLine($"Reminder at: {reminder.DateTime}");
}

Note: On Windows, only a single reminder per event is supported. If multiple reminders are provided, only the first one will be used.

DeleteEvent(string eventId)

Removes an event, specified by the unique identifier, from the device calendar.

DeleteEvent(CalendarEvent eventToDelete)

Removes an event from the device calendar. This is basically just a convenience method that calls DeleteEvent with eventToDelete.Id.

Acknowledgements

This project could not have came to be without these projects and people, thank you! ❤️

Xamarin.Essentials PR

There are a couple of people involved in bringing this functionality to Xamarin.Essentials. Unfortunately the PR was never merged. In an attempt not to let this code go to waste, I transformed it into this library. Thank you @mattleibow, @nickrandolph, @ScottBTR and @mkieres for the initial work here!

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-android35.0 is compatible.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-ios18.0 is compatible.  net9.0-maccatalyst was computed.  net9.0-maccatalyst18.0 is compatible.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net9.0-windows10.0.19041 is compatible.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.1.0 195 3/9/2026
4.0.0 9,183 4/28/2025
3.0.1 255 4/26/2025
3.0.0 977 3/30/2025
3.0.0-preview4 190 3/28/2025
3.0.0-preview3 269 2/11/2025
3.0.0-preview2 169 1/9/2025
3.0.0-preview1 190 1/4/2025
2.0.1 2,693 12/20/2024
2.0.0 13,808 12/21/2023
2.0.0-preview1 211 12/8/2023
1.0.2 975 10/20/2023
1.0.1 380 10/2/2023
1.0.0 237 9/28/2023
1.0.0-preview8 194 9/27/2023
1.0.0-preview7 172 9/26/2023
1.0.0-preview6 224 9/19/2023
1.0.0-preview5 187 9/16/2023
1.0.0-preview4 207 9/13/2023
1.0.0-preview3 203 9/13/2023
Loading failed