CloudKit (cloud_kit v0.3.0)

Copy Markdown View Source

Elixir client for the Apple CloudKit API.

The public surface is intentionally small:

CloudKit.query_records(%{recordType: "Items"})
CloudKit.fetch_record("record_name")
CloudKit.create_record(%{recordType: "Items", fields: %{...}})
CloudKit.update_record("record_name", %{fields: %{...}})
CloudKit.delete_record("record_name")
CloudKit.upload_asset("file_path", "record_type", "field_name")
CloudKit.token()

Configuration

config :cloud_kit,
  container_id: System.get_env("CLOUDKIT_CONTAINER_ID"),
  environment: "development", # or "production"
  server_key_id: System.get_env("CLOUDKIT_SERVER_KEY_ID"),
  private_key: System.get_env("CLOUDKIT_PRIVATE_KEY"),
  base_url: "https://api.apple-cloudkit.com"

Every function also accepts per-call opts that override the application config.

Summary

Functions

Create a new record.

Create a subscription for change notifications.

Create a custom zone.

Delete a record by record name.

Download an asset from CloudKit.

Fetch a single record by record name.

List active subscriptions.

List zones in the database.

Query records from the CloudKit database.

Return a cached-per-call CloudKit access token (after the JWT → token exchange).

Types

opts()

@type opts() :: keyword()

response()

@type response() :: {:ok, map()} | {:error, term()}

Functions

create_record(record, opts \\ [])

@spec create_record(map(), opts()) :: response()

Create a new record.

Parameters

  • record: Map containing:
    • recordType - The record type
    • recordName - Optional unique record name (generated if not provided)
    • fields - Map of field name to value
  • opts:
    • :zone_id - Zone ID for record

Examples

CloudKit.create_record(%{
  recordType: "Items",
  fields: %{
    name: %{value: "New Item"},
    price: %{value: 99.99, type: "DOUBLE"}
  }
})

create_subscription(subscription, opts \\ [])

@spec create_subscription(map(), opts()) :: response()

Create a subscription for change notifications.

Parameters

  • subscription: Map containing:
    • subscriptionType - Type ("query" or "zone")
    • recordType - For query subscriptions, the record type
    • filters - Optional filters
    • notification - Notification configuration
  • opts: Optional configuration

Examples

CloudKit.create_subscription(%{
  subscriptionType: "query",
  recordType: "Items",
  notification: %{
    alertBody: "A new item was created"
  }
})

create_zone(zone_name, opts \\ [])

@spec create_zone(String.t(), opts()) :: response()

Create a custom zone.

Parameters

  • zone_name: The zone name
  • opts: Optional configuration

delete_record(record_name, opts \\ [])

@spec delete_record(String.t(), opts()) :: :ok | {:error, term()}

Delete a record by record name.

Parameters

  • record_name: The unique record name
  • opts:
    • :record_type - The record type
    • :zone_id - Zone ID for record

delete_subscription(subscription_id, opts \\ [])

@spec delete_subscription(String.t(), opts()) :: :ok | {:error, term()}

Delete a subscription.

Parameters

  • subscription_id: The subscription ID to delete
  • opts: Optional configuration

delete_zone(zone_name, opts \\ [])

@spec delete_zone(String.t(), opts()) :: :ok | {:error, term()}

Delete a zone.

Parameters

  • zone_name: The zone name to delete
  • opts: Optional configuration

download_asset(download_url, opts \\ [])

@spec download_asset(String.t(), opts()) :: {:ok, binary()} | {:error, term()}

Download an asset from CloudKit.

Parameters

  • download_url: The download URL from an asset field
  • opts: Download options

Examples

{:ok, content} = CloudKit.download_asset(record["fields"]["image"]["downloadURL"])

fetch_record(record_name, opts \\ [])

@spec fetch_record(String.t(), opts()) :: response()

Fetch a single record by record name.

Parameters

  • record_name: The unique record name
  • opts:
    • :record_type - Optional record type
    • :zone_id - Zone ID for record
    • :desired_keys - List of field names to return

list_subscriptions(opts \\ [])

@spec list_subscriptions(opts()) :: {:ok, [map()]} | {:error, term()}

List active subscriptions.

Parameters

  • opts: Optional configuration

list_zones(opts \\ [])

@spec list_zones(opts()) :: {:ok, [map()]} | {:error, term()}

List zones in the database.

Parameters

  • opts: Optional configuration overrides

query_records(query, opts \\ [])

@spec query_records(map(), opts()) :: {:ok, map()} | {:error, term()}

Query records from the CloudKit database.

Parameters

  • query: Map containing:
    • recordType - The record type to query
    • filterBy - Optional filter specification
    • sortBy - Optional sort specification
    • limit - Maximum records to return (default 200)
    • desiredKeys - Optional list of field names to return
  • opts:
    • :zone_id - Zone ID for record (defaults to default zone)

Examples

CloudKit.query_records(%{
  recordType: "Items",
  filterBy: [%{fieldName: "name", comparator: "EQUALS", fieldValue: %{value: "Test"}}],
  limit: 50
})

token(opts \\ [])

@spec token(opts()) :: {:ok, String.t()} | {:error, term()}

Return a cached-per-call CloudKit access token (after the JWT → token exchange).

update_record(record_name, updates, opts \\ [])

@spec update_record(String.t(), map(), opts()) :: response()

Update an existing record.

Parameters

  • record_name: The unique record name
  • updates: Map of fields to update
  • opts:
    • :record_type - The record type
    • :zone_id - Zone ID for record

Examples

CloudKit.update_record("record_123", %{
  fields: %{
    price: %{value: 149.99, type: "DOUBLE"}
  }
})

upload_asset(file_path, record_type, field_name, opts \\ [])

@spec upload_asset(String.t(), String.t(), String.t(), opts()) :: response()

Upload an asset to CloudKit.

Parameters

  • file_path: Path to the file to upload
  • record_type: The record type that will use this asset
  • field_name: The field name in the record
  • opts:
    • :zone_id - Zone ID
    • :record_name - Optional record name to associate

Examples

CloudKit.upload_asset("/path/to/image.png", "Items", "image")