dillidon/alerts-and-pickers
Advanced usage of UIAlertController and pickers based on it: Telegram, Contacts, Location, PhotoLibrary, Country, Phone Code, Currency, Date...
Stale — last commit 2y ago
worst of 4 axeslast commit was 2y ago; top contributor handles 96% of recent commits…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 2y ago; no CI workflows detected
- ✓2 active contributors
- ✓MIT licensed
- ⚠Stale — last commit 2y ago
Show 4 more →Show less
- ⚠Small team — 2 contributors active in recent commits
- ⚠Single-maintainer risk — top contributor 96% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: 1 commit in the last 365 days
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
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 "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/dillidon/alerts-and-pickers)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/dillidon/alerts-and-pickers on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: dillidon/alerts-and-pickers
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/dillidon/alerts-and-pickers 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 — Stale — last commit 2y ago
- 2 active contributors
- MIT licensed
- ⚠ Stale — last commit 2y ago
- ⚠ Small team — 2 contributors active in recent commits
- ⚠ Single-maintainer risk — top contributor 96% 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 dillidon/alerts-and-pickers
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/dillidon/alerts-and-pickers.
What it runs against: a local clone of dillidon/alerts-and-pickers — 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 dillidon/alerts-and-pickers | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch new exists | Catches branch renames |
| 4 | 3 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 842 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of dillidon/alerts-and-pickers. If you don't
# have one yet, run these first:
#
# git clone https://github.com/dillidon/alerts-and-pickers.git
# cd alerts-and-pickers
#
# 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 dillidon/alerts-and-pickers and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "dillidon/alerts-and-pickers(\\.git)?\\b" \\
&& ok "origin remote is dillidon/alerts-and-pickers" \\
|| miss "origin remote is not dillidon/alerts-and-pickers (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 new >/dev/null 2>&1 \\
&& ok "default branch new exists" \\
|| miss "default branch new no longer exists"
# 4. Critical files exist
test -f "Example/AppDelegate.swift" \\
&& ok "Example/AppDelegate.swift" \\
|| miss "missing critical file: Example/AppDelegate.swift"
test -f "Alerts&Pickers.xcodeproj/project.pbxproj" \\
&& ok "Alerts&Pickers.xcodeproj/project.pbxproj" \\
|| miss "missing critical file: Alerts&Pickers.xcodeproj/project.pbxproj"
test -f "Example/FlowLayouts/VegaScrollFlowLayout.swift" \\
&& ok "Example/FlowLayouts/VegaScrollFlowLayout.swift" \\
|| miss "missing critical file: Example/FlowLayouts/VegaScrollFlowLayout.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 842 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~812d)"
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/dillidon/alerts-and-pickers"
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
Alerts & Pickers is a Swift library that extends UIAlertController with custom content controllers for native iOS picker UIs (date, location, contacts, photo library, country, phone code, currency, color, and more). It solves the problem of embedding complex picker interfaces inside modal alerts/action sheets without building custom dialogs from scratch—by wrapping UIAlertController with convenient helper methods and pre-built picker content view controllers. Monolithic Xcode project (Alerts&Pickers.xcodeproj) with Example/ directory containing a reference iOS app built on Storyboard. Core library code inferred to be in root-level Swift files (not visible in top 60 list) alongside extension methods for UIAlertController. Assets/gifs/ documents 40+ picker variants (actionSheet/alert × 20 picker types). No modular packages or separate framework structure.
👥Who it's for
iOS developers building data-input flows who need quick, native-feeling picker modals (country selectors, date pickers, contact choosers) without shipping custom modal UI code. Specifically useful for apps requiring Telegram-style contact pickers, location selection, or currency/phone code spinners.
🌱Maturity & risk
Moderately mature but aging: targets Swift 4.0 and iOS 11+, single-maintainer repo (dillidon), codebase is 251k lines of Swift with comprehensive examples, but appears dormant—no visible recent activity timeline provided, and relies on deprecated/older iOS APIs. Suitable for production use in legacy or stable codebases, but not actively maintained for modern iOS.
Standard open source risks apply.
Active areas of work
No active development signals detected; repo appears stable/unmaintained. README and asset library are comprehensive (40 animated GIFs showing all picker variants), suggesting past effort to document features thoroughly, but no visible PRs, branches, or recent commits mentioned in provided data.
🚀Get running
git clone https://github.com/dillidon/alerts-and-pickers.git
cd alerts-and-pickers
open Alerts\&Pickers.xcodeproj
Then build and run the Example scheme on iOS 11+ simulator or device using Xcode 9+.
Daily commands: Open Alerts&Pickers.xcodeproj in Xcode 9+, select Example scheme, then Cmd+R on an iOS 11+ simulator or device.
🗺️Map of the codebase
Example/AppDelegate.swift— Application entry point and lifecycle manager for the example app; all alert and picker demonstrations originate hereAlerts&Pickers.xcodeproj/project.pbxproj— Build configuration and project structure definition; required to understand how the framework compiles and integrates picker componentsExample/FlowLayouts/VegaScrollFlowLayout.swift— Core layout engine for picker presentation; handles custom UICollectionView flow logic essential to picker UI rendering
🧩Components & responsibilities
- AppDelegate (UIKit, Swift) — Orchestrates all picker instantiation, configuration, and presentation; manages demo app lifecycle and window setup
- Failure mode: Missing picker function or incorrect alert configuration results in demo crash or blank modal
- UIAlertController (subclass/extension) (UIKit) — Wraps native alert/action sheet with custom pickers as contentViewController; manages button actions and completion handlers
- Failure mode: Oversized content, keyboard conflicts, or incorrect button wiring leads to UI clipping or unresponsive actions
- Picker View Controllers (TableView/CollectionView/DatePicker/MapView) (UIKit, CoreLocation, Contacts, Photos, EventKit) — Implements selection interface and data source logic for each picker type (Country, Currency, Contacts, Photos, etc.)
- Failure mode: Missing data source delegates, permission denials, or invalid selection indices cause picker malfunction or app crash
- VegaScrollFlowLayout (UIKit, CoreGraphics) — Custom UICollectionViewFlowLayout providing scroll-to-select behavior and dynamic cell sizing for picker grids
- Failure mode: Incorrect scroll offset calculation or cell size mismatch leads to misaligned picker selection or dropped cells
🔀Data flow
User tap on demo button→AppDelegate action handler— User initiates picker presentation via UI controlAppDelegate→UIAlertController instantiation— Creates alert or action sheet with custom picker as contentViewControllerPicker view controller→UITableViewDataSource / UICollectionViewDataSource— Data source methods return picker items (countries, currencies, contacts, photos, etc.)User selection in picker→Delegate callback (didSelectRowAtIndexPath, didSelectItemAtIndexPath)— Selection event updates internal picker state and optionally updates UIUser tap on action button→Completion handler in AppDelegate— Selected value passed back via closure or completion block; alert is dismissedCompletion handler→Result display in demo UI— Selected value is displayed or logged for demonstration purposes
🛠️How to make changes
Add a new custom picker type
- Create a new UIViewController subclass in Example/ that conforms to UIPickerViewDataSource/Delegate or UITableViewDataSource/Delegate (
Example/[NewPickerName]ViewController.swift) - Add the picker view controller as a contentViewController within UIAlertController's preferredContentSize (
Example/AppDelegate.swift) - Register the new picker in the main demo storyboard by adding an action button to present it (
Example/Resources/Assets.xcassets/icons/) - Define a custom flow layout if the picker requires non-standard scrolling or grid behavior (
Example/FlowLayouts/VegaScrollFlowLayout.swift)
Customize picker appearance and behavior
- Modify the UIAlertController's title, message, and button configurations in the example view controller (
Example/AppDelegate.swift) - Override cell layout or styling in the picker's UITableViewCell or UICollectionViewCell subclass (
Example/FlowLayouts/VegaScrollFlowLayout.swift) - Add or replace assets (icons, colors) in the appropriate xcassets folder (
Example/Resources/Assets.xcassets/)
Add a new action sheet example
- Create a new function in AppDelegate that instantiates UIAlertController with preferredStyle .actionSheet (
Example/AppDelegate.swift) - Attach the custom picker's contentViewController to the alert controller (
Example/AppDelegate.swift) - Add a UIAction button to the alert that returns the selected picker value via completion handler (
Example/AppDelegate.swift)
🔧Why these technologies
- UIAlertController — Native iOS framework for modal dialogs; provides standard alert and action sheet interfaces with custom content support via contentViewController
- UIPickerView / UITableView / UICollectionView — Native iOS components optimized for selection interfaces; allow rich, scrollable picker presentations with minimal overhead
- MKMapView — Native MapKit framework for location-based picker; integrates seamlessly with iOS location services and permissions model
- Swift 4.0 — Modern language with type safety and protocol-oriented design; simplifies delegate patterns and view controller composition
- Storyboard — Visual layout tool that enables rapid prototyping of alert/picker examples without code duplication
⚖️Trade-offs already made
-
All pickers built on native UIAlertController rather than custom modal view
- Why: Ensures consistent iOS system look-and-feel, automatic keyboard handling, and respects system accessibility features
- Consequence: Limited to UIAlertController's content sizing constraints; complex custom animations require subclassing or supplementary views
-
Example-driven architecture with no separate library module
- Why: Simplifies learning; developers can directly modify and extend picker logic without abstraction layers
- Consequence: Code reuse across multiple picker types may require duplication; harder to version independently
-
Custom VegaScrollFlowLayout for CollectionView pickers
- Why: Enables specialized scroll-to-select behavior and grid layouts beyond standard UICollectionViewFlowLayout
- Consequence: Additional layout logic increases maintenance surface; must handle edge cases in cell sizing and scroll updates
🚫Non-goals (don't propose these)
- Does not provide persistent state management or data model layer
- Does not handle authentication, network requests, or backend integration
- Does not include unit tests or test harness (example-focused, not library-focused)
- Does not target tvOS, watchOS, or macOS (iOS 11+ only)
- Does not provide SwiftUI integration (UIKit-only, built before SwiftUI adoption)
⚠️Anti-patterns to avoid
- Implicit force unwraps in picker data sources (Medium) —
Example/FlowLayouts/VegaScrollFlowLayout.swift and picker view controllers (inferred): Risk of runtime crashes if array indices are not bounds-checked before accessing picker data or cell configuration - Missing permission checks for sensitive pickers (High) —
Example/AppDelegate.swift (inferred for Contacts, Photos, Location pickers): Pickers requesting user data (contacts, photo library, location) may not explicitly check or request permissions before access, leading to silent failures - Hardcoded asset names in code —
Example/AppDelegate.swift and picker view controllers (inferred): Icon or asset names may be hardcoded strings rather than type-safe enums, increasing refactoring brittleness
🪤Traps & gotchas
Swift 4.0 syntax incompatible with Swift 5.5+; project uses storyboard-based example (Example/Resources/Assets.xcassets/) so simulator may require booting iOS 11–13 to avoid asset scale warnings. UIAlertController preferredContentSize behavior varies by iOS version (pre-13 vs 13+); library may need per-version testing. No pod/SPM metadata visible, so integration as framework requires manual file copying or git submodule. Deprecated APIs: MKMapView and UIPickerView usage unchanged since iOS 11—potential for API removal in iOS 17+.
🏗️Architecture
💡Concepts to learn
- UIAlertController content view controller embedding — Core pattern in this repo: using setValue(_:forKey:) with 'contentViewController' and preferredContentSize to embed complex UIs in native alerts; understanding this is required to extend or maintain the library
🔗Related repos
jrendel/SwiftKeychainWrapper— Complementary UIKit utility library (no external dependencies, pure Swift) solving credential storage alongside Alerts&Pickers' data inputSearchTextField/SearchTextField— Similar pattern of wrapping UITextField with custom picker behavior; shares iOS 11+ native UI philosophyfacebook/facebook-ios-sdk— Uses UIAlertController for identity/picker flows; example of production-scale alert customization at scalehackiftekhar/IQKeyboardManager— Complementary library managing keyboard + picker presentation together in iOS forms; often used alongside Alerts&Pickers in real appsxmartlabs/XLForm— Higher-level form abstraction that wraps pickers (date, location, picker lists); Alerts&Pickers is lower-level alternative for modal-only use cases
🪄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 Swift Package Manager (SPM) support with Package.swift
The repo currently only supports CocoaPods/Carthage via .xcodeproj. Swift Package Manager is now the standard for iOS dependency management. Adding SPM support would make the library accessible to modern projects and increase adoption. This requires creating a Package.swift manifest file that properly exposes the AlertsAndPickers module.
- [ ] Create Package.swift in repo root with proper name and products configuration
- [ ] Define platforms as .iOS(.v11) to match current deployment target
- [ ] Organize Sources/ directory structure to match SPM conventions (Sources/AlertsAndPickers/)
- [ ] Test SPM integration by adding the repo via Xcode's 'Add Packages' dialog
- [ ] Update README.md with SPM installation instructions alongside existing methods
Create automated screenshot/GIF generation tests for visual pickers
The repo has 40+ GIF files in Assets/gifs/ demonstrating each picker type (colorPicker, contactsPicker, countryPicker, datePicker, etc.), but these appear manually created. Adding snapshot tests using a tool like SnapshotTesting would ensure visual regressions are caught during CI/CD and reduce manual screenshot burden when updating features.
- [ ] Add SnapshotTesting Swift package dependency to Example target
- [ ] Create Tests/ directory structure with ViewControllerSnapshotTests.swift
- [ ] Implement snapshot tests for each major picker type (ColorPickerViewController, ContactsPickerViewController, CountryPickerViewController, DatePickerViewController, PhotoLibraryPickerViewController)
- [ ] Configure test schemes in .xcodeproj/xcshareddata/xcschemes/ to run snapshot tests
- [ ] Document snapshot regeneration workflow in CONTRIBUTING.md for updating visual changes
Add GitHub Actions CI workflow for Swift compilation and basic tests
The repo has no .github/workflows/ directory, meaning there's no automated testing on PR/push. Given the variety of picker types and iOS versions (11+), automated CI would catch compilation errors early and ensure examples build on Xcode 9+. This is critical for a UI library where visual regressions and API mismatches could silently break functionality.
- [ ] Create .github/workflows/swift-build.yml with matrix testing for Xcode 14/15 and iOS 11/16 simulators
- [ ] Add build step that runs 'xcodebuild build-for-testing' for the main Alerts&Pickers scheme
- [ ] Add test step that runs unit tests if Tests/ directory exists, otherwise validate Example app builds
- [ ] Configure workflow to trigger on PR to main/master and push events
- [ ] Add status badge to README.md linking to GitHub Actions workflow results
🌿Good first issues
- Add unit test suite: create Tests/ directory with XCTestCase subclasses covering UIAlertController extensions (addCountryPicker, addDatePicker, etc.) and verify preferredContentSize calculations across iOS 11–16. Currently no test files visible in project structure.
- Migrate to Swift Package Manager: create Package.swift at root, expose library targets, and add CI workflow (GitHub Actions) to build on Xcode 13–15. Enables SPM adoption and modern dependency management.
- Document picker customization patterns: add inline code comments and a CUSTOMIZATION.md guide showing how to subclass existing pickers (e.g., custom country list, date range limits) with 2–3 concrete examples from Example/
⭐Top contributors
Click to expand
Top contributors
- [@Roman Volodko](https://github.com/Roman Volodko) — 26 commits
- @None — 1 commits
📝Recent commits
Click to expand
Recent commits
482d080— v 1.4.1 fix ColorPicker bugs (Roman Volodko)5ff858b— Add .gitignore file (None)a06b186— fix readme (Roman Volodko)b0a15a7— v 1.3 (Roman Volodko)d4e4c44— v 1.3 Telegram Picker (Roman Volodko)5cab928— v 1.3 (Roman Volodko)37d6ed3— v 1.2 Telegram Picker, Contacts Picker, Location Picker, TextViewer (Roman Volodko)f8b3f2f— v 1.2 - Add Like Telegram Picker (Roman Volodko)9546408— v 1.2 - Add Text & Markdown Viewer (Roman Volodko)b4b2137— v 1.1 (Roman Volodko)
🔒Security observations
This is a UI library project with moderate security concerns. The primary risks stem from outdated Swift/iOS version requirements that lack modern security patches. The handling of sensitive user data (contacts, location, photos) requires proper permission management verification. The codebase itself appears to be a wrapper around native iOS APIs without obvious injection vulnerabilities or hardcoded secrets. No external dependencies with known vulnerabilities were identified in the provided context. Key improvements needed: upgrade to modern Swift/iOS versions, ensure comprehensive privacy permission handling, add security documentation, and clean up version control artifacts.
- Medium · Outdated Swift and iOS Version Requirements —
README.md, Xcode project configuration. The project targets Swift 4.0 and iOS 11+, which are significantly outdated. Swift 4.0 was released in 2017 and iOS 11 in 2017. Modern security patches, bug fixes, and vulnerability mitigations are not available in these versions. The codebase may be vulnerable to known security issues that have been patched in newer Swift/iOS versions. Fix: Update the project to target Swift 5.0+ and iOS 14+/15+ minimum. Review and address any deprecation warnings and security-related API changes when upgrading. - Medium · User Data Access Without Clear Permission Management —
Example app components - Contacts, Location, PhotoLibrary pickers. The project includes pickers for sensitive user data (Contacts, Location, PhotoLibrary) based on the file structure and description. While UIAlertController and native pickers are used, there is no visible documentation or evidence of proper privacy permission handling (NSContactsUsageDescription, NSLocationWhenInUseUsageDescription, NSPhotoLibraryUsageDescription in Info.plist). Fix: Ensure all Info.plist privacy keys are properly configured with user-friendly descriptions. Implement proper permission request flows before accessing user data, and gracefully handle permission denials. - Low · No Security Policy or Documentation —
Repository root. The repository lacks a SECURITY.md file or security policy documentation. There is no clear process for reporting security vulnerabilities or coordinating responsible disclosure. Fix: Create a SECURITY.md file with instructions for reporting security vulnerabilities. Consider using GitHub's security advisory feature. - Low · User Data in Xcode Workspace Metadata —
.gitignore, Alerts&Pickers.xcodeproj/xcuserdata/. The .xcuserdata directory is tracked in the repository (none.xcuserdatad). This directory can contain user-specific configuration that should not be shared, and should be added to .gitignore. Fix: Add 'xcuserdata/' to .gitignore immediately and remove the directory from git history using 'git rm --cached' and force push.
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.