brightdigit/MistKit
Swift Package for Server-Side and Command-Line Access to CloudKit Web Services
Table of Contents
- 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:
- File β Add Package Dependencies
- Enter:
https://github.com/brightdigit/MistKit.git - 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
- Get API Token:
- Log into Apple Developer Console - Navigate to CloudKit Database - Generate an API Token
- Set Environment Variable:
``bash export CLOUDKIT_API_TOKEN="your_api_token_here" ``
- 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.
- 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 ```
- Upload Public Key: Upload the public key to Apple Developer Console
- 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 errorsTokenManagerError: Authentication and credential errorsTokenStorageError: 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
- API Documentation: Complete API reference
- CloudKit Web Services: Apple's official CloudKit Web Services documentation
License
MistKit is released under the MIT License. See LICENSE for details.
Acknowledgments
- Built on Swift OpenAPI Generator
- Uses Swift Crypto for server-to-server authentication
- Inspired by CloudKit Web Services REST API
Roadmap
v1.0.0-alpha.1
- [x] Composing Web Service Requests β
- [x] Modifying Records (records/modify) β
- [x] Fetching Records Using a Query (records/query) β
- [x] Fetching Records by Record Name (records/lookup) β
- [x] Fetching Current User Identity (users/caller) β
v1.0.0-alpha.2
- [x] Vapor Token Client β
- [x] Vapor Token Storage β
- [x] Vapor URL Client β
- [x] Swift NIO URL Client β
- [x] Date Field Types β
- [x] Location Field Types β
- [x] List Field Types β
- [x] Reference Field Types β
- [x] Error Codes β
- [x] Fetching Zones (zones/list) β
v1.0.0-alpha.3
- [ ] Name Component Types
- [x] Uploading Assets (assets/upload) β
- [ ] Fetching Zones by Identifier (zones/lookup)
- [ ] Fetching Database Changes (changes/database)
- [x] Add Support for swiftlang/swift-source-compat-suite β
v1.0.0-alpha.4
- [x] Uploading Assets (assets/upload) β
- [x] Add Support for swiftlang/swift-source-compat-suite β
- [x] MistDemo - Web Authentication Demo β
- [x] WASM Platform Support β
- [x] Android Platform Support β
v1.0.0-alpha.X
- [ ] Discovering User Identities (POST users/discover)
- [ ] Discovering All User Identities (GET users/discover)
- [ ] Referencing Existing Assets (assets/rereference)
- [ ] Fetching Contacts (users/lookup/contacts)
- [ ] Fetching Users by Email (users/lookup/email)
- [ ] Fetching Users by Record Name (users/lookup/id)
- [ ] Fetching Record Changes (records/changes)
- [ ] Fetching Record Information (records/resolve)
- [ ] Accepting Share Records (records/accept)
- [ ] Modifying Zones (zones/modify)
- [ ] Fetching Record Zone Changes (changes/zone)
- [ ] Fetching Zone Changes (zones/changes)
- [ ] Fetching Subscriptions (subscriptions/list)
- [ ] Fetching Subscriptions by Identifier (subscriptions/lookup)
- [ ] Modifying Subscriptions (subscriptions/modify)
- [ ] Creating APNs Tokens (tokens/create)
- [ ] Registering Tokens (tokens/register)
- [ ] Feature: Add custom CloudKit zone support for queries
v1.0.0
- [ ] System Field Integration
- [ ] Handle Data Size Limits
- [ ] Add architecture diagrams to Bushel documentation
- [ ] Add comprehensive test suite for Bushel demo
- [ ] Implement incremental sync with change tracking for Bushel
- [ ] Migrate Bushel Demo to it's own Repository
- [ ] Migrate Celestra Demo to it's own Repository
v1.1.0
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: API Reference
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