{"id":13588349,"url":"https://github.com/debug45/PermissionWizard","last_synced_at":"2025-04-08T03:33:36.826Z","repository":{"id":62450618,"uuid":"300927325","full_name":"debug45/PermissionWizard","owner":"debug45","description":"🔮 An ultimate library for iOS and macOS system permissions management. The easiest way to check or request a permission.","archived":false,"fork":false,"pushed_at":"2023-11-04T11:29:23.000Z","size":799,"stargazers_count":130,"open_issues_count":1,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-12T10:42:53.869Z","etag":null,"topics":["apple","camera","catalyst","ios","ipad","iphone","location","mac","macos","notifications","permissions","photos","plist","swift"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/debug45.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-03T16:37:08.000Z","updated_at":"2025-02-28T15:25:02.000Z","dependencies_parsed_at":"2022-11-01T23:17:21.892Z","dependency_job_id":"0bdcfffb-0253-453b-8e23-ceadbdf65d87","html_url":"https://github.com/debug45/PermissionWizard","commit_stats":{"total_commits":76,"total_committers":2,"mean_commits":38.0,"dds":0.1578947368421053,"last_synced_commit":"2a1c7ee8bdec7951370ad1ffd7022ab04f3c6041"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debug45%2FPermissionWizard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debug45%2FPermissionWizard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debug45%2FPermissionWizard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/debug45%2FPermissionWizard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/debug45","download_url":"https://codeload.github.com/debug45/PermissionWizard/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247772742,"owners_count":20993626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple","camera","catalyst","ios","ipad","iphone","location","mac","macos","notifications","permissions","photos","plist","swift"],"created_at":"2024-08-01T15:06:39.416Z","updated_at":"2025-04-08T03:33:36.381Z","avatar_url":"https://github.com/debug45.png","language":"Swift","readme":"# 🔮 PermissionWizard\n\n[![CocoaPods](https://img.shields.io/badge/CocoaPods-supported-success)](https://cocoapods.org/pods/PermissionWizard)\n![Carthage](https://img.shields.io/badge/Carthage-supported-success)\n\n[Читать на русском](https://github.com/debug45/PermissionWizard/blob/master/README.ru.md)\n\nIt is an ultimate tool for system permissions management. No longer you have to understand system API of each new permission type or search it on the Stack Overflow. 😄\n\n## Advantages\n\n📱 Supports the newest features of **iOS 17** and **macOS 14 Sonoma**\n\u003cbr/\u003e\n🖥 Works great with **Mac Catalyst**\n\n✋ Supports **all existing permission types**\n\u003cbr/\u003e\n🛡 Provides crash free by **validating your plist** keys\n\u003cbr/\u003e\n📬 Use **async/await** and **completion blocks** even where it is not provided by default system API\n\u003cbr/\u003e\n🛣 Forget about **thread management** by specifying desired dispatch queues to invoke completion blocks (optional)\n\n🚀 Completely written in **Swift**\n\u003cbr/\u003e\n🍭 Unifies your code **regardless of permission types** you are working with\n\u003cbr/\u003e\n🖼 Includes **native icons** and **localized strings** for your UI (optional)\n\u003cbr/\u003e\n🍕 Modular, add to your project **only what you need**\n\u003cbr/\u003e\n🪁 Does not contain anything redundant\n\n## Supported Types\n\n\u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Bluetooth@3x.png\" width=\"29\" height=\"29\" title=\"Bluetooth\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Calendars@3x.png\" width=\"29\" height=\"29\" title=\"Calendars\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Camera@3x.png\" width=\"29\" height=\"29\" title=\"Camera\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Contacts@3x.png\" width=\"29\" height=\"29\" title=\"Contacts\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/FaceID@3x.png\" width=\"29\" height=\"29\" title=\"Face ID\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Health@3x.png\" width=\"29\" height=\"29\" title=\"Health\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Home@3x.png\" width=\"29\" height=\"29\" title=\"Home\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/LocalNetwork@3x.png\" width=\"29\" height=\"29\" title=\"Local Network\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Location@3x.png\" width=\"29\" height=\"29\" title=\"Location\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Microphone@3x.png\" width=\"29\" height=\"29\" title=\"Microphone\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Motion@3x.png\" width=\"29\" height=\"29\" title=\"Motion\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Music@3x.png\" width=\"29\" height=\"29\" title=\"Music\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Notifications@3x.png\" width=\"29\" height=\"29\" title=\"Notifications\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Photos@3x.png\" width=\"29\" height=\"29\" title=\"Photos\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Reminders@3x.png\" width=\"29\" height=\"29\" title=\"Reminders\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Siri@3x.png\" width=\"29\" height=\"29\" title=\"Siri\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/SpeechRecognition@3x.png\" width=\"29\" height=\"29\" title=\"Speech Recognition\"/\u003e \u003cimg src=\"https://github.com/debug45/PermissionWizard/raw/master/Documentation/Tracking@3x.png\" width=\"29\" height=\"29\" title=\"Tracking\"/\u003e\n\n## Requirements\n\n- iOS 14 / macOS 11 Big Sur\n- Xcode 15\n- Swift 5.5\n\n## Installation\n\n### [CocoaPods](https://cocoapods.org)\n\nTo integrate **PermissionWizard** into your Xcode project, add it to your `Podfile`:\n\n```ruby\npod 'PermissionWizard'\n```\n\nBy default, the library will be installed fully.\n\nDue to Apple’s policy regarding system permissions, your app may be rejected due to mention of API that is not actually used. It is recommended to install only components that you need. In this case **you will not have any troubles**. ⚠️\n\n```ruby\npod 'PermissionWizard/Assets' # Icons and localized strings\npod 'PermissionWizard/Bluetooth'\npod 'PermissionWizard/Calendars'\npod 'PermissionWizard/Camera'\npod 'PermissionWizard/Contacts'\npod 'PermissionWizard/FaceID'\npod 'PermissionWizard/Health'\npod 'PermissionWizard/Home'\npod 'PermissionWizard/LocalNetwork'\npod 'PermissionWizard/Location'\npod 'PermissionWizard/Microphone'\npod 'PermissionWizard/Motion'\npod 'PermissionWizard/Music'\npod 'PermissionWizard/Notifications'\npod 'PermissionWizard/Photos'\npod 'PermissionWizard/Reminders'\npod 'PermissionWizard/Siri'\npod 'PermissionWizard/SpeechRecognition'\npod 'PermissionWizard/Tracking'\n```\n\nDo not specify `pod 'PermissionWizard'` if you install separate components.\n\n### [Carthage](https://github.com/Carthage/Carthage)\n\nTo integrate **PermissionWizard** into your Xcode project, add it to your `Cartfile`:\n\n```ogdl\ngithub \"debug45/PermissionWizard\"\n```\n\nBy default, the library is compiled fully when you build the project.\n\nDue to Apple’s policy regarding system permissions, your app may be rejected due to mention of API that is not actually used. It is recommended to enable only components that you need. In this case **you will not have any troubles**. ⚠️\n\nTo enable only components that you need, create the `PermissionWizard.xcconfig` file in the root directory of your project. Put appropriate settings into the file according to the following template:\n\n```\nENABLED_FEATURES = ASSETS BLUETOOTH CALENDARS CAMERA CONTACTS FACE_ID HEALTH HOME LOCAL_NETWORK LOCATION MICROPHONE MOTION MUSIC NOTIFICATIONS PHOTOS REMINDERS SIRI SPEECH_RECOGNITION TRACKING\nSWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(ENABLED_FEATURES) CUSTOM_SETTINGS\n```\n\nCustomize the first line of the template removing unnecessary component names.\n\n## How to Use\n\nUsing of **PermissionWizard** is incredibly easy!\n\n```swift\nimport PermissionWizard\n\nif useSwiftConcurrency {\n    await Permission.contacts.checkStatus() // .notDetermined\n} else {\n    Permission.contacts.checkStatus { status in\n        status // .notDetermined\n    }\n}\n\ndo {\n    if useSwiftConcurrency {\n        try await Permission.location.requestAccess(whenInUseOnly: true) // (value: .whenInUseOnly, isAccuracyReducing: false)\n    } else {\n        try Permission.location.requestAccess(whenInUseOnly: true) { status in\n            status.value // .whenInUseOnly\n            status.isAccuracyReducing // false\n        }\n    }\n    \n    if useSwiftConcurrency {\n        await Permission.camera.checkStatus(withMicrophone: true) // (camera: .granted, microphone: .denied)\n    } else {\n        Permission.camera.checkStatus(withMicrophone: true) { status in\n            status.camera // .granted\n            status.microphone // .denied\n        }\n    }\n} catch let error {\n    error.userInfo[\"message\"] // You must add a row with the “NSLocationWhenInUseUsageDescription” key to your app’s plist file and specify the reason why you are requesting access to location. This information will be displayed to a user.\n    \n    guard let error = error as? Permission.Error else {\n        return\n    }\n    \n    error.type // .missingPlistKey\n}\n```\n\nSome permission types support additional features. For example, if a user allows access to his location only with reduced accuracy, you can request temporary access to full accuracy:\n\n```swift\nif useSwiftConcurrency {\n    try? await Permission.location.requestTemporaryPreciseAccess(purposePlistKey: \"Default\") // true\n} else {\n    try? Permission.location.requestTemporaryPreciseAccess(purposePlistKey: \"Default\") { result in\n        result // true\n    }\n}\n```\n\nUnfortunately, the ability to work with certain permission types is limited by default system API. For example, you can check the current status of a home permission only by requesting it.\n\n### Info.plist\n\nFor each permission type you are using, Apple requires to add the corresponding string to your `Info.plist` that describes a purpose of your access requests. **PermissionWizard** can help you to find the name of a necessary plist key:\n\n```swift\nPermission.faceID.usageDescriptionPlistKey // NSFaceIDUsageDescription\n\nPermission.health.readingUsageDescriptionPlistKey // NSHealthUpdateUsageDescription\nPermission.health.writingUsageDescriptionPlistKey // NSHealthShareUsageDescription\n```\n\nIf you request access to some permission using default system API but forget to edit your `Info.plist`, the app will crash. However with **PermissionWizard** the crash will not occur — `try` is just used.\n\n### Thread Management\n\nIn some cases default system API may return a result in a different dispatch queue. To avoid a crash and instead of using `DispatchQueue.main.async`, you can ask **PermissionWizard** to invoke a completion block already in a preferred queue:\n\n```swift\nPermission.tracking.checkStatus { _ in\n    // Default queue\n}\n\nPermission.tracking.checkStatus(completion: { _ in\n    // DispatchQueue.main\n}, forcedInvokationQueue: .main)\n```\n\n### UI Assets\n\nIf your UI needs permission type icons or localized names, you can easily get it using **PermissionWizard**:\n\n```swift\nlet permission = Permission.speechRecognition.self\n\nimageView.image = permission.getIcon(squircle: true)\nlabel.text = permission.getLocalizedName() // Speech Recognition\n```\n\nKeep in mind that icons and localized strings are only available if the `Assets` component of **PermissionWizard** is installed (CocoaPods) or enabled (Carthage). All system languages are supported.\n\n## Known Issues\n\n- Local Network and Location permissions cannot be requested using async/await\n- Bluetooth permission always returns `.granted` on simulators\n- Local Network permission does not work on simulators\n\n## Roadmap\n\n- Extend support of macOS (specific permission types, native icons)\n- Make the library compatible with Swift Package Manager\n- Support more convenient usage in SwiftUI code\n\n## Conclusion\n\nYou can contact me on [Telegram](https://t.me/debug45) and [LinkedIn](https://linkedin.com/in/debug45). If you find an issue, please [tell](https://github.com/debug45/PermissionWizard/issues/new) about it.\n\nLibrary is released under the MIT license. The permission type icons and localized strings belong to Apple, their use is regulated by the company rules.\n\nIf **PermissionWizard** is useful for you please star this repository. Thank you! 👍","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebug45%2FPermissionWizard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdebug45%2FPermissionWizard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdebug45%2FPermissionWizard/lists"}