Skip to content
Client v5: BLE, BLE Hosting, HTTP, Jobs - Linux, MacOS, & Blazor Support! Full AOT, RX on BLE only & MANY other features! Power up!

Contact Store | Getting Started

A cross-platform library for accessing device contacts on Android and iOS. Provides full CRUD operations, LINQ query support, Shiny’s AccessState permission model, and dependency injection integration. Built on Shiny.Core, so it runs in any Shiny host — with or without .NET MAUI.

GitHubGitHub stars for shinyorg/contactstore
DownloadsNuGet downloads for Shiny.Contacts
Frameworks
.NET MAUI
.NET
  • Full CRUD — create, read, update, and delete device contacts
  • LINQ queriesIQueryable<Contact> with native translation on both platforms
  • Shiny permissionsGetCurrentAccess() and RequestAccess() using Shiny.Core’s AccessState model
  • No MAUI required — built on Shiny.Core, so it works in any Shiny host
  • AOT compatible — trimmer and AOT safe
  • Dependency injection — register with a single AddContactStore() call
PlatformMinimum Version
AndroidAPI 24
iOS15.0
Changed files
  • MyApp/
Platforms/Android/AndroidManifest.xml
AndroidManifest.xml
1<?xml version="1.0" encoding="utf-8"?>2<manifest xmlns:android="http://schemas.android.com/apk/res/android">3	<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">4	</application>5	<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>6	<uses-permission android:name="android.permission.BATTERY_STATS" />7	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />8	<uses-permission android:name="android.permission.INTERNET" />9	<uses-permission android:name="android.permission.READ_CONTACTS" />10	<uses-permission android:name="android.permission.WRITE_CONTACTS" />11</manifest>
// Request access (triggers OS prompt if needed)
var access = await contactStore.RequestAccess();
if (access != AccessState.Available)
return;
// Get all contacts
var contacts = await contactStore.GetAll();
// Query with LINQ
var results = contactStore.Query()
.Where(c => c.GivenName.Contains("John"))
.ToList();
// Create a contact
var contact = new Contact { GivenName = "John", FamilyName = "Doe" };
contact.Phones.Add(new ContactPhone("555-1234", PhoneType.Mobile));
string id = await contactStore.Create(contact);
// Update
contact.GivenName = "Jane";
await contactStore.Update(contact);
// Delete
await contactStore.Delete(id);

Bulk reads — GetAll() and Query() — populate only the lightweight Thumbnail. The full-resolution Photo is null on these results: decoding every contact’s full image into memory at once spikes memory and can get the app OOM/jetsam-killed on a real device with many photo contacts. Fetch a single contact with GetById(id) to get the full Photo (it also includes the Thumbnail).

Bind list rows to Thumbnail, and load Photo on a per-contact detail screen.

claude plugin marketplace add shinyorg/skills
claude plugin install shiny-maui@shiny
copilot plugin marketplace add https://github.com/shinyorg/skills
copilot plugin install shiny-maui@shiny
View shiny-maui Plugin