SwiftKickMobile/SwiftMessages
A very flexible message bar for UIKit and SwiftUI.
Slowing — last commit 3mo ago
worst of 4 axesno tests detected; no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3mo ago
- ✓15 active contributors
- ✓MIT licensed
Show 4 more →Show less
- ⚠Slowing — last commit 3mo ago
- ⚠Single-maintainer risk — top contributor 80% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: add a test suite
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/swiftkickmobile/swiftmessages)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/swiftkickmobile/swiftmessages on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: SwiftKickMobile/SwiftMessages
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/SwiftKickMobile/SwiftMessages shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Slowing — last commit 3mo ago
- Last commit 3mo ago
- 15 active contributors
- MIT licensed
- ⚠ Slowing — last commit 3mo ago
- ⚠ Single-maintainer risk — top contributor 80% of recent commits
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live SwiftKickMobile/SwiftMessages
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/SwiftKickMobile/SwiftMessages.
What it runs against: a local clone of SwiftKickMobile/SwiftMessages — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in SwiftKickMobile/SwiftMessages | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 134 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of SwiftKickMobile/SwiftMessages. If you don't
# have one yet, run these first:
#
# git clone https://github.com/SwiftKickMobile/SwiftMessages.git
# cd SwiftMessages
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of SwiftKickMobile/SwiftMessages and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "SwiftKickMobile/SwiftMessages(\\.git)?\\b" \\
&& ok "origin remote is SwiftKickMobile/SwiftMessages" \\
|| miss "origin remote is not SwiftKickMobile/SwiftMessages (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "SwiftMessages/MessageView.swift" \\
&& ok "SwiftMessages/MessageView.swift" \\
|| miss "missing critical file: SwiftMessages/MessageView.swift"
test -f "SwiftMessages/Presenter.swift" \\
&& ok "SwiftMessages/Presenter.swift" \\
|| miss "missing critical file: SwiftMessages/Presenter.swift"
test -f "SwiftMessages/MessageHostingView.swift" \\
&& ok "SwiftMessages/MessageHostingView.swift" \\
|| miss "missing critical file: SwiftMessages/MessageHostingView.swift"
test -f "SwiftMessages/PassthroughWindow.swift" \\
&& ok "SwiftMessages/PassthroughWindow.swift" \\
|| miss "missing critical file: SwiftMessages/PassthroughWindow.swift"
test -f "SwiftMessages/Animator.swift" \\
&& ok "SwiftMessages/Animator.swift" \\
|| miss "missing critical file: SwiftMessages/Animator.swift"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 134 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~104d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/SwiftKickMobile/SwiftMessages"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
SwiftMessages is a flexible UIKit and SwiftUI message presentation library that displays notification bars, cards, and dialogs at configurable screen positions (top, bottom, center, behind nav/tab bars). It provides pre-built nib-based layouts (cardView, messageView), physics-based dismiss gestures, dimming modes, and full customization via subclassing or arbitrary UIView/View injection — solving the problem of building polished, reusable notifications without reinventing animation and layout logic. Standard iOS framework layout: /Demo contains a reference app with ViewControllers (ExploreViewController.swift, ViewController.swift, etc.) and custom views (CountedMessageView.swift, TacoDialogView.swift + .xib). Core framework code is in a separate SwiftMessages.xcodeproj (not shown in detail but implied by demo's dependency). Nib-based layouts are included and can be copied into user projects for customization.
👥Who it's for
iOS developers building UIKit and SwiftUI apps who need to display user-facing messages (alerts, errors, success notifications, in-app toasts) with minimal boilerplate and maximum visual polish. Design-conscious teams can fork nib files and customize layouts without touching framework code.
🌱Maturity & risk
Production-ready and actively maintained. Written primarily in Swift (185KB), with Objective-C legacy code (534B) and Ruby build scripts (2.5KB). Distributed via CocoaPods, Carthage, and Swift Package Manager. The presence of a polished Demo app, multiple layout nib files, and version badges indicate maturity; latest README mentions SwiftUI support updates as of Xcode 26, showing recent activity.
Low risk for most projects. Single maintainer (TimothyMoose per README badge) is a potential concern for critical production apps, but the framework is relatively stable with no visible breaking changes in recent history. No visible test directory in the file list is a minor gap; integration tests would strengthen confidence. Dependency count unknown from file list, but CocoaPods/SPM distribution suggests minimal external dependencies.
Active areas of work
SwiftUI support is being actively developed; the README explicitly notes SwiftUI support requires Xcode 26 update 10.0.2, indicating recent feature work. No specific open PRs or milestones visible in the file list, but the CHANGELOG.md and frequent Demo updates suggest ongoing maintenance.
🚀Get running
Clone the repo: git clone https://github.com/SwiftKickMobile/SwiftMessages.git. Install via CocoaPods (pod install in Demo/), Carthage (carthage update), or Swift Package Manager (File → Add Package Dependency in Xcode). Open Demo/Demo.xcodeproj and run the Demo target on a simulator or device to see all layouts and features in action.
Daily commands: Open Demo/Demo.xcodeproj in Xcode, select the Demo scheme, and press Cmd+R (or use Product → Run). The Demo app demonstrates all message layouts, dismiss gestures, and configuration options via ViewController.swift and ExploreViewController.swift. No external server or build step required.
🗺️Map of the codebase
SwiftMessages/MessageView.swift— Core message view implementation; foundational for all message presentations and stylingSwiftMessages/Presenter.swift— Central orchestrator for message display logic, layout calculations, and dismiss handlingSwiftMessages/MessageHostingView.swift— SwiftUI integration layer; bridges SwiftUI content into UIKit-based message systemSwiftMessages/PassthroughWindow.swift— Window management for message overlay; critical for z-order and event handlingSwiftMessages/Animator.swift— Animation engine for message entrance/exit; handles physics-based and standard transitionsSwiftMessages/PhysicsAnimation.swift— Physics simulation for interactive dismiss gestures; core interactive feature
🧩Components & responsibilities
- Presenter — Central state machine: receives show() calls, calculates layout, orchestrates Animator, manages window lifecycle, handles
🛠️How to make changes
Add a Custom Message View
- Create a new UIView subclass conforming to MessageViewConvertible protocol (
SwiftMessages/MessageViewConvertible.swift) - Implement configureContent(background:) to set up your custom view hierarchy and styling (
SwiftMessages/BaseView.swift) - In your app, instantiate SwiftMessages, set your custom view via messageView property, and call show() (
SwiftMessages/Presenter.swift)
Add SwiftUI Message Content
- Create a SwiftUI View struct with your message design (
Demo/Demo/ViewController.swift) - Wrap it using MessageHostingView(message: view) to embed in UIKit message system (
SwiftMessages/MessageHostingView.swift) - Configure MessagePresentation with animationMode, position, and other settings (
SwiftMessages/Presenter.swift)
Implement Physics-Based Dismiss Gesture
- Set animationMode to .interactivePhysics in MessagePresentation config (
SwiftMessages/Presenter.swift) - PhysicsAnimation will be activated automatically; tune damping/velocity in PhysicsAnimation (
SwiftMessages/PhysicsAnimation.swift) - Pan gestures are routed through PhysicsPanHandler for interactive simulation (
SwiftMessages/PhysicsPanHandler.swift)
Adjust Margin Around Safe Areas
- Have your message view conform to MarginAdjustable protocol (
SwiftMessages/MarginAdjustable.swift) - Implement layoutMargins property and use in Auto Layout constraints (
SwiftMessages/MarginAdjustable+Extensions.swift) - Presenter will call marginsAdjusted() automatically during layout (
SwiftMessages/Presenter.swift)
🔧Why these technologies
- UIView subclassing with XIB templates — Provides flexible pre-built message layouts (CardView, TabView, StatusLine) that developers can customize or replace entirely
- CADisplayLink for physics animation — Enables smooth 60fps physics-based gesture interaction with realistic momentum and damping
- Custom PassthroughWindow (UIWindow subclass) — Allows message overlay to sit above other UI elements while forwarding touch events to underlying views, avoiding input blocking
- MessageViewConvertible protocol — Decouples message content from presentation logic; any UIView can be a message without inheritance
- MessageHostingView (UIHostingController wrapper) — Bridges SwiftUI into UIKit message pipeline, enabling modern SwiftUI content in traditional UIKit apps
⚖️Trade-offs already made
-
PassthroughWindow overlay approach vs. View Controller presentation
- Why: Overlay allows precise z-order control and positioning (top, bottom, center, behind nav/tab bars) without View Controller stack complexity
- Consequence: Adds window management complexity and requires careful event forwarding, but gains flexibility in positioning
-
Physics simulation in CADisplayLink vs. UIView animations
- Why: Physics-based dismiss is interactive and responsive to user velocity; standard animations are deterministic
- Consequence: More code complexity in PhysicsAnimation, but provides premium user experience for interactive gestures
-
Presenter orchestrates both layout and animation
- Why: Centralizes state machine for show/hide lifecycle and prevents race conditions
- Consequence: Presenter becomes larger; tight coupling between layout and animation, but reduced bugs from state inconsistency
🚫Non-goals (don't propose these)
- Does not provide native SwiftUI View API at the top level; uses UIView/UIHostingController bridging
- Not a notification center replacement; no persistent notification queue or priority system
- Does not handle authentication or permissions
- Not responsible for keyboard management beyond KeyboardTrackingView observation
- Not a form validation library; messages are presentation-only
🪤Traps & gotchas
No visible Podfile.lock or package-resolved files, so exact pinned dependency versions are unknown — first pod install may pull different transitive versions. SwiftUI support requires Xcode 26 update 10.0.2 specifically; older Xcode versions may silently fail on SwiftUI code paths. Nib files must be copied into your project's main bundle for MessageView.viewFromNib() to find them — if placed in a Framework bundle, the search fails. No visible unit tests or integration tests in the file list, making it harder to validate custom layout changes.
🏗️Architecture
💡Concepts to learn
- View Hierarchies & Window Management — SwiftMessages must inject message views above navigation controllers, tab bars, and status bars; understanding UIWindow, rootViewController, and subview ordering is critical for correct positioning and z-order handling.
- Nib-Based Layout Loading — SwiftMessages uses .xib files (Interface Builder) for pre-built layouts (TacoDialogView.xib, MessageView nib files). Understanding UINib, instantiateWithOwner:options:, and File's Owner wiring is essential for customization.
- Physics-Based Animation & Gesture Recognition — The framework advertises 'fun, physics-based' dismiss gestures; this likely uses UISnapBehavior, UIDynamicAnimator, or UIPanGestureRecognizer with spring dynamics for realistic motion.
- View Controller Presentation Lifecycle — SwiftMessages must coordinate with UIViewController's viewWillAppear, viewDidAppear, viewWillDisappear for correct timing of animations and state transitions; lifecycle misalignment causes flicker or missed dismissal.
- Auto Layout & Constraint-Based Positioning — Message views must adapt to safe areas, notches, and landscape rotation; Auto Layout (NSLayoutConstraint, NSLayoutAnchor) ensures messages position correctly behind tab bars and nav bars without hardcoded coordinates.
- SwiftUI View Wrapping (UIViewControllerRepresentable) — SwiftMessages bridges UIKit and SwiftUI; understanding how to wrap UIView/UIViewController in SwiftUI via UIViewControllerRepresentable is required for proper SwiftUI integration patterns.
- CABasicAnimation & Core Animation — Smooth message entry/exit animations are powered by Core Animation, not just UIView.animate(); CABasicAnimation allows fine-grained control over timing curves and keyframe paths for entrance animations.
🔗Related repos
toast-swift/Toast-Swift— Lightweight Swift toast notifications; lighter alternative if you need minimal customization and no dismissal gesturesthii/Notchmeister— Displays notifications behind notches and Dynamic Islands on modern iPhones; complements SwiftMessages for edge-case layoutspointfreeco/swiftui-navigation— Companion library for SwiftUI-first apps using SwiftMessages; provides state management patterns for message presentationrealm/SwiftLint— Code style enforcement for Swift projects; commonly paired with SwiftMessages development to enforce consistent formatting in custom layoutsapple/swift-package-manager— SwiftMessages distributes via SPM; understanding SPM fundamentals helps debug package resolution and local development workflows
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for SwiftUI message presentation
The repo supports both UIKit and SwiftUI (as mentioned in README with 'UPDATE: SwiftUI support in Xcode 26 requires 10.0.2'), but there's no visible test directory structure in the file list. SwiftUI presentation logic differs significantly from UIKit, and comprehensive unit tests would catch regressions in SwiftUI view lifecycle, state management, and presentation transitions. This is critical for maintaining compatibility across both frameworks.
- [ ] Create Tests/ directory structure in SwiftMessages.xcodeproj
- [ ] Add test targets for SwiftUIPresenterTests covering view initialization, dismissal, and state updates
- [ ] Add integration tests verifying SwiftUI views render correctly with different message styles and positions (top/bottom/center)
- [ ] Test SwiftUI modifier behavior and custom view bindings
Add GitHub Actions CI workflow for iOS builds and tests
The repo has CocoaPods, Carthage, and Swift Package Manager support (Package.swift exists), but there's no visible CI configuration. A GitHub Actions workflow would automatically validate builds across different dependency managers and iOS versions, catching integration issues early. This is especially important for a library supporting multiple iOS versions and two UI frameworks.
- [ ] Create .github/workflows/ios-build.yml with matrix testing for iOS 13+ versions
- [ ] Include CocoaPods (using Demo/Podfile), Carthage, and SPM build steps
- [ ] Run unit tests and generate code coverage reports
- [ ] Add workflow status badge to README.md
Document SwiftUI API with code examples in README
The README mentions SwiftUI support is required but provides no SwiftUI usage examples or API documentation. The file structure shows Demo/ with ViewControllers for UIKit (ExploreViewController.swift, TacoDialogView.xib), but no corresponding SwiftUI demo views. Adding concrete SwiftUI examples would significantly improve discoverability and adoption, especially for new developers unfamiliar with the library.
- [ ] Add 'SwiftUI Usage' section to README.md with code examples showing basic message presentation
- [ ] Create Demo/Demo/SwiftUIExamplesView.swift showcasing top/bottom/center positions and custom views
- [ ] Document differences between UIKit and SwiftUI APIs in README
- [ ] Include example of view modifiers, binding state management, and dismissal patterns
🌿Good first issues
- Add a Swift unit test suite for MessageView configuration and presentation logic — currently no test directory exists. Start with Demo/Demo/ViewController.swift patterns to create Tests/MessageViewTests.swift covering show(), hide(), and configuration edge cases.
- Document the nib-to-custom-layout workflow with a step-by-step guide and example. Currently, TacoDialogView.xib exists but lacks comments; add inline XIB documentation and create a Demo/CUSTOM_LAYOUT_GUIDE.md referencing the exact Interface Builder steps.
- Add accessibility labels (NSAccessibilityLabel, isAccessibilityElement) to all built-in MessageView layouts in Demo/Assets.xcassets and nib files so screen readers announce messages properly — currently no accessibility setup is visible.
⭐Top contributors
Click to expand
Top contributors
- @wtmoose — 80 commits
- @mofeejegi — 4 commits
- @MojtabaHs — 4 commits
- @teameh — 1 commits
- @Jacky-LinPeng — 1 commits
📝Recent commits
Click to expand
Recent commits
c0ff6c6— Release prep (wtmoose)6010bc7— RefactorMessageHostingViewHit Testing to Improve SwiftUI Touch Handling (#582) (mofeejegi)213fedc— Fix the bottom constraint issue on iPadOS 18+ when the tab bar has no superview or frame is empty (#578) (mofeejegi)920d846— Hide Background Elements from Modal SwiftMessage in VoiceOver mode (#577) (mofeejegi)007f4cc— Introduce SwiftMessagesHideAction and Environment Key for SwiftUI (#574) (mofeejegi)b929e04— PhysicsPanHandler.swift make configure public (#571) (teameh)c544df6— Update changelog (wtmoose)0eba59a— Remove unecessary sort logic (wtmoose)438a274— SwiftUI layout improvement (#560) (wtmoose)5500236— SwiftMessages.Config expands the popupPriority property to support the popup queue to accurately control the display ord (Jacky-LinPeng)
🔒Security observations
SwiftMessages is a UI library with a relatively clean security posture. No critical vulnerabilities were identified in the static analysis. The main findings are minor process improvements: establishing a security disclosure policy (SECURITY.md), ensuring dependency management best practices, and verifying code signing configurations. The library's purpose (message display) inherently limits injection attack vectors. No hardcoded secrets, SQL injection, XSS vulnerabilities, or infrastructure misconfigurations were detected in the provided file structure.
- Low · Missing Security Headers Documentation —
Repository root. The codebase does not contain visible security policy documentation or SECURITY.md file for handling security vulnerabilities. This makes it difficult for security researchers to report issues responsibly. Fix: Create a SECURITY.md file with instructions for reporting security vulnerabilities responsibly, including contact information and disclosure policy. - Low · Potential Outdated Dependencies —
Package.swift, SwiftMessages.podspec. No Package.swift content details were provided to analyze dependency versions. The library depends on UIKit and SwiftUI frameworks, but explicit dependency pinning and update strategy is not visible in the provided files. Fix: Regularly audit and update dependencies using tools like Dependabot. Specify minimum version requirements and test compatibility with security patch releases. - Low · No Code Signing Verification Visible —
SwiftMessages.xcodeproj/project.pbxproj, SwiftMessages.podspec. The Xcode project files and podspec do not show explicit code signing configurations or security preferences in the provided excerpts. This could lead to unsigned or improperly signed builds. Fix: Ensure proper code signing certificates are configured, use automatic signing where possible, and implement signed releases with reproducible builds.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.