RepoPilotOpen in app →

hyperoslo/ImagePicker

:camera: Reinventing the way ImagePicker works.

Mixed

Stale — last commit 2y ago

worst of 4 axes
Use as dependencyConcerns

non-standard license (Other); last commit was 2y ago…

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 2y ago; no CI workflows detected

  • 28+ active contributors
  • Distributed ownership (top contributor 22% of recent commits)
  • Other licensed
Show 4 more →
  • Stale — last commit 2y ago
  • Non-standard license (Other) — review terms
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms
  • Deploy as-is MixedHealthy 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 "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/hyperoslo/imagepicker?axis=fork)](https://repopilot.app/r/hyperoslo/imagepicker)

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/hyperoslo/imagepicker on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: hyperoslo/ImagePicker

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:

  1. 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.
  2. 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.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/hyperoslo/ImagePicker 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

  • 28+ active contributors
  • Distributed ownership (top contributor 22% of recent commits)
  • Other licensed
  • ⚠ Stale — last commit 2y ago
  • ⚠ Non-standard license (Other) — review terms
  • ⚠ 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 hyperoslo/ImagePicker repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/hyperoslo/ImagePicker.

What it runs against: a local clone of hyperoslo/ImagePicker — 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 hyperoslo/ImagePicker | Confirms the artifact applies here, not a fork | | 2 | License is still Other | 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 ≤ 651 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>hyperoslo/ImagePicker</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of hyperoslo/ImagePicker. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/hyperoslo/ImagePicker.git
#   cd ImagePicker
#
# 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 hyperoslo/ImagePicker and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "hyperoslo/ImagePicker(\\.git)?\\b" \\
  && ok "origin remote is hyperoslo/ImagePicker" \\
  || miss "origin remote is not hyperoslo/ImagePicker (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other 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 "Source/ImagePickerController.swift" \\
  && ok "Source/ImagePickerController.swift" \\
  || miss "missing critical file: Source/ImagePickerController.swift"
test -f "Source/CameraView/CameraMan.swift" \\
  && ok "Source/CameraView/CameraMan.swift" \\
  || miss "missing critical file: Source/CameraView/CameraMan.swift"
test -f "Source/ImageGallery/ImageGalleryViewDataSource.swift" \\
  && ok "Source/ImageGallery/ImageGalleryViewDataSource.swift" \\
  || miss "missing critical file: Source/ImageGallery/ImageGalleryViewDataSource.swift"
test -f "Source/BottomView/BottomContainerView.swift" \\
  && ok "Source/BottomView/BottomContainerView.swift" \\
  || miss "missing critical file: Source/BottomView/BottomContainerView.swift"
test -f "Source/Configuration.swift" \\
  && ok "Source/Configuration.swift" \\
  || miss "missing critical file: Source/Configuration.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 651 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~621d)"
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/hyperoslo/ImagePicker"
  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).

</details>

TL;DR

ImagePicker is an iOS Swift framework that provides a production-ready camera and photo library picker UI component. It combines camera capture and photo library browsing in a single modal controller, optimized for memory efficiency by passing image asset references instead of full UIImage objects, with customizable configuration for colors, text, fonts, and camera features. Dual-structure repo: primary source is in the root ImagePicker.xcodeproj Swift package, while Demo/ImagePickerDemo contains a reference app demonstrating usage. Configuration is injected via a Configuration object at instantiation time. Core delegate pattern communicates user interactions (wrap, done, cancel) back to the host controller.

👥Who it's for

iOS app developers who need to let users select existing photos or take new pictures without building custom camera/picker UI. Primarily used by apps requiring image upload flows, profile photo selection, or gallery-based content creation.

🌱Maturity & risk

Production-ready but appears dormant. The codebase is stable (84K Swift lines with established patterns), published via CocoaPods and Carthage, but the CHANGELOG and commit history suggest infrequent updates in recent years. No visible CI/CD badges or automated test suite in the file listing indicates limited maintenance infrastructure.

