Contents

brightdigit/MistKit

Swift Package for Server-Side and Command-Line Access to CloudKit Web Services

Table of Contents

- Key Features

- Installation - Requirements - Platform Support - Quick Start

- Authentication - Error Handling - Advanced Usage - Examples

Overview

MistKit provides a modern Swift interface to CloudKit Web Services REST API, enabling cross-platform CloudKit access for server-side Swift applications, command-line tools, and platforms where the CloudKit framework isn't available.

Built with Swift concurrency (async/await) and designed for modern Swift applications, MistKit supports all three CloudKit authentication methods and provides type-safe access to CloudKit operations.

Key Features

  • 🌍 Cross-Platform Support: Works on macOS, iOS, tvOS, watchOS, visionOS, and Linux
  • ⚑ Modern Swift: Built with Swift 6 concurrency features and structured error handling
  • πŸ” Multiple Authentication Methods: API token, web authentication, and server-to-server authentication
  • πŸ›‘οΈ Type-Safe: Comprehensive type safety with Swift's type system
  • πŸ“‹ OpenAPI-Based: Generated from CloudKit Web Services OpenAPI specification
  • πŸ”’ Secure: Built-in security best practices and credential management

Getting Started

Installation

Add MistKit to your Package.swift:

dependencies: [
    .package(url: "https://github.com/brightdigit/MistKit.git", from: "1.0.0-alpha.4")
]

Or add it through Xcode:

  1. File β†’ Add Package Dependencies
  2. Enter: https://github.com/brightdigit/MistKit.git
  3. Select version and add to your target

Requirements

  • Swift 6.1+
  • Xcode 16.0+ (for iOS/macOS development)
  • Linux: Ubuntu 18.04+ with Swift 6.1+

Platform Support

Minimum Platform Versions

| Platform | Minimum Version | Server-to-Server Auth | |----------|-----------------|----------------------| | macOS | 10.15+ | 11.0+ | | iOS | 13.0+ | 14.0+ | | tvOS | 13.0+ | 14.0+ | | watchOS | 6.0+ | 7.0+ | | visionOS | 1.0+ | 1.0+ | | Linux | Ubuntu 18.04+ | βœ… | | Windows | 10+ | βœ… |

Quick Start

1. Choose Your Authentication Method

MistKit supports three authentication methods depending on your use case:

API Token (Container-level access)
import MistKit

let service = try CloudKitService(
    containerIdentifier: "iCloud.com.example.MyApp",
    apiToken: ProcessInfo.processInfo.environment["CLOUDKIT_API_TOKEN"]!
)
Web Authentication (User-specific access)
let service = try CloudKitService(
    containerIdentifier: "iCloud.com.example.MyApp",
    apiToken: ProcessInfo.processInfo.environment["CLOUDKIT_API_TOKEN"]!,
    webAuthToken: userWebAuthToken
)
Server-to-Server (Enterprise access, public database only)
let serverManager = try ServerToServerAuthManager(
    keyIdentifier: ProcessInfo.processInfo.environment["CLOUDKIT_KEY_ID"]!,
    privateKeyData: privateKeyData
)

let service = try CloudKitService(
    containerIdentifier: "iCloud.com.example.MyApp",
    tokenManager: serverManager,
    environment: .production,
    database: .public
)
2. Create CloudKit Service
do {
    let service = try CloudKitService(
        containerIdentifier: "iCloud.com.example.MyApp",
        apiToken: ProcessInfo.processInfo.environment["CLOUDKIT_API_TOKEN"]!
    )
    // Use service for CloudKit operations
} catch {
    print("Failed to create service: \\(error)")
}

Usage

Authentication

API Token Authentication
  1. Get API Token:

- Log into Apple Developer Console - Navigate to CloudKit Database - Generate an API Token

  1. Set Environment Variable:

``bash export CLOUDKIT_API_TOKEN="your_api_token_here" ``

  1. Use in Code:

