RepoPilotOpen in app →

delba/Permission

A unified API to ask for permissions on iOS

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

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-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 10 active contributors
  • MIT licensed
  • CI configured
Show 3 more →
  • Tests present
  • Stale — last commit 4y ago
  • Concentrated ownership — top contributor handles 70% of recent commits

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 "Healthy" badge

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

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/delba/permission)](https://repopilot.app/r/delba/permission)

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

Onboarding doc

Onboarding: delba/Permission

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/delba/Permission 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

GO — Healthy across all four use cases

  • 10 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 4y ago
  • ⚠ Concentrated ownership — top contributor handles 70% of recent commits

<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 delba/Permission repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/delba/Permission.

What it runs against: a local clone of delba/Permission — 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 delba/Permission | 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 ≤ 1429 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "delba/Permission(\\.git)?\\b" \\
  && ok "origin remote is delba/Permission" \\
  || miss "origin remote is not delba/Permission (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 "Source/Permission.swift" \\
  && ok "Source/Permission.swift" \\
  || miss "missing critical file: Source/Permission.swift"
test -f "Source/PermissionType.swift" \\
  && ok "Source/PermissionType.swift" \\
  || miss "missing critical file: Source/PermissionType.swift"
test -f "Source/PermissionStatus.swift" \\
  && ok "Source/PermissionStatus.swift" \\
  || miss "missing critical file: Source/PermissionStatus.swift"
test -f "Source/Types/Location.swift" \\
  && ok "Source/Types/Location.swift" \\
  || miss "missing critical file: Source/Types/Location.swift"
test -f "Source/PermissionSet.swift" \\
  && ok "Source/PermissionSet.swift" \\
  || miss "missing critical file: Source/PermissionSet.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 1429 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1399d)"
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/delba/Permission"
  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

Permission is a unified Swift library that abstracts iOS permission requests (camera, microphone, location, contacts, notifications, etc.) behind a single, type-safe API. Instead of handling each permission framework separately (AVFoundation, CoreLocation, EventKit, HealthKit), developers use .camera.request(), .location.request(), or .notifications.request() with consistent callback signatures and status enums. Source/ contains the core abstraction: Permission.swift is the main entry point, PermissionStatus.swift defines the unified status enum, and PermissionType.swift acts as a factory/protocol. Each permission type (Camera, Contacts, Location, etc.) gets its own file in Source/Types/ implementing permission-specific logic. PermissionAlert.swift and PermissionButton.swift provide UI helpers. The .podspec and .xcconfig files handle distribution and build flags.

👥Who it's for

iOS app developers who need to request multiple device permissions and want to avoid boilerplate code for each framework's different delegate patterns, request APIs, and status enums. Particularly useful for apps requiring camera, location, health, or notification access.

🌱Maturity & risk

Actively developed but showing signs of age—the repo has proper CI (Travis in .travis.yml), CocoaPods/Carthage distribution, and comprehensive permission type coverage (15 permission types in Source/Types/). However, no visible git commit history, issue counts, or recent activity dates in the provided data. Likely production-ready but may not be under active maintenance.

Single-maintainer risk (delba/Permission suggests one owner). No dependency list visible in the provided data, but the library wraps Apple frameworks directly, limiting external risk. The iOS permission landscape evolves with each iOS version (e.g., App Tracking Transparency, Approximate Location)—older codebases may miss new permission types or deprecations. Test coverage appears minimal (only Tests/PermissionTests.swift listed).

Active areas of work

No specific recent activity visible in the provided file structure or README. The repo appears stable rather than actively developed—no pull requests, milestones, or changelog visible. Last activity and open issues unknown from the data provided.

🚀Get running

git clone https://github.com/delba/Permission.git
cd Permission
pod install
open Permission.xcworkspace

Then open Permission.xcworkspace in Xcode (not the .xcodeproj directly, as CocoaPods sets up dependencies via workspace).

Daily commands: Open Permission.xcworkspace in Xcode, select the Permission scheme, and run (⌘R). For tests, select PermissionTests scheme and run ⌘U. No local server or script required—it's a framework, not an app.

🗺️Map of the codebase

  • Source/Permission.swift — Core unified API entry point for requesting permissions; defines the Permission type and request() method that all features depend on
  • Source/PermissionType.swift — Protocol definition that all permission types must conform to; establishes the contract for implementing new permission types
  • Source/PermissionStatus.swift — Enum representing permission states (.notDetermined, .denied, .authorized); fundamental to all permission flow logic
  • Source/Types/Location.swift — Example permission type implementation showing the pattern for adding new iOS framework integrations
  • Source/PermissionSet.swift — Aggregates multiple Permission requests into a single batch operation; enables multi-permission flows
  • Source/PermissionAlert.swift — Handles displaying native iOS permission dialogs and custom alerts; bridges user interaction with permission status

🧩Components & responsibilities

  • Permission (enum) (Swift enum, closures) — Static factory for all permission types; exposes .request() as unified entry point
    • Failure mode: If PermissionType implementation is missing, request() returns error or hangs
  • PermissionType (protocol) (Swift protocol) — Defines contract: type property (for identification) and request() method signature
    • Failure mode: Conforming type fails to implement; compiler error
  • Permission Types (Camera, Location, etc.) (AVFoundation, CoreLocation, Contacts, etc.) — Concrete implementations wrapping iOS frameworks; handle native permission dialogs and status queries
    • Failure mode: iOS framework unavailable or permission key missing from Info.plist → native dialog not shown
  • PermissionAlert & PermissionButton (UIKit, closures) — UI layer for displaying pre-permission dialogs and request buttons
    • Failure mode: If user cancels dialog, .request() never called; permission stays .notDetermined
  • PermissionSet (Swift generics, closures, dictionary) — Batches multiple permission requests; coordinates async completion and aggregates results
    • Failure mode: Individual request fails (e.g., malformed PermissionType); PermissionSet completion fires with partial results

🔀Data flow

  • AppPermission enum — App calls Permission.camera.request() or similar
  • Permission enumPermissionType (concrete implementation) — Permission routes to Camera, Location, Contacts, etc. based on type
  • PermissionTypeiOS Framework (AVFoundation, CoreLocation, etc.) — Concrete type queries native framework for current status and requests permission
  • iOS FrameworkUser via native dialog — OS prompts user to Allow/Deny; user response returned to framework
  • iOS FrameworkPermissionType — Updated permission status returned to concrete type
  • PermissionTypePermission completion handler — Final status (.notDetermined, .authorized, .denied) passed to app's callback
  • PermissionSetMultiple PermissionTypes — Batches requests to multiple types; collects results in dictionary
  • PermissionSetundefined — undefined

🛠️How to make changes

Add a New Permission Type

  1. Create a new file in Source/Types/ named after the permission (e.g., Source/Types/HealthKit.swift) (Source/Types/Camera.swift)
  2. Implement the PermissionType protocol with type property and request() method (Source/PermissionType.swift)
  3. Import the required iOS framework (e.g., HealthKit) and use its native APIs to request permission (Source/Types/Location.swift)
  4. Add a static property to Permission enum in Permission.swift to expose the new type (Source/Permission.swift)
  5. Add test cases in Tests/PermissionTests.swift to verify the new permission type (Tests/PermissionTests.swift)

Request Multiple Permissions at Once

  1. Create a PermissionSet by combining multiple Permission instances (Source/PermissionSet.swift)
  2. Call the request() method on the PermissionSet with a completion handler (Source/PermissionSet.swift)
  3. Check the status dictionary in the completion to see results for each permission type (Source/PermissionSet.swift)

Display a Custom Permission Request UI

  1. Use PermissionAlert to display a native dialog before requesting permission (Source/PermissionAlert.swift)
  2. Call permission.request() inside the alert's completion handler (Source/Permission.swift)
  3. Optionally use PermissionButton for a pre-built UI component (Source/PermissionButton.swift)

🔧Why these technologies

  • Swift & iOS Frameworks (AVFoundation, CoreLocation, Contacts, etc.) — Native iOS permissions require direct framework integration; Swift is the modern iOS language for type-safe wrappers
  • Protocol-based abstraction (PermissionType) — Enables uniform API across diverse iOS permission types that have different underlying frameworks
  • Closure-based completion handlers — Fits iOS era when this library was written; avoids dependency on Combine/async-await
  • CocoaPods & Carthage packaging — Standard dependency distribution for iOS libraries; enables integration into existing iOS projects

⚖️Trade-offs already made

  • Unified API hiding diverse iOS frameworks

    • Why: Simplifies developer experience and reduces boilerplate across many permission types
    • Consequence: Hides framework-specific details; harder to use advanced features of individual frameworks
  • Closure-based async instead of modern concurrency

    • Why: Library predates Swift Concurrency and async-await; maintains broad iOS version support
    • Consequence: Less modern feel and potential callback hell for complex permission flows; won't integrate with async code without wrappers
  • Stateless Permission enum approach

    • Why: Simplifies API; no need for state management or observer patterns
    • Consequence: Each request re-checks status; doesn't cache results or observe system changes automatically

🚫Non-goals (don't propose these)

  • Real-time permission change monitoring (no observer pattern for OS-level changes)
  • Async-await integration (closure-only API)
  • Permission dependency resolution (e.g., 'Location Always requires WhenInUse first')
  • Localized permission explanation strings (library only wraps native dialogs)
  • Android support (iOS-only framework)

🪤Traps & gotchas

  1. Framework must be added to Xcode project manually: Most permission frameworks (AVFoundation, CoreLocation, HealthKit) require the framework to be linked in Build Phases, or permission requests silently fail. 2. Info.plist keys are critical: Each permission type requires specific keys (e.g., NSCameraUsageDescription, NSLocationWhenInUseUsageDescription). Missing keys will crash or block requests. 3. iOS version gates: Some permissions (e.g., Siri, BluetoothPeripheral) are only available on iOS 10+; the library may not gracefully degrade. Check PermissionFlags.xcconfig for conditional compilation. 4. Delegate retention: Location and some other frameworks rely on CLLocationManager delegates—if the Permission object is deallocated, the request may be abandoned.

🏗️Architecture

💡Concepts to learn

  • Protocol-driven abstraction — Permission uses a PermissionType protocol so each iOS permission framework (AVFoundation, CoreLocation, EventKit) is wrapped uniformly—essential for understanding how to add new permission types.
  • Callback-based async handling — iOS permission requests are asynchronous (user takes time to respond); Permission abstracts this with closures like permission.request { status in ... } instead of exposing delegate patterns.
  • Status quo pattern (permission states) — Each iOS permission has four states (notDetermined, authorized, denied, disabled)—Permission unifies this in PermissionStatus enum so callers don't learn each framework's status API.
  • Singleton factories with static properties — Permission exposes .camera, .contacts, .location as static properties—a lightweight factory pattern that avoids init() boilerplate and ensures one Permission instance per type.
  • iOS Framework wrapping patterns — Permission demonstrates how to wrap different Apple frameworks (some use delegates like CLLocationManager, others use callbacks like AVCaptureDevice)—essential knowledge for iOS SDK integration.
  • CocoaPods distribution and .podspec metadata — Permission is distributed via CocoaPods; understanding Permission.podspec shows how to declare supported iOS versions, source files, and subspecs for selective permission installation.
  • Preprocessor flags and build configuration (xcconfig)PermissionFlags.xcconfig likely gates permission types by iOS version—essential for supporting old iOS versions that lack new permission frameworks.
  • IQKeyboardManager/IQKeyboardManager — Similar abstraction library for iOS—hides boilerplate (keyboard handling) behind a simple API; good reference for permission-less dependency injection patterns.
  • realm/realm-swift — Well-maintained Swift framework showing how to wrap a complex C++ library with a clean, type-safe Swift interface—relevant architectural pattern for Permission's wrapper approach.
  • firebase/firebase-ios-sdk — Apple framework integration at scale—Firebase also wraps multiple Apple frameworks (notifications, auth, analytics) with unified APIs, similar architectural goals.
  • airbnb/lottie-ios — Production Swift library with CocoaPods/Carthage distribution and clear separation of concerns; reference for package structure and build configuration.
  • delba/Log — Same author's another library—may share architectural patterns and tooling preferences; useful for understanding the maintainer's style.

🪄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 comprehensive unit tests for PermissionType enum and individual permission type implementations

The repo has minimal test coverage (only PermissionTests.swift exists). Each permission type in Source/Types/ (Camera.swift, Contacts.swift, Location.swift, etc.) lacks dedicated unit tests. Adding tests would verify that each permission type correctly implements its specific iOS framework requirements (e.g., CLLocationManager for Location, AVCaptureDevice for Camera).

  • [ ] Create Tests/Types/ directory structure
  • [ ] Add unit tests for Camera.swift verifying AVFoundation integration
  • [ ] Add unit tests for Location.swift and LocationWhenInUse.swift/LocationAlways.swift verifying CoreLocation behavior
  • [ ] Add unit tests for Contacts.swift, Events.swift, Photos.swift verifying EventKit/Photos framework calls
  • [ ] Add unit tests for Microphone.swift, Bluetooth.swift, SpeechRecognizer.swift
  • [ ] Ensure tests verify permission status transitions and appropriate framework method calls

Add GitHub Actions CI/CD workflow to replace Travis CI

.travis.yml exists but GitHub Actions is now the standard for GitHub repos. This modernizes the CI pipeline, removes external service dependency, and provides better integration with GitHub. The project should test across multiple iOS SDK versions and Swift versions.

  • [ ] Create .github/workflows/ci.yml file
  • [ ] Configure matrix testing for iOS SDK versions (13, 14, 15, 16, 17) and Swift versions
  • [ ] Add build step using xcodebuild against Permission.xcodeproj
  • [ ] Add test step using xcodebuild to run PermissionTests.xcscheme
  • [ ] Add CocoaPods pod spec lint validation step
  • [ ] Remove .travis.yml once workflow is validated

Add Info.plist documentation for required permission keys in README

The repo exposes a unified API for requesting permissions, but the README doesn't document the critical step of adding NSUserPermission* keys to the app's Info.plist. This is essential for iOS 10+ and causes silent failures if omitted. A new section should map each PermissionType to its required Info.plist keys with examples.

  • [ ] Expand README.md with new 'Configuration' or 'Setup' section
  • [ ] Create mapping table: PermissionType → Required Info.plist keys (e.g., Camera → NSCameraUsageDescription)
  • [ ] Provide example Info.plist snippet showing all permission keys
  • [ ] Reference Apple's official documentation links for each permission type
  • [ ] Add note about iOS version requirements for each permission type (e.g., Siri requires iOS 10+)

🌿Good first issues

  • Add comprehensive unit tests for each permission type in Source/Types/—currently only Tests/PermissionTests.swift exists. Start by testing status queries and request callbacks for Camera.swift and Contacts.swift.
  • Document the required Info.plist keys for each permission type. Create a file (e.g., PERMISSIONS.md) listing keys like NSCameraUsageDescription for Camera, NSLocationWhenInUseUsageDescription for LocationWhenInUse, etc., with iOS version requirements.
  • Add support for iOS 14's App Tracking Transparency permission. Create Source/Types/AppTracking.swift conforming to PermissionType, wrapping AppTrackingTransparency framework, and register it in PermissionType.swift.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • d80694f — Bump to 3.1.2 (delba)
  • 9c729fb — Use keywindow (delba)
  • ae3773b — Clean up CI (delba)
  • 1972c1a — Change simulator to iPhone 11 (delba)
  • e2bc0ea — Update to 3.1.1 (delba)
  • 1ce5463 — Add a never case to PermissionType (delba)
  • a7e8013 — Use xcode11.2 (delba)
  • 72e4ac0 — Bump to 3.1 (delba)
  • accd941 — Prefix classes with Permission to prevent lint issues (delba)
  • 2c21697 — Remove deprecated .swift-version file (delba)

🔒Security observations

The Permission library appears to be a focused iOS permissions wrapper with generally sound architecture. No critical vulnerabilities were identified based on the available file structure. Main concerns are: (1) lack of visibility into dependency versions and their security status, (2) absence of a security policy or vulnerability disclosure process, (3) potential for misuse by developers if not properly documented. The codebase follows iOS best practices by isolating permission types into separate modules. Recommend adding security documentation and ensuring dependencies are regularly audited for vulnerabilities.

  • Medium · Missing dependency specifications in Pod specification — Permission.podspec. The Permission.podspec file content was not provided for analysis. Without reviewing the podspec, it's impossible to verify if all dependencies are pinned to specific versions or if vulnerable dependency versions are being used. CocoaPods dependencies should be explicitly versioned to prevent transitive dependency vulnerabilities. Fix: Review Permission.podspec and ensure all dependencies specify minimum version constraints and regularly update to patched versions. Use pod outdated to check for updates.
  • Medium · No security policy or vulnerability disclosure process documented — Repository root. The repository lacks visible security documentation such as a SECURITY.md file or vulnerability disclosure policy. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file documenting responsible disclosure procedures and security contact information.
  • Low · Potential for sensitive data exposure via permissions — Source/Types/*.swift. While not a direct code vulnerability, this library handles sensitive iOS permissions (Location, Contacts, Camera, Microphone, Photos, etc.). If not used correctly by developers, could lead to inappropriate permission requests or data exposure. Fix: Ensure documentation clearly states best practices for permission usage, including requesting only necessary permissions and explaining their purpose to users in privacy policies.
  • Low · Missing certificate pinning for API calls — Source/Permission.swift and related files. If this library makes any network requests during permission handling, certificate pinning is not evident from the file structure. This could expose requests to MITM attacks. Fix: If network requests are made, implement certificate pinning using libraries like TrustKit or similar mechanisms.

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.