Low risk for basic use cases, but potential iOS version compatibility issues due to dormancy—iOS camera APIs and photo library permissions have evolved significantly since this repo's active development period. Single maintainer (hyperoslo organization) with no visible issue triage process creates adoption risk if bugs arise on newer iOS versions. Dependency on UIImagePickerController patterns may not align with modern PHPickerViewController best practices.

Active areas of work

No recent activity is apparent from the file listing. The CHANGELOG, .swiftlint.yml, and CONTRIBUTING.md suggest a past period of active development, but no open PRs, milestones, or recent commits are visible in the provided data.

🚀Get running

Clone the repo: git clone https://github.com/hyperoslo/ImagePicker.git && cd ImagePicker. For CocoaPods: add pod 'ImagePicker' to your Podfile and run pod install. For Carthage: add github "hyperoslo/ImagePicker" to your Cartfile and run carthage update. To run the demo app: open Demo/ImagePickerDemo/ImagePickerDemo.xcworkspace in Xcode and build for iOS simulator/device.

Daily commands: Open ImagePicker.xcodeproj and build the ImagePicker-iOS scheme. For the demo app: open Demo/ImagePickerDemo/ImagePickerDemo.xcworkspace, ensure CocoaPods are installed via pod install (Podfile visible at Demo/ImagePickerDemo/Podfile), then build and run on iOS simulator or device.

🗺️Map of the codebase

  • Source/ImagePickerController.swift — Main entry point and controller that orchestrates the entire image picker experience; every integration starts here.
  • Source/CameraView/CameraMan.swift — Core camera management abstraction handling capture session, device permissions, and device switching; critical for camera functionality.
  • Source/ImageGallery/ImageGalleryViewDataSource.swift — Data source layer that bridges PHPhotoLibrary access to the gallery UI; handles asset fetching and caching.
  • Source/BottomView/BottomContainerView.swift — Manages the bottom UI container that coordinates camera, gallery, and stack views; orchestrates user interactions.
  • Source/Configuration.swift — Configuration struct that exposes customizable settings across the entire picker; governs behavior and appearance.
  • Source/AssetManager.swift — Handles image/video asset processing, saving, and retrieval from device storage; critical for data persistence.

🧩Components & responsibilities

  • ImagePickerController (UIViewController, AVFoundation, Photos Framework) — Root view controller orchestrating camera, gallery, and mode selection; delegates to sub-managers
    • Failure mode: Permission denial (camera/photo library) shows graceful error UI; missing permission causes blank preview
  • CameraMan (AVFoundation, AVCaptureDevice) — AVCaptureSession lifecycle, device discovery, torch/zoom control, and photo capture delegation
    • Failure mode: Session setup failure silently falls back to gallery-only mode; capture errors are logged
  • ImageGalleryViewDataSource (Photos Framework, PHAsset, PHCachingImageManager) — PHFetchResult caching and thumbnail/full-res image fetching for gallery cells
    • Failure mode: Asset fetch timeout defaults to placeholder; deleted assets gracefully skip in results
  • AssetManager (UIImage, AVAsset, FileManager) — Persists captured images and videos to app Documents; loads and exposes saved media
    • Failure mode: Write failure prevents image save; read failure skips asset in enumeration
  • Configuration — Global state object holding user preferences (colors, behavior, permissions flags)

🛠️How to make changes

Add a new camera feature (e.g., flash toggle)

  1. Add toggle property and AVCaptureDevice.TorchMode logic in CameraMan.swift (Source/CameraView/CameraMan.swift)
  2. Expose the feature as a Configuration property in Configuration.swift (Source/Configuration.swift)
  3. Add UI button to TopView.swift and wire its action to CameraMan (Source/TopView/TopView.swift)