``swift let service = try CloudKitService( containerIdentifier: "iCloud.com.example.MyApp", apiToken: ProcessInfo.processInfo.environment["CLOUDKIT_API_TOKEN"]! ) ``

Web Authentication

Web authentication enables user-specific operations and requires both an API token and a web authentication token obtained through CloudKit JS authentication.

let service = try CloudKitService(
    containerIdentifier: "iCloud.com.example.MyApp",
    apiToken: apiToken,
    webAuthToken: webAuthToken
)
Server-to-Server Authentication

Server-to-server authentication provides enterprise-level access using ECDSA P-256 key signing. Note that this method only supports the public database.

  1. Generate Key Pair:

```bash # Generate private key openssl ecparam -genkey -name prime256v1 -noout -out private_key.pem

# Extract public key openssl ec -in private_key.pem -pubout -out public_key.pem ```

  1. Upload Public Key: Upload the public key to Apple Developer Console
  1. Use in Code:

```swift let privateKeyData = try Data(contentsOf: URL(fileURLWithPath: "private_key.pem"))

let serverManager = try ServerToServerAuthManager( keyIdentifier: "your_key_id", privateKeyData: privateKeyData ) let service = try CloudKitService( containerIdentifier: "iCloud.com.example.MyApp", tokenManager: serverManager, environment: .production, database: .public ) ```

Error Handling

MistKit provides comprehensive error handling with typed errors:

do {
    let service = try CloudKitService(
        containerIdentifier: "iCloud.com.example.MyApp",
        apiToken: apiToken
    )
    // Perform operations
} catch let error as CloudKitError {
    print("CloudKit error: \\(error.localizedDescription)")
} catch let error as TokenManagerError {
    print("Authentication error: \\(error.localizedDescription)")
} catch {
    print("Unexpected error: \\(error)")
}
Error Types
  • CloudKitError: CloudKit Web Services API errors
  • TokenManagerError: Authentication and credential errors
  • TokenStorageError: Token storage and persistence errors

Advanced Usage

Using AsyncHTTPClient Transport

For server-side applications, MistKit can use swift-openapi-async-http-client as the underlying HTTP transport. This is particularly useful for server-side Swift applications that need robust HTTP client capabilities.

import MistKit
import OpenAPIAsyncHTTPClient

// AsyncHTTPClient instance usually supplied by the Server API
let httpClient : HTTPClient

// Create the transport
let transport = AsyncHTTPClientTransport(client: httpClient)

// Use with CloudKit service
let service = try CloudKitService(
    containerIdentifier: "iCloud.com.example.MyApp",
    apiToken: apiToken,
    transport: transport
)
Adaptive Token Manager

For applications that might upgrade from API-only to web authentication:

let adaptiveManager = AdaptiveTokenManager(
    apiToken: apiToken,
    storage: storage
)

// Later, upgrade to web authentication
try await adaptiveManager.upgradeToWebAuth(webAuthToken: webToken)

Examples

Check out the Examples/ directory for complete working examples:

  • MistDemo: Web-based CloudKit authentication demo with automatic token capture
  • BushelCloud: Server-to-Server auth demo syncing macOS restore images, Xcode, and Swift versions
  • CelestraCloud: RSS reader demonstrating CloudKit query filtering, sorting, and web etiquette patterns

Documentation

License

MistKit is released under the MIT License. See LICENSE for details.

Acknowledgments

Roadmap

v1.0.0-alpha.1

v1.0.0-alpha.2

v1.0.0-alpha.3

v1.0.0-alpha.4

v1.0.0-alpha.X

v1.0.0

v1.1.0

Support


MistKit: Bringing CloudKit to every Swift platform 🌟

Package Metadata

Repository: brightdigit/MistKit

Stars: 235

Forks: 13

Open issues: 63

Default branch: main

Primary language: swift

License: MIT

Topics: cloudkit, server-side-swift, swift, vapor

README: README.md