Container: Environment:

Class: Container

.setUpAuth()

This sample demonstrates how to authenticate a user with your app. There are two steps to authentication:

  1. Setting up auth. This step checks whether a user is signed in. If you have specified auth.persist = true in your configuration you could run setUpAuth while bootstrapping your app and this function will use the stored cookie. The promise resolves with a userIdentity object or null and a sign-in or sign-out button will have been appended to the button container with id apple-sign-in-button or apple-sign-out-button (whichever is appropriate). These containers need to be in the DOM before executing the function and their IDs can be customized in CloudKit.configure.
  2. Binding handlers to the rendered button. The promises whenUserSignsIn and whenUserSignsOut are resolved when the user signs-in/out respectively. The former resolves with a userIdentity object.

If you selected the option Request user discoverability at sign in when creating your API token, a user will be able to grant discoverability permission to the app during the above sign-in flow.

Class: Container

.fetchCurrentUserIdentity()

This sample demonstrates how to fetch the currently signed-in user’s userIdentity object. If the current user has made himself discoverable to the app, this object will have nonempty nameComponents.

Class: Container

.discoverAllUserIdentities()

This sample demonstrates how to obtain a list of UserIdentity objects corresponding to users of the app in the signed-in user’s iCloud Contacts who have made themselves discoverable to the app.

Class: Container

.discoverUserIdentityWithEmailAddress()

This sample demonstrates how to look up a user’s discoverable information by email address. This method will always return a userIdentity object with the lookupInfo field populated. The other fields will be populated only if a matching discoverable user is found.

Class: Container

.discoverUserIdentityWithUserRecordName()

This sample demonstrates how to look up a discoverable user’s identity by user record name. The .catch() block is invoked when no matching user is found.

Page Not Found

The page you were looking for was not found. Please use the menu on the left to navigate the app.

Class: Container

.registerForNotifications()

This sample shows how to add a notification listener to the container. The listener will get called whenever the server sends us a notification of an update to a subscription. In order to receive notifications your app must park a connection with the notification backend using registerForNotifications.

Class: Database

.saveRecords()

This sample demonstrates how to save a record to a cloud database. Leave the recordName field blank to let the server generate a record name. Leave the recordChangeTag field blank when creating a new record and supply the latest server change tag when modifying an existing record. Create a share record in the private database by specifying the record type cloudkit.share.

Class: Database

.deleteRecords()

This sample demonstrates how an authenticated user can delete a record.

Class: Database

.fetchRecords()

This sample demonstrates how to fetch a record by record name from any database and zone.

Class: Container

.fetchRecordInfos()

This sample demonstrates how to resolve a record from a stable short GUID.

Class: Container

.acceptShares()

This sample demonstrates how to accept a share with a short GUID.

Class: Database

.shareWithUI()

This sample shows how to share a record with the default sharing UI.

Class: Database

.saveSubscriptions()

This sample demonstrates how a user can subscribe to a change to a record in a specific zone (zone subscription) as well as to changes to records that match a query condition (query subscription). Once subscribed, your app can register for notifications of changes.

Class: Database

.deleteSubscriptions()

This sample shows how to delete a subscription by ID.

Class: Database

.fetchSubscriptions()

This sample shows how to fetch a subscription by ID.

Class: Database

.fetchAllSubscriptions()

This sample shows how to fetch all subscriptions.

Class: Database

.fetchDatabaseChanges()

This sample demonstrates how an authenticated user can get all changed zones relative to a meta-sync token in their private or shared database.

Class: Database

.fetchRecordZoneChanges()

This sample demonstrates how an authenticated user can get all changes relative to a sync token in a custom or shared zone. If no sync token is provided all records in the zone are returned. The response will always contain a new sync token which can be cached in the client and sent in a new sync request. The sync token can also be used for paginating a result set. The moreComing boolean on the response indicates if the result set is incomplete.

When you have a zone-level subscription you can get notified of changes to that zone and you would typically run fetchRecordZoneChanges to then fetch the latest changes and bring your client up-to-date.

Class: Database

.saveRecordZones()

This sample shows how to create a custom zone in the user’s private database. Zones are useful for syncing a user’s data. Once you have created a custom zone you will be able to create records in that zone and test the sync feature.

Class: Database

.deleteRecordZones()

This sample shows how to delete a custom zone by name from the private database.

Class: Database

.fetchRecordZones()

This sample shows how to fetch a record zone by name from the private database.

Class: Database

.fetchAllRecordZones()

This sample shows how to list all record zones in your private database. The response will always contain the default zone.

Class: Database

.performQuery()

This sample demonstrates how any user can query records in the public database and a logged in user can query records in their private database.

CloudKit on the web

This web application provides executable sample code for the core API methods provided by the CloudKit JS JavaScript library. While these methods cover many typical use cases, there are more flexible versions available if needed which allow for batch requests and more configuration. The user is advised to refer to the CloudKit JS Reference for more information.

All code examples can be run by clicking the play button at the top of the page. The results will be displayed below the sample code block.