Customize the gallery appearance (e.g., cell styling)

  1. Modify cell layout and styling in ImageGalleryViewCell.swift (Source/ImageGallery/ImageGalleryViewCell.swift)
  2. Adjust grid layout parameters in ImageGalleryLayout.swift (Source/ImageGallery/ImageGalleryLayout.swift)
  3. Add configuration options to Configuration.swift if needed (Source/Configuration.swift)

Add post-processing to captured images (e.g., filters, watermark)

  1. Intercept image data in CameraMan.swift after capture (Source/CameraView/CameraMan.swift)
  2. Process and save the modified image in AssetManager.swift (Source/AssetManager.swift)
  3. Expose processing options as Configuration properties (Source/Configuration.swift)

Add permission/privacy handling for a new sensor (e.g., microphone for video)

  1. Add permission request logic in CameraMan.swift or LocationManager.swift as a template (Source/CameraView/CameraMan.swift)
  2. Handle permission denied UI in the relevant view (TopView or CameraView) (Source/TopView/TopView.swift)
  3. Document required Info.plist keys in README.md (README.md)

🔧Why these technologies

  • AVFoundation — Native iOS camera capture with real-time preview and device control (torch, zoom, mic)
  • Photos Framework (PHPhotoLibrary) — Memory-efficient access to photo library with asset caching and permission handling
  • UICollectionView — Efficient scrolling gallery with cell reuse for potentially thousands of assets
  • Auto Layout — Responsive UI that adapts across iPhone/iPad sizes and orientations
  • Swift — Type-safe, modern iOS development with Codable and protocol-oriented patterns

⚖️Trade-offs already made

  • Pass image references instead of full image objects

    • Why: Reduce memory footprint for multi-image selection workflows
    • Consequence: Requires careful lifetime management of PHAsset references; images must be fetched on demand
  • Single ImagePickerController entry point with configuration object

    • Why: Simpler API surface and reduced state fragmentation
    • Consequence: All customization must go through Configuration; less granular control for advanced use cases
  • Synchronous image save to device storage in AssetManager

    • Why: Guaranteed persistence before callback completion
    • Consequence: Blocks main thread briefly; can cause UI lag during rapid captures

