Skip to content
WebViewGold Vibe Coding to App Store
English
Get WebViewGold

Cursor + contacts

Contacts access for your Cursor app, without a privacy rejection

Find-your-friends screens, group invites and split-the-bill apps often want the address book. In a WebViewGold app, your Cursor app asks for permission with requestcontactpermission:// and receives names and phone numbers as JSON in the contacts variable after readcontacts://. The code takes minutes; how you use the data decides whether the app passes review.

From $109 one-time per platform, or let our team do it all from $698.

  • Approval guarantee – or money back within 14 days
  • No coding needed
  • One-time payment, free updates
  • 24/7 human support
  • Made in Germany since 2014 · ISO 27001

When reading contacts is worth it

Find friends who already use the app

Compare normalized phone numbers with accounts in your backend and show "3 of your contacts are here" instead of an empty friends list.

Invite one person at a time

The user picks a contact, the app prepares a personal invite and opens the share sheet. No bulk invites, no surprises for the recipient.

Add a client or teammate fast

CRM, booking and team apps can prefill a new record from a picked contact instead of making users retype names and numbers.

Often you do not need it

A plain invite link through the native share sheet (shareapp://) needs no permission at all and is the easier path through review. Ask for contacts only when matching or picking adds real value.

Prompt for Cursor

Paste this into Cursor to implement the web-app side. Review the result, publish, then test inside the WebViewGold app.

Prompt for the Cursor agent
Prompt for the Cursor agent: Implement contacts access for the WebViewGold app wrapper. 1) Create lib/webviewgold/contacts.ts with isWebViewGold() (navigator.userAgent includes my custom WebViewGold token), requestPermission() which navigates to requestcontactpermission://, and readContacts(timeoutMs = 5000) which sets window.contacts = undefined, navigates to readcontacts:// and resolves with the name-to-phone-numbers object or null. 2) Add normalizeNumber() with libphonenumber-js using the user's country. 3) Build a ContactsPicker component: explainer, Continue (permission), Load contacts (read), search, no preselection, no Select all. 4) Add a server endpoint that matches up to 2000 normalized numbers against users, returns only matches, stores and logs nothing, and is rate-limited. 5) Send invites through shareapp://message?=TEXT&url=INVITE_URL. 6) Add tests and document the privacy rules in .cursor/rules.

Great work! Never coded anything but managed to work with this. Easy and fast! Also with great help from the creators!

Lucas Dubois · CodeCanyon

Ask, read and use contacts responsibly

An hour for the code, a little longer for the privacy texts.

  1. Declare the permission

    Android: add android.permission.READ_CONTACTS to AndroidManifest.xml, as the WebViewGold docs require. iOS: the contacts usage description in Info.plist must say why, for example "to show which of your contacts already use the app".

  2. Explain first, then ask

    Show your own screen that explains the benefit with a Continue button, then navigate to requestcontactpermission://. Never ask on first launch or before the user reaches the feature.

  3. Read the address book

    After permission, navigate to readcontacts://. WebViewGold fills the global contacts variable with an object of names and phone-number arrays; without permission it is null.

  4. Let the user choose

    Show a searchable list with nothing preselected and no Select all button, and show the exact invite text before anything is sent.

  5. Send only what the feature needs

    For friend matching, normalize the numbers and send them to your backend for a one-time comparison; do not keep unmatched numbers. For invites, send nothing at all: open the share sheet.

Request, read and map the contacts

Two separate taps: one for the permission, one to load the list. The contacts variable arrives asynchronously. Friend matching, if you need it, runs server side for signed-in users only; in your Cursor project that means: Your own API routes or services.

javascript
var IN_APP = navigator.userAgent.indexOf("WebViewGold") !== -1; // your custom user agent token

function waitFor(name, timeoutMs, done) {
  var start = Date.now();
  (function check() {
    if (typeof window[name] !== "undefined") { done(window[name]); }
    else if (Date.now() - start < timeoutMs) { setTimeout(check, 100); }
    else { done(undefined); }
  })();
}

// Tap 1: after your own explainer screen
function askForContacts() {
  if (!IN_APP) { showInviteLink(); return; }
  window.location.href = "requestcontactpermission://";
}

// Tap 2: "Show my contacts"
function loadContacts() {
  window.contacts = undefined;
  window.location.href = "readcontacts://";
  waitFor("contacts", 5000, function (list) {
    if (!list) { showPermissionHint(); return; } // null = no permission
    // shape: { "John Appleseed": ["888-555-5512", "888-555-1212"], ... }
    var people = Object.keys(list).map(function (n) { return { name: n, phones: list[n] }; });
    renderPicker(people); // nothing preselected, no "Select all"
  });
}

// Denied earlier? Let the user change it in Settings
function openAppSettings() { window.location.href = "settingsapp://"; }

What Apple and Google check

  • Apple Guideline 5.1.1: request access in context, only for features that need it, with a purpose string that explains the use. Vague strings are a frequent rejection reason.
  • Apple Guideline 5.1.2: do not use contacts to build a contact database or pass it to third parties, and contact people only at the user's explicit, individual initiative: no Select all, no preselected contacts, and show what the message will say. Check the current guideline text before you submit.
  • Google Play User Data policy: address book data is personal and sensitive. If you upload it, show a prominent in-app disclosure before the permission request and declare Contacts in the Data safety form.
  • Hashing phone numbers is not anonymization, because the number space is small. Treat hashes as personal data, keep them only as long as needed and cover them in your privacy policy and account deletion (the account deletion guide).
  • Since iOS 18, users can share only selected contacts. Make sure the feature works with a short list and do not nag for full access.

Frequently asked questions

What does readcontacts:// return?

A JSON object keyed by contact name, each with an array of phone numbers, stored in the global contacts variable. Without permission the variable is null. Email addresses, postal addresses and photos are not part of the documented format.

Will Apple reject an app that reads contacts?

Not for reading them, but often for how. Ask in context with a clear purpose string, let users pick individual people, never invite everyone at once, and do not keep the address book on your server unless the feature needs it and your privacy policy says so.

Do I need contacts access for an invite feature?

Often not. A share sheet with a personal invite link reaches WhatsApp, Messages and email without any permission and is far easier to explain in review. Use contacts access when you match friends or build groups from existing contacts.

What happens if the user says no?

readcontacts:// then leaves the contacts variable as null. Offer the invite link instead, and if the user changes their mind later, open the app settings with settingsapp:// so they can grant access.

Three ways to get your app into the stores

Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.

Do it yourself

$109 per platform, one-time

The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.

See plans on the main page

Cloud Builder

$349 per license, one-time add-on

No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.

How the Cloud Builder works Try the free demo

Full Service

$698 per platform $798

Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.

Full Service details Powered by WeSetupYourWebViewApp

Winter Sale prices valid until December 31, 2026.

Ready to ship your Cursor app?

App Store & Google Play approval guarantee – or your money back within 14 days

Rather hand it over? Full Service: we configure, build and deliver within 72 hours, from $698 per platform. Questions? Chat with us 24/7.

Refunds are granted under the conditions listed in our FAQ: a non-content rejection by Apple and/or Google, claimed within 14 days after purchase.