my-toybox
!Simulator Screenshot - iPad Pro 13-inch (M4) - 2025-05-11 at 15 32 02
my-toybox is an experimental iOS/macOS app project that showcases a wide variety of SwiftUI and Metal-based visual effects and animations. It acts as a sandbox or "toybox" of interactive screens where you can explore different UI techniques and graphics rendering approaches.
📎 Try it instantly with App Clip (iOS only)
Overview
- Languages & Frameworks: Swift 6.3, SwiftUI, Metal
- Project Format: Xcode workspace (
MyToybox.xcworkspace) - Platform: iOS 18+ (iPhone/iPad), macOS 15+
- Recommended: Xcode 26.4.1 or later
AppScreen enum and rendered using SwiftUI and, in some cases, custom Metal shaders.
Key Features
🔹 Dozens of Sample Screens
Each screen lives underPackages/Sources/Screens// and showcases a specific animation, layout, or rendering technique.
The screen list is defined in Packages/Sources/AppScreens/AppScreen.swift.
Each case name in enum AppScreen must be a valid Swift identifier in lowerCamelCase (e.g. gameOfLifeScreen).
🔹 SPM Build Tool Plugins
This project uses SPM plugins to automatically compile resources during build:| Plugin | Input | Output |
|--------|-------|--------|
| BuildMetalShaders | .metal files | default.metallib (compiled shaders) |
The @Screens macro (ScreenMacros) converts each AppScreen case into a corresponding View type.
🔹 Metal Shaders
Some effects (like mosaic or particle waves) are implemented with.metal shader files using SwiftUI's shader support.
🔹 Modern SwiftUI & Concurrency
- Uses
async/awaitfor loading screen metadata asynchronously. - Applies
@Observablefor reactive state management. - Embraces SwiftUI idioms like
NavigationSplitViewfor adaptive layouts.
🔹 Adaptive Navigation
- On iPad or in landscape, a sidebar and detail panel are shown via
NavigationSplitView. - On compact devices (e.g., iPhones in portrait), tapping a screen pushes to its detail view.
- The first screen auto-selects by default on regular-width devices.
Project Structure
my-toybox/
├─ MyToybox.xcworkspace/ # Xcode workspace (open with xed .)
├─ Makefile # Build commands (see below)
├─ App/
│ ├─ MyToybox.xcodeproj/ # Xcode project
│ └─ MyToybox/
│ ├─ App.swift # Entry point of the app
│ └─ Resources/
│ └─ Assets.xcassets/ # App icons and image assets
├─ Packages/ # Swift Package
│ ├─ Package.swift # Swift Package definition
│ ├─ Plugins/
│ │ └─ BuildMetalShaders/ # SPM plugin for Metal compilation
│ ├─ Sources/
│ │ ├─ MyToyboxCore/ # Core protocols and shared utilities
│ │ │ ├─ ScreenMetadata.swift # Protocol defining screen metadata & thumbnail
│ │ │ ├─ Tag.swift # Tag enum for screen categorization
│ │ │ ├─ ThumbnailView.swift # Reusable thumbnail view wrapper
│ │ │ └─ DeepLinkSheet.swift # URL-based deep link handling
│ │ ├─ AppScreens/ # AppScreen.swift enum; wires all screen modules
│ │ ├─ ClipScreens/ # App Clip screen catalog (subset)
│ │ ├─ MockScreens/ # Mock screen catalog for previews/testing
│ │ ├─ PlatformSupport/ # Platform abstraction (PlatformViewRepresentable)
│ │ ├─ MyToyboxMedia/ # Shared media for shader-based screens
│ │ └─ Screens/ # One SPM module per screen (SwiftUI + optional Metal)
│ │ ├─ RootScreen/ # Root navigation shell (sidebar, split, compact layouts)
│ │ ├─ DetailScreen/ # Detail view for individual screens
│ │ ├─ TagPicker/ # Tag filter UI (SPM module TagPicker)
│ │ └─ … # Other screen modules (Badge, GameOfLife, …)
│ └─ Tests/
│ └─ MyToyboxCoreTests/ # Unit tests for core module
├─ MetadatasMacros/ # @Metadatas / @Metadata macro package
├─ ScreenMacros/ # @Screens / @Screen macro package
└─ Scripts/
├─ build_metallib.sh # Metal shader build script (used by plugin)
├─ new_screen.sh # Script to create new screens
└─ check_screen_sync.sh # Validates screen consistency
Key Files:
App.swift: The app's@mainentry point, launching theRootScreen.Packages/Sources/Screens/RootScreen/RootScreen.swift: The master-detail view listing all available screens.Packages/Sources/Screens/RootScreen/RootScreenModel.swift: Handles sidebar selection and tag filtering state for the catalog.Packages/Sources/AppScreens/AppScreen.swift: Enum defining all available screens with their metadata.
Getting Started
1. Clone the repository
git clone https://github.com/Koshimizu-Takehito/my-toybox.git
cd my-toybox
2. Open in Xcode
make open
or
xed .
- This opens
MyToybox.xcworkspacecontaining both the app and SPM packages. - Or open
Packages/Package.swiftfor SPM-only development.
Note: Metal shaders are automatically compiled by SPM plugins during build.
3. Build and run
- Choose a simulator or real device and run the app via Xcode.
Makefile Commands
This project includes a Makefile for common development tasks:
| Command | Description |
|---------|-------------|
| make help | Show available commands |
| make open | Open project in Xcode |
| make setup | Install Mint (if needed) and dependencies |
| make sync | Pull latest changes and update dependencies |
| make new-screen | Create a new screen (interactive) |
| make new-screen NAME=Foo | Create a new screen named Foo |
| make new-screen NAME=Foo SHADER=yes | Create a new screen with Metal shader |
| make lint | Run SwiftLint |
| make lint-fix | Run SwiftLint with auto-correction |
| make lint-strict | Run SwiftLint treating warnings as errors (for CI) |
| make format | Format code with SwiftFormat |
| make format-check | Check code formatting (no changes) |
| make fix | Format and auto-fix all code |
| make clean | Remove build artifacts |
| make fastlane-setup | Install fastlane and pull current App Store metadata |
| make metadata-pull | Pull latest metadata & screenshots from App Store Connect |
| make metadata-precheck | Validate local metadata without uploading |
| make metadata-push | Upload metadata, screenshots, and release notes to ASC |
Creating a New Screen
# Interactive mode
make new-screen
Direct creation
make new-screen NAME=MyNewAnimation
With Metal shader support
make new-screen NAME=MyShaderEffect SHADER=yes
make new-screen generates a per-module Resources/Localizable.xcstrings for the new screen with screen. / screen. keys. Each screen module owns its own localization catalog and resolves symbols through its own bundle.
Localization workflow
For localization policy, semantic key rules, and CI enforcement details, see:
LOCALIZATION_WORKFLOW.md
App Store metadata management
Builds are uploaded by Xcode Cloud. App Store Connect metadata
(description, keywords, screenshots, release notes, etc.) is managed
through fastlane deliver in metadata-only mode — no binary upload.
Local
- Place your App Store Connect API key as
fastlane/AuthKey_(gitignored)..p8 cp .env.template .envand fill inASC_KEY_ID/ASC_ISSUER_ID(the.envfile is gitignored and auto-loaded bymake).- Run
make fastlane-setupto install fastlane and pull the current ASC metadata intofastlane/metadata/andfastlane/screenshots/. - Edit, then
make metadata-precheckandmake metadata-push.
fastlane/README.md for details.
CI (GitHub Actions)
Workflow .github/workflows/app-store-metadata.yml runs the same make metadata-*
targets on demand via workflow_dispatch. Credentials are stored as Environment
secrets under the app-store-connect environment with required reviewers:
ASC_KEY_ID— API Key IDASC_ISSUER_ID— Issuer IDASC_KEY_BASE64—.p8encoded withbase64 -i AuthKey_XXX.p8
pull mode opens an automated PR (chore/metadata-pull) against develop.
How to Use
- On launch, the app displays a list of demo screens.
- Tap (or click) a screen to open it in the detail panel or navigation stack.
- On iPads or large screens, you'll see both the sidebar and selected content side-by-side.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
- Maintained by: Koshimizu-Takehito