🚫Non-goals (don't propose these)

  • Real-time video recording and playback (camera capture only, gallery shows video metadata)
  • Editing tools (filters, crop, rotate) — view-only with selection
  • Cloud sync or remote storage — local device storage only
  • Android or cross-platform support

🪤Traps & gotchas

Camera and photo library permissions require NSCameraUsageDescription and NSPhotoLibraryUsageDescription in Info.plist—missing these will cause runtime crashes. The framework's memory optimization relies on PHAssets being resolved downstream; if you directly access imagePicker.stack.assets without proper AssetManager.resolveAssets() wrapping, you may face stale asset references. imageLimit defaults to 0 (unlimited), which can surprise users expecting single-image behavior. Xcode workspace is split between root project and Demo workspace; modifying framework code requires updating the root .xcodeproj, not the demo workspace.

🏗️Architecture

💡Concepts to learn

  • Asset References vs. Image Resolution — ImagePicker passes PHAsset references instead of UIImage objects to reduce memory overhead during selection; understanding when to resolve assets vs. keep references is critical for not regressing the performance optimization
  • UIImagePickerController Delegate Pattern — The framework wraps UIImagePickerController's delegate callbacks and exposes them via custom delegate methods (wrapperDidPress, doneButtonDidPress, cancelButtonDidPress); you must understand Apple's picker delegate protocol to extend this framework
  • Configuration Injection / Dependency Injection — The framework uses a Configuration struct passed at initialization to customize colors, fonts, text, and features; this is the primary extension point and avoids tight coupling between the picker and host app
  • iOS Photo Library Permissions (PHPhotoLibrary) — Modern iOS requires explicit user consent to access photos via NSPhotoLibraryUsageDescription; ImagePicker relies on the host app to request and handle these permissions correctly
  • Memory-Efficient Image Passing via Asset References — The core optimization passes lightweight PHAsset objects rather than decoded UIImage bitmaps, which can be gigabytes; this pattern is essential for smooth UX when selecting many images
  • Swift Linting & Code Style (SwiftLint) — The .swiftlint.yml file enforces code consistency across the codebase; PRs must pass these checks, making familiarity with SwiftLint rules necessary for contributions
  • hyperoslo/NibDesignable — Companion UI framework from the same organization (hyperoslo) often used alongside ImagePicker for building custom iOS UI components
  • yonat/ImagePickerSheetController — Alternative image picker with sheet presentation style and multi-image selection, designed for the same use case but with different UX patterns
  • squarefrog/PHAssetCollectionViewController — Low-level photo library browser using Photos framework directly, useful if you need fine-grained control that ImagePicker abstracts away
  • mobileplayer/mobileplayer-ios — Related media handling framework from similar era; shares design patterns around asset management and delegate-based event handling

🪄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 integration tests and CI workflow

The repo has Package.swift but no GitHub Actions workflow to validate SPM builds. This is critical since SPM is a first-class dependency manager for modern Swift projects. A new contributor could add a .github/workflows/spm.yml that tests building via swift build on multiple Swift versions, ensuring the package metadata in Package.swift stays valid and that SPM users aren't broken by future changes.

  • [ ] Create .github/workflows/spm.yml with matrix builds for Swift 5.3+ versions
  • [ ] Test swift build and swift test commands against the Package.swift manifest
  • [ ] Verify that all source files referenced in Package.swift are correctly included
  • [ ] Add badge to README.md showing SPM CI status

Add unit tests for CameraMan.swift and CameraView.swift

The Source/CameraView directory contains critical camera functionality (CameraMan.swift, CameraView.swift) but there's no test coverage visible in the file structure. A new contributor could create Tests/CameraViewTests/ with unit tests covering camera permissions, capture session setup, flash/focus/zoom controls, and delegate callbacks—this is high-risk code that benefits greatly from regression testing.

  • [ ] Create Tests/CameraViewTests/CameraManTests.swift with mocked AVCaptureSession
  • [ ] Add tests for camera permission request handling and denied/granted states
  • [ ] Test flash mode toggling, focus, and zoom functionality in CameraManTests
  • [ ] Create Tests/CameraViewTests/CameraViewTests.swift for UI layout and delegate calls
  • [ ] Ensure tests compile and run via swift test in Package.swift

Extract and document Configuration.swift API with code examples in Configuration.md

Configuration.swift exists but there's no dedicated documentation explaining all available configuration options. The README is incomplete and doesn't detail how users customize ImagePicker's behavior (colors, camera settings, image quality, etc.). A new contributor could create Documentation/Configuration.md with examples of common customization patterns, cross-referenced from README.md, making onboarding smoother for new users.

  • [ ] Review Configuration.swift and document all public properties and their purposes
  • [ ] Create Documentation/Configuration.md with organized sections (Camera Settings, UI Customization, Permissions, etc.)
  • [ ] Add code examples showing how to initialize Configuration with custom values
  • [ ] Include a troubleshooting section for common configuration issues
  • [ ] Add link to Configuration.md from README.md in a new 'Configuration' section

🌿Good first issues

  • Add unit tests for Configuration struct initialization and delegate method invocation—no test directory visible in the file list, making this an easy win to improve code coverage
  • Document the AssetManager.resolveAssets() pattern with a concrete code example in README.md showing the difference between asset references and resolved UIImages, since this optimization is non-obvious
  • Create a Swift Package Manager integration guide—currently only CocoaPods and Carthage are documented, but SPM is now the recommended package manager for iOS development

Top contributors

Click to expand

📝Recent commits

Click to expand
  • d8a8f84 — Merge pull request #483 from Kirow/hotfixes/ios15 (3lvis)
  • afbec27 — renamed ButtonPicker.configuration to avoid naming conflict with iOS 15 UIButton.configuration (Kirill Serebriakov)
  • c0b3230 — Merge pull request #475 from shalamowww/master (3lvis)
  • ba263f0 — Added galleryOnly configuration mode (shalamowww)
  • 4cfb7e3 — Update README.md (3lvis)
  • cb86a53 — Merge pull request #472 from Vinzius/patch-1 (3lvis)
  • 59261d9 — [fix] demo project (Vinzius)
  • ecee6e2 — Merge pull request #468 from abdallahEid/configuration-class-renaming (3lvis)
  • f56b91a — Renaming Configuration class to ImagePickerConfiguration (abdallahEid)
  • 079f350 — Merge pull request #466 from MohamedAbdallah-14/Fix-Single-Selection (3lvis)

🔒Security observations

The ImagePicker library is a camera and photo gallery integration framework with moderate security posture. Primary concerns include: (1) likely missing or incomplete Info.plist privacy declarations, (2) potential memory management issues with camera/video streams, (3) unvalidated user-selected media content, and (4) unclear location data handling. No obvious hardcoded secrets, SQL injection, XSS, or dependency vulnerabilities were detected in the provided file structure. The library follows standard iOS development patterns but would benefit from explicit security validation, memory safety reviews, and comprehensive privacy documentation for integrators.

  • Medium · Missing permission declarations in Info.plist — SupportFiles/Info.plist, Source/CameraView/CameraMan.swift, Source/LocationManager.swift. The ImagePicker library accesses camera and photo library resources. The codebase references CameraMan, LocationManager, and image gallery features, but proper privacy permission strings (NSCameraUsageDescription, NSPhotoLibraryUsageDescription, NSLocationWhenInUseUsageDescription) may not be declared in Info.plist. This could cause runtime crashes or app store rejection. Fix: Ensure all required privacy permission keys are properly declared in Info.plist with user-facing descriptions complying with App Store requirements.
  • Medium · Potential unsafe memory handling in camera operations — Source/CameraView/CameraMan.swift, Source/CameraView/CameraView.swift. CameraView and CameraMan classes handle real-time camera streams and video capture. Without visible memory management patterns in the file structure, there's risk of memory leaks or buffer overflows when processing large image/video data streams, especially given the complexity of AVFoundation operations. Fix: Review camera resource cleanup in deinit methods, ensure proper AVCaptureSession teardown, implement memory pressure handling for large video processing, and use weak references where appropriate.
  • Medium · Unvalidated user-selected content — Source/AssetManager.swift, Source/ImageGallery/ImageGalleryView.swift. The library processes images and videos selected from the photo library without apparent validation. Malicious or crafted media files could potentially cause issues. No visible sanitization or format validation in the file structure. Fix: Implement validation for selected images/videos including format checking, file size limits, and integrity verification before processing or display.
  • Low · Potential location data exposure — Source/LocationManager.swift. LocationManager is included in the codebase but its usage context is unclear. Location data from images (EXIF metadata) or the LocationManager itself could be exposed without user awareness or consent. Fix: Document LocationManager usage, ensure location data is only collected with explicit user consent, strip EXIF metadata from images before sharing, and provide clear privacy documentation.
  • Low · Missing input validation in Configuration — Source/Configuration.swift. Configuration.swift likely contains customizable settings. Without visible validation logic in the file structure, user-provided configuration values could potentially be misused. Fix: Implement comprehensive input validation for all configuration parameters, enforce type safety, and use allowlists for any string-based settings.
  • Low · Insufficient code obfuscation for library — Source/. As a public open-source library, the code is fully visible. While open-source itself isn't a vulnerability, sensitive logic related to permission handling or data processing should be properly documented for security awareness. Fix: Add security documentation, conduct security audits, provide security guidelines for integrators, and document any known limitations or security considerations.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · hyperoslo/ImagePicker — RepoPilot