Obtaining the CloudKit JS library

CloudKit JS is hosted at https://cdn.apple-cloudkit.com/ck/2/cloudkit.js. Include the library on your web page using either of the two methods below. You will automatically get updates and bug fixes as they are released.

Option #1 - Load CloudKit JS synchronously

<script src="https://cdn.apple-cloudkit.com/ck/2/cloudkit.js"></script>

Option #2 - Load CloudKit JS asynchronously

<!-- Listen for the cloudkitloaded event on the window object. -->
<script>
  window.addEventListener('cloudkitloaded', function() {
    // Now the global namespace CloudKit is defined and you can proceed
    // to configure your application.
  });
</script>

<!-- Include the script with the ‘async’ attribute. -->
<script src="https://cdn.apple-cloudkit.com/ck/2/cloudkit.js" async></script>

Configuring CloudKit JS

The first use of the CloudKit namespace in your javascript app should be configuration code.

CloudKit.configure({
  locale: 'en-us',

  containers: [{

    // Change this to a container identifier you own.
    containerIdentifier: 'com.example.apple-samplecode.cloudkit-catalog',

    apiTokenAuth: {
      // And generate a web token through CloudKit Dashboard.
      apiToken: '<insert your token here>',

      persist: true, // Sets a cookie.

      signInButton: {
        id: 'apple-sign-in-button',
        theme: 'black' // Other options: 'white', 'white-with-outline'.
      },

      signOutButton: {
        id: 'apple-sign-out-button',
        theme: 'black'
      }
    },

    environment: 'development'
  }]
});

Change the container identifier to one that you own. For more information on how to create a container see CloudKit Quick Start. You can can create a container and generate an API token through the CloudKit Dashboard.

Browser support

CloudKit JS is supported on Safari, Firefox, Chrome, Internet Explorer and Microsoft Edge, including embedded web views. For security reasons, a mobile web view must launch the Apple sign-in page in a native browser in order to use iCloud authentication.



Server-side CloudKit with node.js

A powerful CloudKit feature is the ability to make API calls with a server script. This feature is enabled by creating a server-to-server key in the API Access section of CloudKit Dashboard. Such a key allows a server script to authenticate with CloudKit and make API calls to the public database with the inherited privileges of the creator of the key. In this section we will explain this process for a node.js script using CloudKit JS.

Creating a server-to-server key

If you are on a Mac, you already have OpenSSL installed and you can generate a private key in Terminal with this command:

openssl ecparam -name prime256v1 -genkey -noout -out eckey.pem

This will create the file eckey.pem in your working directory. In CloudKit Dashboard navigate to API Access -> Server-to-Server Keys -> Add Server-to-Server Key and paste the output of the following command into the Public Key text field of the new key.

openssl ec -in eckey.pem -pubout

Hit Save and the Key ID attribute will get populated. You will use this key ID in configuring your node script.

Installing dependencies

In order to use CloudKit JS server-side you will need a fetch implementation such as node-fetch which you can install from NPM. You must also download CloudKit JS itself from Apple’s CDN.

npm install node-fetch
curl https://cdn.apple-cloudkit.com/ck/2/cloudkit.js > cloudkit.js

Configuring CloudKit JS in a node script

Create a script file in your working directory and add the following configuration code.

var fetch = require('node-fetch');
var CloudKit = require('./cloudkit');

CloudKit.configure({
  services: {
    fetch: fetch,
    logger: console
  },
  containers: [{

    // Change this to a container identifier that you own.
    containerIdentifier: 'com.example.apple-samplecode.cloudkit-catalog',

    environment: 'development',

    serverToServerKeyAuth: {

      // This is the key ID you generated in CloudKit Dashboard.
      keyID: '<insert key ID>',

      // This should reference the private key file that you used to
      // generate the above key ID.
      privateKeyFile: __dirname + '/eckey.pem'

    }
  }]
});

Note: Never expose or share the above private key with anyone, including Apple, as it has unrestricted access to your CloudKit container.

Authenticating and using the APIs

Before making API calls your script needs to authenticate with CloudKit using the server-to-server key that was set in the configuration code.

var container = CloudKit.getDefaultContainer();

// Server to server keys only allow calls to the public database.
var database = container.publicCloudDatabase;


// Authenticate with CloudKit using the server-to-server
// key set in CloudKit.configure()
container.setUpAuth()
  .then(function(userInfo) {

    // The userInfo is that of the user who created the key in CloudKit Dashboard.
    // If this user has permission to write a record of type Item to the
    // public database, the following call will succeed.
    return database.saveRecords({ recordType: 'Item' });

  }).then(function(response) {

    var savedRecord = response.records[0];
    console.log('Record name:', savedRecord.recordName);

    process.exit(0);

  }).catch(function(error) {
    // Handle the error.
    process.exit(1);
  });

You are now ready to start scripting with CloudKit JS and node.js. You may wish to look at the sections Query and Records for examples of API calls that you can use in server-side scripts.