### AVAudioSession Setup and Playback Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/avfoundation-ref.md Sets up the audio session for playback and starts an audio engine pipeline to play a file. ```swift // AUDIO SESSION SETUP import AVFoundation try AVAudioSession.sharedInstance().setCategory( .playback, // or .playAndRecord, .ambient mode: .default, // or .voiceChat, .measurement options: [.mixWithOthers, .allowBluetoothHFP] ) try AVAudioSession.sharedInstance().setActive(true) // AUDIO ENGINE PIPELINE let engine = AVAudioEngine() let player = AVAudioPlayerNode() engine.attach(player) engine.connect(player, to: engine.mainMixerNode, format: nil) try engine.start() player.scheduleFile(audioFile, at: nil) player.play() ``` -------------------------------- ### AVAudioEngine Basic Pipeline Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/avfoundation-ref.md Sets up a basic AVAudioEngine pipeline with a player node and a reverb effect, connecting them and starting the engine. ```swift let engine = AVAudioEngine() // Create nodes let player = AVAudioPlayerNode() let reverb = AVAudioUnitReverb() reverb.loadFactoryPreset(.largeHall) reverb.wetDryMix = 50 // Attach to engine engine.attach(player) engine.attach(reverb) // Connect: player → reverb → mixer → output engine.connect(player, to: reverb, format: nil) engine.connect(reverb, to: engine.mainMixerNode, format: nil) // Start engine.prepare() try engine.start() // Play file let url = Bundle.main.url(forResource: "audio", withExtension: "m4a")! let file = try AVAudioFile(forReading: url) player.scheduleFile(file, at: nil) player.play() ``` -------------------------------- ### Basic SwiftData Migration Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/swiftdata-migration.md A quick reference guide for setting up a basic SwiftData migration. It includes defining versioned schemas, creating a migration plan, and applying it to the ModelContainer. ```swift // 1. Define versioned schemas enum SchemaV1: VersionedSchema { /* models */ } enum SchemaV2: VersionedSchema { /* models */ } // 2. Create migration plan enum MigrationPlan: SchemaMigrationPlan { static var schemas: [any VersionedSchema.Type] { [SchemaV1.self, SchemaV2.self] } static var stages: [MigrationStage] { [migrateV1toV2] } static let migrateV1toV2 = MigrationStage.lightweight( fromVersion: SchemaV1.self, toVersion: SchemaV2.self ) } // 3. Apply to container let schema = Schema(versionedSchema: SchemaV2.self) let container = try ModelContainer( for: schema, migrationPlan: MigrationPlan.self ) ``` -------------------------------- ### Initialize Xcode First Launch Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-fix-build/SKILL.md Runs the initial setup for Xcode after a new version or simulator runtime is installed. This is a required step before simulators can be used, especially in CI/CD. ```bash # 1. Select Xcode version xcode-select -s /Applications/Xcode.app # 2. Run first launch setup xcodebuild -runFirstLaunch ``` -------------------------------- ### Install Axiom Plugin Source: https://github.com/charleswiltgen/axiom/blob/main/SUBMISSION-STATUS.md Use this command to install the Axiom plugin from the marketplace. You can also add community marketplaces to your installation. ```bash # From the Axiom marketplace /plugin marketplace add CharlesWiltgen/Axiom # Once listed in community marketplaces, they can add those marketplaces too /plugin marketplace add jeremylongshore/claude-code-plugins-plus /plugin marketplace add ananddtyagi/claude-code-marketplace /plugin marketplace add EveryInc/every-marketplace ``` -------------------------------- ### Complete Widget Implementation Example Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/extensions-widgets-ref.md A Swift code example demonstrating a complete widget implementation, including configuration and timeline provider. ```APIDOC ## Complete Widget Implementation ### Description This code snippet provides a practical example of a complete widget implementation in Swift. It includes the necessary structures for `Widget Configuration` and the `TimelineProvider`, illustrating how to define a widget, its data provider, and its timeline policies. ### Code Example ```swift // Widget Configuration @main struct MyWidget: Widget { let kind = "MyWidget" var body: some WidgetConfiguration { StaticConfiguration(kind: kind, provider: Provider()) { entry in MyWidgetView(entry: entry) } .configurationDisplayName("My Widget") .description("Shows app data.") .supportedFamilies([.systemSmall, .systemMedium]) } } // Timeline Provider struct Provider: TimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), data: "Placeholder") } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) { completion(SimpleEntry(date: Date(), data: fetchFromCache())) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let data = fetchFromSharedDefaults() let entry = SimpleEntry(date: Date(), data: data) let timeline = Timeline(entries: [entry], policy: .after(Date().addingTimeInterval(3600))) completion(timeline) } } // Placeholder for SimpleEntry and MyWidgetView, and fetch functions struct SimpleEntry: TimelineEntry { let date: Date let data: String } struct MyWidgetView: View { var entry: SimpleEntry var body: some View { Text(entry.data) } } func fetchFromCache() -> String { // Simulate fetching data from cache return "Cached Data" } func fetchFromSharedDefaults() -> String { // Simulate fetching data from shared defaults return "Shared Data" } ``` ``` -------------------------------- ### SwiftUI File Importer Example Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-macos/skills/sandbox-and-file-access.md Demonstrates how to use SwiftUI's .fileImporter to allow users to select files. Access is automatically started and must be stopped using stopAccessingSecurityScopedResource(). Bookmarks should be created for future access. ```swift struct ContentView: View { @State private var showImporter = false var body: some View { Button("Open File") { showImporter = true } .fileImporter( isPresented: $showImporter, allowedContentTypes: [.plainText, .pdf], allowsMultipleSelection: false ) { result in switch result { case .success(let urls): guard let url = urls.first else { return } // Access is already started for URLs from fileImporter defer { url.stopAccessingSecurityScopedResource() } // Read the file let data = try? Data(contentsOf: url) // If you need this file later, bookmark it NOW saveBookmark(for: url) case .failure(let error): // Handle — do not swallow silently logger.error("File import failed: \(error.localizedDescription)") } } } } ``` -------------------------------- ### Install Axiom MCP Server via npm Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-mcp/README.md Add the Axiom MCP server to your tool's MCP configuration for quick start. This downloads and runs the server in production mode. ```json { "mcpServers": { "axiom": { "command": "npx", "args": ["-y", "axiom-mcp"] } } } ``` -------------------------------- ### Build and Sign PKG Installer Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-macos/skills/direct-distribution.md Builds an unsigned installer package (.pkg) from an application bundle and then signs it using an Installer certificate. Replace placeholders with your actual signing identity. ```bash productbuild --component MyApp.app /Applications MyApp-unsigned.pkg productsign --sign "Developer ID Installer: ()" \ MyApp-unsigned.pkg MyApp.pkg ``` -------------------------------- ### Install Dependencies Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-mcp/README.md Installs project dependencies using npm. This is the first step before building or running the project. ```bash npm install ``` -------------------------------- ### AppKit Open Panel Example Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-macos/skills/sandbox-and-file-access.md Shows how to use AppKit's NSOpenPanel for file selection. Similar to SwiftUI's fileImporter, access is started and must be stopped, and bookmarks are recommended for persistent access. ```swift let panel = NSOpenPanel() panel.allowedContentTypes = [.plainText] panel.allowsMultipleSelection = false panel.begin { response in guard response == .OK, let url = panel.url else { return } // Access is already started for URLs from NSOpenPanel defer { url.stopAccessingSecurityScopedResource() } let data = try? Data(contentsOf: url) // Bookmark if needed for future access saveBookmark(for: url) } ``` -------------------------------- ### Install SwiftFormat Source: https://github.com/charleswiltgen/axiom/blob/main/docs/hooks/index.md Use this command to install SwiftFormat, a tool required for the Swift Auto-Format hook. ```bash brew install swiftformat ``` -------------------------------- ### List Installed Apps Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-test-simulator/SKILL.md Lists all applications currently installed on the booted simulator. This is useful for inventory and verification purposes. ```bash xcrun simctl listapps booted ``` -------------------------------- ### Example Consumable Product Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/in-app-purchases.md Example of a consumable product configuration within a StoreKit configuration file. ```text Product ID: com.yourapp.coins_100 Reference Name: 100 Coins Price: $0.99 ``` -------------------------------- ### Start Workout Intent Example Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/app-intents-ref.md A complete example of an App Intent for starting a workout. It includes defining parameters, a parameter summary, and performing the workout action on the MainActor. ```swift struct StartWorkoutIntent: AppIntent { static var title: LocalizedStringResource = "Start Workout" static var description: IntentDescription = "Starts a new workout session" static var supportedModes: IntentModes = .foreground // iOS 26+ (was `openAppWhenRun = true`) @Parameter(title: "Workout Type") var workoutType: WorkoutType @Parameter(title: "Duration (minutes)") var duration: Int? static var parameterSummary: some ParameterSummary { Summary("Start \(\.$workoutType)") { \.$duration } } func perform() async throws -> some IntentResult { let workout = Workout( type: workoutType, duration: duration.map { TimeInterval($0 * 60) } ) await MainActor.run { WorkoutCoordinator.shared.start(workout) } return .result( dialog: "Starting \(workoutType.displayName) workout" ) } } enum WorkoutType: String, AppEnum { case running case cycling case swimming case yoga static var typeDisplayRepresentation: TypeDisplayRepresentation = "Workout Type" static var caseDisplayRepresentations: [WorkoutType: DisplayRepresentation] = [ .running: "Running", .cycling: "Cycling", .swimming: "Swimming", .yoga: "Yoga" ] var displayName: String { switch self { case .running: return "running" case .cycling: return "cycling" case .swimming: return "swimming" case .yoga: return "yoga" } } } ``` -------------------------------- ### ProximityReaderDiscovery Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/tap-to-pay-ref.md A system-provided UI component for guiding merchants through the Tap to Pay setup process. ```APIDOC ## ProximityReaderDiscovery ### Description This is a system-provided UI element that assists merchants in setting up and understanding the Tap to Pay feature. It is maintained by Apple and localized for different regions. ### Usage Used for integrating the merchant tutorial UI for Tap to Pay discovery. ``` -------------------------------- ### Database Setup with Migrations Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/sqlitedata.md Set up a database using `DatabaseQueue` and manage schema evolution with `DatabaseMigrator`. Register migrations to create tables and apply changes. ```swift import Dependencies import SQLiteData import GRDB func appDatabase() throws -> any DatabaseWriter { var configuration = Configuration() configuration.prepareDatabase { db in // Configure database behavior db.trace { print("SQL: \($0)") } // Optional SQL logging } let database = try DatabaseQueue(configuration: configuration) var migrator = DatabaseMigrator() // Register migrations migrator.registerMigration("v1") { db in try #sql( """ CREATE TABLE "items" ( "id" TEXT PRIMARY KEY NOT NULL DEFAULT (uuid()), "title" TEXT NOT NULL DEFAULT '', "isInStock" INTEGER NOT NULL DEFAULT 1, "notes" TEXT NOT NULL DEFAULT '' ) STRICT """ ) .execute(db) } try migrator.migrate(database) return database } ``` -------------------------------- ### Example Usage of @Animatable and @AnimatableIgnored Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/animation-ref.md This example demonstrates how to use @Animatable for animatable properties like progress and total items, and @AnimatableIgnored for non-animatable properties such as title, start time, and debug flags. ```swift @MainActor @Animatable struct ProgressView: View { var progress: Double // Animated var totalItems: Int // Animated (if Float, not if Int) @AnimatableIgnored var title: String // Not animated @AnimatableIgnored var startTime: Date // Not animated @AnimatableIgnored var debugEnabled: Bool // Not animated var body: some View { VStack { Text(title) ProgressBar(value: progress) if debugEnabled { Text("Started: \(startTime.formatted())") } } } } ``` -------------------------------- ### App Store Server API: Get App Transaction Info Response Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/storekit-ref.md Example JSON response structure for the GET /inApps/v2/appTransaction/{transactionId} endpoint, containing signed app transaction information. ```json { "signedAppTransactionInfo": "eyJhbGc..." } ``` -------------------------------- ### Verify Build with Simulator Screenshot Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-build/skills/xcode-debugging.md A workflow to boot a simulator, build and install an app, launch it, and capture a screenshot for visual verification. Replace bundle ID and simulator name as needed. ```bash # 1. Boot simulator (if not already) xcrun simctl boot "iPhone 16 Pro" # 2. Build and install app xcodebuild build -scheme YourScheme \ -destination 'platform=iOS Simulator,name=iPhone 16 Pro' # 3. Launch app xcrun simctl launch booted com.your.bundleid # 4. Wait for UI to stabilize sleep 2 # 5. Capture screenshot xcrun simctl io booted screenshot /tmp/verify-build-$(date +%s).png ``` -------------------------------- ### Get Detailed App Info Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-test-simulator/SKILL.md Retrieves detailed information about a specific application installed on the booted simulator. ```bash xcrun simctl appinfo booted com.example.YourApp ``` -------------------------------- ### AVCaptureSession Setup and Configuration Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/camera-capture-ref.md Demonstrates how to set up an AVCaptureSession, configure its preset, add inputs and outputs, and manage its lifecycle. ```APIDOC ## AVCaptureSession Central coordinator for capture data flow. ### Session Presets | Preset | Resolution | Use Case | |--------|------------|----------| | `.photo` | Optimal for photos | Photo capture | | `.high` | Highest device quality | Video recording | | `.medium` | VGA quality | Preview, lower storage | | `.low` | CIF quality | Minimal storage | | `.hd1280x720` | 720p | HD video | | `.hd1920x1080` | 1080p | Full HD video | | `.hd4K3840x2160` | 4K | Ultra HD video | | `.inputPriority` | Use device format | Custom configuration | ### Session Configuration ```swift // Batch configuration (atomic) session.beginConfiguration() defer { session.commitConfiguration() } // Check preset support if session.canSetSessionPreset(.hd4K3840x2160) { session.sessionPreset = .hd4K3840x2160 } // Add input/output if session.canAddInput(input) { session.addInput(input) } if session.canAddOutput(output) { session.addOutput(output) } ``` ### Session Lifecycle ```swift // Start (ALWAYS on background queue) sessionQueue.async { session.startRunning() // Blocking call } // Stop sessionQueue.async { session.stopRunning() } // Check state session.isRunning // true/false session.isInterrupted // true during phone calls, etc. ``` ### Session Notifications ```swift // Session started NotificationCenter.default.addObserver( forName: .AVCaptureSessionDidStartRunning, object: session, queue: .main) { _ in } // Session stopped NotificationCenter.default.addObserver( forName: .AVCaptureSessionDidStopRunning, object: session, queue: .main) { _ in } // Session interrupted (phone call, etc.) NotificationCenter.default.addObserver( forName: .AVCaptureSessionWasInterrupted, object: session, queue: .main) { notification in let reason = notification.userInfo?[AVCaptureSessionInterruptionReasonKey] as? Int } // Interruption ended NotificationCenter.default.addObserver( forName: .AVCaptureSessionInterruptionEnded, object: session, queue: .main) { _ in } // Runtime error NotificationCenter.default.addObserver( forName: .AVCaptureSessionRuntimeError, object: session, queue: .main) { notification in let error = notification.userInfo?[AVCaptureSessionErrorKey] as? Error } ``` ### Interruption Reasons | Reason | Value | Cause | |--------|-------|-------| | `.videoDeviceNotAvailableInBackground` | 1 | App went to background | | `.audioDeviceInUseByAnotherClient` | 2 | Another app using audio | | `.videoDeviceInUseByAnotherClient` | 3 | Another app using camera | | `.videoDeviceNotAvailableWithMultipleForegroundApps` | 4 | Split View (iPad) | | `.videoDeviceNotAvailableDueToSystemPressure` | 5 | Thermal throttling | ``` -------------------------------- ### Synchronous makeSharedContext Example Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/previews-ref.md Demonstrates a synchronous `makeSharedContext()` implementation for providing an `@Observable` object when no asynchronous setup is required. ```swift static func makeSharedContext() async throws -> AppState { let state = AppState() state.products = Product.previewCatalog return state } ``` -------------------------------- ### GRDB DatabaseMigrator Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/database-migration.md Demonstrates setting up a GRDB DatabaseMigrator with multiple migration steps, including schema creation and column alteration. ```swift var migrator = DatabaseMigrator() // Migration 1 migrator.registerMigration("v1") { db in try db.execute(sql: """ CREATE TABLE IF NOT EXISTS users ( id TEXT PRIMARY KEY, name TEXT NOT NULL ) """) } // Migration 2 migrator.registerMigration("v2") { db in let hasColumn = try db.columns(in: "users") .contains { $0.name == "email" } if !hasColumn { try db.execute(sql: """ ALTER TABLE users ADD COLUMN email TEXT ") } } // Apply migrations try migrator.migrate(dbQueue) ``` -------------------------------- ### Liquid Glass Navigation Example Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/swiftui-26-ref.md Demonstrates setting up a NavigationStack with a toolbar item and a searchable field using Liquid Glass patterns. ```swift NavigationStack { ContentView() .navigationTitle("Home") .toolbar { ToolbarItem(placement: .automatic) { Button("Add", systemImage: "plus") { } } } .searchable(text: $searchText) .searchFieldPlacement(.navigationBarDrawer(displayMode: .always)) } ``` -------------------------------- ### Add Delay to Animation Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/animation-ref.md Introduce a delay before an animation begins. This example waits 0.5 seconds before starting the spring animation. ```swift .animation(.spring.delay(0.5)) ``` -------------------------------- ### Record by Launching Application Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/xcprof-ref.md Launches an application from startup and records profiling data with a 10-second time limit. ```bash xcprof record --allow-launch --time-limit 10s -- /path/to/MyApp # launch from startup ``` -------------------------------- ### Manifest Download Policy: Prefetch Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/background-assets-ref.md JSON configuration for a prefetch download policy, starting during install and potentially continuing in the background. ```json "downloadPolicy": { "prefetch": { "installationEventTypes": ["firstInstallation", "subsequentUpdate"] } } ``` -------------------------------- ### SwiftUI App ModelContainer Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/swiftdata.md Set up the SwiftData ModelContainer for a SwiftUI application. This example shows how to configure the container for specific models. ```swift import SwiftUI import SwiftData @main struct MusicApp: App { var body: some Scene { WindowGroup { ContentView() } .modelContainer(for: [Track.self, Album.self]) } } ``` -------------------------------- ### Database Migrator Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/grdb.md Initializes a DatabaseMigrator and registers multiple migration steps to create tables, add columns, and create indexes. ```swift var migrator = DatabaseMigrator() // Migration 1: Create tables migrator.registerMigration("v1") { db in try db.create(table: "tracks") { t in t.column("id", .text).primaryKey() t.column("title", .text).notNull() t.column("artist", .text).notNull() t.column("duration", .real).notNull() } } // Migration 2: Add column migrator.registerMigration("v2_add_genre") { db in try db.alter(table: "tracks") { t in t.add(column: "genre", .text) } } // Migration 3: Add index migrator.registerMigration("v3_add_indexes") { db in try db.create(index: "idx_genre", on: "tracks", columns: ["genre"]) } // Run migrations try migrator.migrate(dbQueue) ``` -------------------------------- ### CloudKit Sync Basic Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/sqlitedata.md Sets up a `SyncEngine` for CloudKit synchronization. This involves defining a `DependencyKey` for the `SyncEngine` and preparing dependencies with the database and sync engine instances. ```swift import CloudKit extension DependencyValues { var defaultSyncEngine: SyncEngine { get { self[DefaultSyncEngineKey.self] } set { self[DefaultSyncEngineKey.self] = newValue } } } private enum DefaultSyncEngineKey: DependencyKey { static let liveValue = { @Dependency(\.defaultDatabase) var database return try! SyncEngine( for: database, tables: Item.self, privateTables: SensitiveItem.self, // Private database startImmediately: true ) }() } // In app init prepareDependencies { $0.defaultDatabase = try! appDatabase() $0.defaultSyncEngine = try! SyncEngine( for: $0.defaultDatabase, tables: Item.self ) } ``` -------------------------------- ### Get Subscription Status for a Transaction Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/storekit-ref.md Retrieve the subscription status for a specific transaction ID. This feature is available starting from iOS 18.4. ```swift let transactionID = transaction.id let status = try await Product.SubscriptionInfo.status(for: transactionID) ``` -------------------------------- ### Launch Instruments Tool Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-performance/skills/performance-profiling.md Opens the Instruments application. This is the first step in performance profiling. ```bash open -a Instruments ``` -------------------------------- ### Simple AppIntent Example Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/app-intents-ref.md Demonstrates the basic structure of an AppIntent, including its title and a simple parameter. This is the starting point for creating custom intents. ```APIDOC ## Simple AppIntent ### Description This is a basic example of an `AppIntent` struct, defining a title and a single parameter for ordering coffee. ### Method N/A (This is a code structure example) ### Endpoint N/A ### Request Body ```swift struct OrderCoffeeIntent: AppIntent { static var title: LocalizedStringResource = "Order Coffee" @Parameter(title: "Coffee Type") var coffeeType: CoffeeType func perform() async throws -> some IntentResult { // Order coffee logic here return .result() } } ``` ### Response N/A ``` -------------------------------- ### Create Minimal SwiftUI Previews Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/debugging-diag.md Start with an empty preview to verify basic rendering, then gradually add your view and its dependencies with mock data to isolate issues. ```swift // Start with empty preview #Preview { Text("Test") } // If this works, gradually add: #Preview { MyView() // Your actual view, but with mock data .environment(MockModel()) // Provide all dependencies } // Find which dependency causes crash ``` -------------------------------- ### Install Provisioning Profile Manually Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-security/skills/code-signing-ref.md Copies a provisioning profile file to the designated directory for manual installation. Ensure the profile is correctly named. ```bash cp MyProfile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/ ``` -------------------------------- ### Fastlane Matchfile Configuration Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/code-signing-ref.md Configure the 'Matchfile' for fastlane match to manage code signing certificates and provisioning profiles. This example shows setup for CI environments. ```ruby fastlane_version "2.195.0" default_platform(:ios) platform :ios do desc "Sync code signing assets" lane :sync_signing do match(type: "appstore", git_url: "https://github.com/your/repo.git", git_branch: "main") end end ``` -------------------------------- ### GitHub Actions CI Keychain Setup Source: https://github.com/charleswiltgen/axiom/blob/main/docs/reference/code-signing-ref.md Example script for setting up a Keychain in GitHub Actions for code signing. It includes creating, unlocking, and importing necessary certificates. ```bash steps: - name: Set up keychain uses: actions/setup-keychain@v1 with: keychain-name: "build.keychain" password: "${{ secrets.KEYCHAIN_PASSWORD }}" allow-root: true - name: Import certificate run: security import --allow-root --keychain build.keychain --password "${{ secrets.CERTIFICATE_PASSWORD }}" --file "./certificates/certificate.p12" ``` -------------------------------- ### List All Simulators Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-performance/skills/xctrace-ref.md Display a list of all available simulator devices, regardless of their booted state. ```bash # List all devices xcrun simctl list devices ``` -------------------------------- ### Initializing Language Model Session with Multiple Tools Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-ai/skills/foundation-models-ref.md Example of setting up a `LanguageModelSession` with an array of tools and a general instruction. The model autonomously decides which tools to call. ```swift let session = LanguageModelSession( tools: [ GetWeatherTool(), FindRestaurantTool(), FindHotelTool() ], instructions: "Plan travel itineraries." ) // Model autonomously decides which tools to call and when ``` -------------------------------- ### Create Relative EKAlarm Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/eventkit-ref.md Creates a time-based alarm set relative to an event's start time, specified in seconds. This example sets the alarm for 1 hour before. ```swift let relativeAlarm = EKAlarm(relativeOffset: -3600) // 1 hour before (seconds) ``` -------------------------------- ### Getting Capture Devices Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/camera-capture-ref.md Provides examples for obtaining default video and audio capture devices, as well as using a discovery session to find all available camera devices. ```swift // Default back camera AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) // Default front camera AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .front) // Default microphone AVCaptureDevice.default(for: .audio) // Discovery session for all cameras let discoverySession = AVCaptureDevice.DiscoverySession( deviceTypes: [.builtInWideAngleCamera, .builtInUltraWideCamera, .builtInTelephotoCamera], mediaType: .video, position: .unspecified ) let cameras = discoverySession.devices ``` -------------------------------- ### Session Setup and Photo Capture Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/camera-capture-ref.md Initializes an AVCaptureSession, configures it for photo capture with a back camera, and sets up a photo output. Includes an example of capturing a photo with specific settings. ```swift // SESSION SETUP import AVFoundation let session = AVCaptureSession() let sessionQueue = DispatchQueue(label: "camera.session") sessionQueue.async { session.beginConfiguration() session.sessionPreset = .photo guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back), let input = try? AVCaptureDeviceInput(device: camera), session.canAddInput(input) else { return } session.addInput(input) let photoOutput = AVCapturePhotoOutput() if session.canAddOutput(photoOutput) { session.addOutput(photoOutput) } session.commitConfiguration() session.startRunning() } // CAPTURE PHOTO var settings = AVCapturePhotoSettings() settings.photoQualityPrioritization = .balanced photoOutput.capturePhoto(with: settings, delegate: self) // ROTATION (iOS 17+) let coordinator = AVCaptureDevice.RotationCoordinator(device: camera, previewLayer: previewLayer) previewLayer.connection?.videoRotationAngle = coordinator.videoRotationAngleForHorizonLevelPreview ``` -------------------------------- ### Initialize and Configure PKCanvasView Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-uikit/skills/pencilkit-paperkit.md Set up a PKCanvasView, add it to your view hierarchy, and make it the first responder to display the PKToolPicker. Ensure you hold a strong reference to the PKToolPicker. ```swift import PencilKit final class DrawingViewController: UIViewController { private let canvasView = PKCanvasView() private let toolPicker = PKToolPicker() // hold a strong reference override func viewDidLoad() { super.viewDidLoad() canvasView.frame = view.bounds canvasView.drawingPolicy = .anyInput // allow finger + Simulator drawing view.addSubview(canvasView) toolPicker.addObserver(canvasView) // canvas reacts to tool changes toolPicker.setVisible(true, forFirstResponder: canvasView) canvasView.becomeFirstResponder() // REQUIRED — or the picker won't appear } } ``` -------------------------------- ### Build and Launch Instruments Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/debugging-diag.md Steps to build your app in Release mode and launch the Instruments tool with the SwiftUI template. ```bash # Build Release xcodebuild build -scheme YourScheme -configuration Release # Launch Instruments # Press Command-I in Xcode # Choose "SwiftUI" template ``` -------------------------------- ### Verify Developer Toolkit Setup for Adapter Export Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-ai/skills/foundation-models-adapters-diag.md Check Python version, environment, and coremltools installation on the developer Mac. Essential for diagnosing toolkit-setup failures during adapter export. ```bash python --version # MUST be 3.11.x — record exact which python # MUST be inside the active conda/venv env python -c "import coremltools; print(coremltools.__version__)" # Must succeed; record version uname -m # arm64 expected for Apple silicon Mac export ``` -------------------------------- ### Hang Diagnosis Decision Tree Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-performance/skills/hang-diagnostics.md A decision tree to guide the diagnosis of app hangs, starting from reported hangs and progressing through available data and reproduction steps to tool selection. ```text START: App hangs reported │ ├─→ Do you have hang diagnostics from Organizer or MetricKit? │ │ │ ├─→ YES: Examine stack trace │ │ │ │ │ ├─→ Stack shows your code running │ │ │ → BUSY: Main thread doing work │ │ │ → Profile with Time Profiler │ │ │ │ │ └─→ Stack shows waiting (semaphore, lock, dispatch_sync) │ │ → BLOCKED: Main thread waiting │ │ → Profile with System Trace │ │ │ └─→ NO: Can you reproduce? │ │ │ ├─→ YES: Profile with Time Profiler first │ │ │ │ │ ├─→ High CPU on main thread │ │ │ → BUSY: Optimize the work │ │ │ │ │ └─→ Low CPU, thread blocked │ │ → Use System Trace to find what's blocking │ │ │ └─→ NO: Enable MetricKit in app │ → Wait for field reports │ → Check Organizer > Hangs ``` -------------------------------- ### Manage Tutorial Asset Pack Lifecycle Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-integration/skills/background-assets-ref.md Demonstrates the lifecycle management of a tutorial asset pack, including ensuring its availability, retrieving file descriptors, and removing it. ```swift import BackgroundAssets @MainActor final class TutorialAssetController { static let packID = "Tutorial" func ensureReady() async throws { let pack = try await AssetPackManager.shared.assetPack(withID: Self.packID) try await AssetPackManager.shared.ensureLocalAvailability(of: pack) } func video() throws -> FileDescriptor { try AssetPackManager.shared.descriptor( for: "Videos/Introduction.m4v", searchingInAssetPackWithID: Self.packID ) } func dispose() async throws { try await AssetPackManager.shared.remove(assetPackWithID: Self.packID) } } ``` -------------------------------- ### Decision Tree for Build Failure Diagnosis Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-fix-build/SKILL.md This flowchart guides the user through a series of checks and potential fixes for common Xcode build failures, starting with mandatory environment checks. ```text User reports build failure ↓ Run mandatory checks (directory, processes, Derived Data, simulators) ↓ Identify issue: ├─ No project/workspace file → Report "wrong directory" to user ├─ (following checks apply if directory verified) ↓ ├─ 10+ xcodebuild processes OR any process > 30min → Kill zombie processes (§1) ├─ Derived Data > 10GB → Clean Derived Data + rebuild (§2) ├─ "No such module" (SPM) → Clean SPM cache + resolve packages (§3) ├─ "No such module" (local) → Clean Derived Data + rebuild (§2) ├─ Package resolution failures → Clean SPM cache (§3) ├─ Intermittent failures → Clean Derived Data + rebuild (§2) ├─ Old code executing → Clean Derived Data + rebuild (§6) ├─ "Unable to boot simulator" → Shutdown/erase simulator (§4) ├─ Tests failing (no code changes) → Clean + retest (§5) └─ All checks clean → Report "environment is clean, likely code issue" ``` -------------------------------- ### Example Screenshot Capture and Analysis Source: https://github.com/charleswiltgen/axiom/blob/main/docs/commands/testing/screenshot.md This example demonstrates the typical interaction when using the /axiom:screenshot command. The user initiates the command, and Claude responds with the captured screenshot's file path and an analysis of the UI. ```bash # User runs command /axiom:screenshot ``` ```text # Claude responds: "Screenshot captured: /tmp/axiom-screenshot-2025-12-08-14-30-45.png Looking at the screenshot, I can see the login screen with the email and password fields. The 'Sign In' button appears centered and properly sized. The logo at the top is correctly positioned with adequate spacing." ``` -------------------------------- ### Testing Deep Links with Simulator Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swift/skills/deep-link-debugging.md These commands demonstrate how to boot a simulator, launch an app, and test deep links using xcrun simctl. ```bash # Boot simulator xcrun simctl boot "iPhone 16 Pro" # Launch app xcrun simctl launch booted com.example.YourApp # Test each deep link xcrun simctl openurl booted "debug://settings" xcrun simctl openurl booted "debug://profile?id=123" ``` -------------------------------- ### CKSyncEngine Setup and Delegate Implementation Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/cloudkit-ref.md Initialize CKSyncEngine with a configuration, including the database, state serialization, and a delegate to handle sync events. Implement the CKSyncEngineDelegate protocol to manage state updates, account changes, and database/record zone changes. ```swift import CloudKit class SyncManager { let syncEngine: CKSyncEngine init() throws { let config = CKSyncEngine.Configuration( database: CKContainer.default().privateCloudDatabase, stateSerialization: loadSyncState(), delegate: self ) syncEngine = try CKSyncEngine(config) } // Implement delegate methods } extension SyncManager: CKSyncEngineDelegate { // Handle events func handleEvent(_ event: CKSyncEngine.Event, syncEngine: CKSyncEngine) async { switch event { case .stateUpdate(let stateUpdate): saveSyncState(stateUpdate.stateSerialization) case .accountChange(let change): handleAccountChange(change) case .fetchedDatabaseChanges(let changes): applyDatabaseChanges(changes) case .fetchedRecordZoneChanges(let changes): applyRecordChanges(changes) case .sentRecordZoneChanges(let changes): handleSentChanges(changes) case .willFetchChanges, .didFetchChanges, .willSendChanges, .didSendChanges: // Optional lifecycle events break @unknown default: break } } // Next batch of changes to send func nextRecordZoneChangeBatch( _ context: CKSyncEngine.SendChangesContext, syncEngine: CKSyncEngine ) async -> CKSyncEngine.RecordZoneChangeBatch? { // Return pending local changes let pendingChanges = getPendingLocalChanges() return CKSyncEngine.RecordZoneChangeBatch( pendingSaves: pendingChanges, recordIDsToDelete: [] ) } } ``` -------------------------------- ### Coordinate Audio and Haptic Playback Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/haptics.md Synchronizes audio playback with haptic feedback. A small delay is introduced to ensure both start at the exact same moment. Requires `AVFoundation` and haptic engine setup. ```swift import AVFoundation class AudioHapticCoordinator { let audioPlayer: AVAudioPlayer let hapticEngine: CHHapticEngine func playCoordinatedExperience() { // Prepare both systems hapticEngine.notifyWhenPlayersFinished { _ in return .stopEngine } // Start at exact same moment let startTime = CACurrentMediaTime() + 0.05 // Small delay for sync // Start audio audioPlayer.play(atTime: startTime) // Start haptic if let pattern = loadAHAPPattern(named: "CoordinatedPattern") { let player = try? hapticEngine.makePlayer(with: pattern) try? player?.start(atTime: CHHapticTimeImmediate) } } } ``` -------------------------------- ### NWConnection Example (Before) Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-networking/skills/networking-migration.md Demonstrates the older NWConnection API using completion handlers for state updates, sending, and receiving data. Requires manual memory management with [weak self]. ```swift // BEFORE — Completion handlers, manual memory management let connection = NWConnection(host: "example.com", port: 443, using: .tls) connection.stateUpdateHandler = { [weak self] state in switch state { case .ready: self?.sendData() case .waiting(let error): print("Waiting: \(error)") case .failed(let error): print("Failed: \(error)") default: break } } connection.start(queue: .main) func sendData() { let data = Data("Hello".utf8) connection.send(content: data, completion: .contentProcessed { [weak self] error in if let error = error { print("Send error: \(error)") return } self?.receiveData() }) } func receiveData() { connection.receive(minimumIncompleteLength: 10, maximumLength: 10) { [weak self] (data, context, isComplete, error) in if let error = error { print("Receive error: \(error)") return } if let data = data { print("Received: \(data)") } } } ``` -------------------------------- ### Conflicting Horizontal Constraints in Swift Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-uikit/skills/auto-layout-debugging.md Demonstrates a common Auto Layout conflict where fixed width, leading, and trailing constraints are applied to the same view, leading to over-constraint. This example shows the incorrect setup. ```swift // Conflicting constraints imageView.widthAnchor.constraint(equalToConstant: 300).isActive = true imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20).isActive = true imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20).isActive = true // Over-constrained: width + leading + trailing = 3 horizontal constraints (only need 2) ``` -------------------------------- ### Add Axiom MCP Server for Claude Code Users Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-mcp/README.md Install the Axiom plugin for Claude Code. The MCP server starts automatically, launching in development mode without additional configuration. ```bash claude-code plugin add axiom@axiom-marketplace ``` -------------------------------- ### NSWritingToolsCoordinator Setup (AppKit) Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-uikit/skills/textkit-ref.md Illustrates the setup process for NSWritingToolsCoordinator in an AppKit application, showing how to assign the delegate and associate the coordinator with a custom view. ```APIDOC ## Setup (AppKit) ```swift // AppKit let coordinator = NSWritingToolsCoordinator() coordinator.delegate = self customView.writingToolsCoordinator = coordinator ``` ``` -------------------------------- ### Boot Simulator by Name Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-test-simulator/SKILL.md Boots a specific simulator identified by its name. Ensure the simulator name is accurate. ```bash xcrun simctl boot "iPhone 16 Pro" ``` -------------------------------- ### Complete Camera Manager Implementation Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/camera-capture-ref.md This Swift class manages the AVFoundation capture session, including setup, starting, stopping, and photo capture. It requires `AVFoundation` and is designed to be run on the main actor. ```swift import AVFoundation @MainActor class CameraManager: NSObject, ObservableObject { let session = AVCaptureSession() let photoOutput = AVCapturePhotoOutput() private let sessionQueue = DispatchQueue(label: "camera.session") private var rotationCoordinator: AVCaptureDevice.RotationCoordinator? private var rotationObservation: NSKeyValueObservation? @Published var isSessionRunning = false func setup() async -> Bool { guard await AVCaptureDevice.requestAccess(for: .video) else { return false } return await withCheckedContinuation { continuation in sessionQueue.async { [self] in session.beginConfiguration() defer { session.commitConfiguration() } session.sessionPreset = .photo guard let camera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back), let input = try? AVCaptureDeviceInput(device: camera), session.canAddInput(input) else { continuation.resume(returning: false) return } session.addInput(input) guard session.canAddOutput(photoOutput) else { continuation.resume(returning: false) return } session.addOutput(photoOutput) photoOutput.maxPhotoQualityPrioritization = .quality continuation.resume(returning: true) } } } func start() { sessionQueue.async { [self] in session.startRunning() DispatchQueue.main.async { self.isSessionRunning = self.session.isRunning } } } func stop() { sessionQueue.async { [self] in session.stopRunning() DispatchQueue.main.async { self.isSessionRunning = false } } } func capturePhoto() { var settings = AVCapturePhotoSettings() settings.photoQualityPrioritization = .balanced if let connection = photoOutput.connection(with: .video), let angle = rotationCoordinator?.videoRotationAngleForHorizonLevelCapture { connection.videoRotationAngle = angle } photoOutput.capturePhoto(with: settings, delegate: self) } } extension CameraManager: AVCapturePhotoCaptureDelegate { nonisolated func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { guard let data = photo.fileDataRepresentation() else { return } // Handle photo data } } ``` -------------------------------- ### SwiftUI Navigation Setup Steps Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-swiftui/skills/nav.md These are the mandatory first steps before implementing navigation in your SwiftUI application. They involve identifying the navigation structure, choosing the appropriate container, defining value types, and planning for deep linking and state restoration. ```swift // Step 1: Identify your navigation structure // Ask: Single stack? Multi-column? Tab-based with per-tab navigation? // Record answer before writing any code // Step 2: Choose container based on structure // Single stack (iPhone-primary): NavigationStack // Multi-column (iPad/Mac-primary): NavigationSplitView // Tab-based: TabView with NavigationStack per tab // Step 3: Define your value types for navigation // All values pushed on NavigationStack must be Hashable // For deep linking/restoration, also Codable struct Recipe: Hashable, Codable, Identifiable { ... } // Step 4: Plan deep link URLs (if needed) // myapp://recipe/{id} // myapp://category/{name}/recipe/{id} // Step 5: Plan state restoration (if needed) // Will you use SceneStorage? What data must be Codable? ``` -------------------------------- ### Check Threading for Session Operations Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/camera-capture-diag.md Verifies that session setup and starting operations are performed on a background thread, not the main thread, to prevent UI freezes. This check is crucial for maintaining application responsiveness. ```swift print("🧵 Thread check:") // When setting up session sessionQueue.async { print(" Setup thread: \(Thread.isMainThread ? \"❌ MAIN\" : \"✅ Background\")") } // When starting session sessionQueue.async { print(" Start thread: \(Thread.isMainThread ? \"❌ MAIN\" : \"✅ Background\")") } ``` -------------------------------- ### DatabasePool Setup Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-data/skills/grdb.md Initialize a DatabasePool for applications requiring heavy concurrent database access from multiple threads. ```swift // For apps with heavy concurrent access let dbPool = try DatabasePool(path: dbPath) ``` -------------------------------- ### Correct Audio Session Setup for Now Playing Source: https://github.com/charleswiltgen/axiom/blob/main/axiom-codex/skills/axiom-media/skills/now-playing.md Use a non-mixable category and activate the audio session before starting playback to ensure Now Playing info appears on the lock screen. Deactivate the session when playback stops. ```swift // ✅ CORRECT — Non-mixable category, activated before playback class PlayerService { func setupAudioSession() throws { try AVAudioSession.sharedInstance().setCategory( .playback, mode: .default, options: [] // ✅ No .mixWithOthers = eligible for Now Playing ) } func play() async throws { // ✅ Activate BEFORE starting playback try AVAudioSession.sharedInstance().setActive(true) player.play() updateNowPlaying() // ✅ Now appears correctly } func stop() async throws { player.pause() // ✅ Deactivate AFTER stopping, with notify option try AVAudioSession.sharedInstance().setActive( false, options: .notifyOthersOnDeactivation ) } } ```