{"id":1792,"url":"https://github.com/iosphere/ISHPermissionKit","last_synced_at":"2025-08-02T04:32:35.197Z","repository":{"id":18150535,"uuid":"21245057","full_name":"iosphere/ISHPermissionKit","owner":"iosphere","description":"A polite and unified way of asking for permission on iOS","archived":false,"fork":false,"pushed_at":"2021-01-08T15:16:39.000Z","size":1227,"stargazers_count":614,"open_issues_count":8,"forks_count":44,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-07-27T23:48:12.165Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://iosphere.de","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iosphere.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-06-26T15:13:52.000Z","updated_at":"2025-06-07T20:14:16.000Z","dependencies_parsed_at":"2022-09-05T17:42:05.557Z","dependency_job_id":null,"html_url":"https://github.com/iosphere/ISHPermissionKit","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/iosphere/ISHPermissionKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iosphere%2FISHPermissionKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iosphere%2FISHPermissionKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iosphere%2FISHPermissionKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iosphere%2FISHPermissionKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iosphere","download_url":"https://codeload.github.com/iosphere/ISHPermissionKit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iosphere%2FISHPermissionKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334618,"owners_count":24233793,"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","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-01-05T20:15:55.915Z","updated_at":"2025-08-02T04:32:34.901Z","avatar_url":"https://github.com/iosphere.png","language":"Objective-C","funding_links":[],"categories":["Permissions","Foundation"],"sub_categories":["Other Parsing","Other free courses"],"readme":"# \u003cimg src=\"icon.png\" align=\"center\" width=\"40\" height=\"40\"\u003e ISHPermissionKit\n\n[![Travis Build Status](https://travis-ci.org/iosphere/ISHPermissionKit.svg?branch=master)](http://travis-ci.org/iosphere/ISHPermissionKit)\u0026nbsp;\n[![Version](http://cocoapod-badges.herokuapp.com/v/ISHPermissionKit/badge.png)](http://cocoadocs.org/docsets/ISHPermissionKit)\u0026nbsp;\n[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n\n*ISHPermissionKit* provides a polite and unified way of asking for permission on iOS. It\nalso provides UI to explain the permission requirements before presenting\nthe system permission dialog to the user. This allows the developer to postpone\nthe system dialog. The framework provides no actual chrome, leaving the\ndeveloper and designer in charge of creating the views.\n\nWhile you can use *ISHPermissionKit* to ask for a user's permission for multiple\ncategories at the same time and out of context, you should continue to ask for\npermission only when the app needs it. However, there might be occassions when\nmultiple permissions are required at the same time, e.g., when starting to record\nlocation and motion data.\n\nThis framework also provides explicit ways to ask for the user's permission\nwhere the system APIs only provide implicit methods of doing so.\n\n**Supported permission categories:**\n\n* Calendar: Events and Reminders\n* Contacts\n* Location: Always and WhenInUse\n* Motion: Activity data (step counting, etc.)\n* HealthKit\n* Microphone\n* Music Library\n* Notifications: Local and Remote\n* Photos: Library and Camera\n* Social: Facebook, Twitter, SinaWeibo, TencentWeibo\n* Siri\n* Speech Recognition\n\nThe library compiles with the **iOS 11 SDK** and later and deploys back to\n**iOS 9**. Permission categories that were added later than the deployment\ntarget will be skipped on unsupported versions.\n\nAll permission categories relate to **sensitive user information**. If your app\nbinary contains code to access this information, it has to comply with\nspecial review guidelines and other requirements to pass binary validation\nin App Store Connect and app review. Therefore, you must specifically enable\nthe categories you need with build flags, everything else will not be included\nin the framework. Please read the [installation instructions](#installation)\ncarefully.\n\n*ISHPermissionKit* verifies that the required usage descriptions are provided in your\napp's `Info.plist`. If the `DEBUG` preprocessor macro is set, it will assert and\nexplain which keys need to be added. Other requirements for each permission\ncategory are mentioned in the header documentation in `ISHPermissionCategory.h`.\n\n\u003cimg src=\"assets/demo.gif\" align=\"center\" width=\"320\" height=\"568\" alt=\"Sample App Demo\"\u003e\n\nIn contrast to other libraries, *ISHPermissionKit* allows you to present custom\nview controllers, ask for several permissions in a sequence, provides a unified\nAPI through subclasses, and is **iOS 10 compatible**.\n\nRecommended reading: [The Right Way to Ask Users for Mobile\nPermissions](https://medium.com/@mulligan/the-right-way-to-ask-users-for-ios-permissions-96fa4eb54f2c \"by Brenden Mulligan (@mulligan)\")\n\n# Roadmap\n\nMissing features:\n\n1. Resetting state correctly when device is reset\n2. Permission monitoring and NSNotifications upon changes\n\nPlease file an issue for missing permissions.\n\n# How to Use\n\n## Sample App\n\nIn order to demonstrate all steps that are required to use *ISHPermissionKit*,\nthe sample application has a [separate repository](https://github.com/iosphere/ISHPermissionKitSampleApp).\n\nThe sample app uses the [dynamically-linked framework](#dynamically-linked-framework).\n\n## Installation\n\n### Build Flags\n\nYour variant of *ISHPermissionKit* will only include the permission categories\nyou actually need. We use preprocessor macros to ensure any unused code is not\ncompiled to save you from suprising App Store rejections, as some privacy\nguidelines apply to all apps that *contain* code to access user data, regardless\nof whether or not the code is ever called in your app. How to enable the\ncategories you need depends on how you install *ISHPermissionKit* (see below).\n\n### Static Library\n\nAdd this Xcode project as a subproject of your app. Then link your app target\nagainst the static library (`ISHPermissionKitLib.a`). You will also need to add\nthe static library as a target dependency. Both settings can be found in your\napp target's *Build Phases*.\n\n**You must [provide a build configuration](#providing-a-build-configuration) manually.**\n\nUse `#import \u003cISHPermissionKit/ISHPermissionKit.h\u003e` to import all public headers.\nThe static library version is recommended if you are concerned about app launch\ntimes, as a high number of dynamic libraries [could increase the latter](https://developer.apple.com/videos/play/wwdc2016/406/).\n\n### Dynamically-Linked Framework\n\nAdd this Xcode project as a subproject of your app. Then add the framework\n(`ISHPermissionKit.framework`) to the app's embedded binaries (on the *General*\ntab of your app target's settings). On the *Build Phases* tab, verify that the\nframework has also been added to the *Target Dependencies* and *Link Binary with\nLibraries* phases, and that a new *Embed Frameworks* phase has been created.\n\n**You must [provide a build configuration](#providing-a-build-configuration) manually.**\n\nYou can use [Carthage](https://github.com/Carthage/Carthage) to fetch and build\nthe framework. You will still have to provide a build configuration manually.\n\nThe framework can be used as a module, so you can use `@import ISHPermissionKit;`\nto import all public headers.\nFurther reading on Modules: [Clang Documentation](http://clang.llvm.org/docs/Modules.html)\n\n### Providing a Build Configuration\n\nWhen building the static or dynamic library, *ISHPermissionKit* will look for a\nfile named `ISHPermissionKitAppConfiguration.xcconfig` in the same directory as\n*ISHPermissionKit*'s root directory (not *within* the root directory), and two\nlevels further up the directory hierarchy. Configuration files in either\nlocation allow you to set preprocessor flags that will be used when compiling\nthe framework.\n\nWe strongly recommend to start with a copy of the template config provided in this\nrepository, [`ISHPermissionKitAppConfiguration.xcconfig`](/ISHPermissionKitAppConfiguration.xcconfig).\nIt includes a list of all supported flags, and you can easily specify which features\nyou need by commenting or uncommenting the respective lines.\n\nYou will have to use the same configuration file to build your app, else the\ncategory-specific symbols will not be available. In your project settings, you\ncan select a configuration file for each target:\n\n![Setting a configuration file](assets/config_file.png)\n\nIf you already use a configuration file, you can pick one and include the other\nin it. Ensure to always use `$(inherited)` when setting preprocessor macros.\n\n### Required Frameworks\n\n*ISHPermissionKit* uses system frameworks to accomplish its tasks. Most of\nthem will be linked automatically unless you have disabled \"Enable Modules\"\n(`CLANG_ENABLE_MODULES`) and \"Link Frameworks Automatically\"\n(`CLANG_MODULES_AUTOLINK`) in your app target's build settings.\n\nUnfortunately, some framework are not weakly linked automatically which\nwill cause your app to crash at launch on older systems that don't support\nthe respective framework. These frameworks must be explicitly linked in\nyour app, and set to \"Optional\". Feel free to duplicate rdar://28008958\n(https://openradar.appspot.com/search?query=28008958).\n\n![Weak-linking a framework in Xcode](assets/weak_linking.png)\n\nThis is currently required for the *Speech* framework, and only if you\nenable the speech permission category.\n\n### Cocoa Pods\n\nYou can use CocoaPods to install *ISHPermissionKit* as a static or dynamic library.\nEach permission category requires a separate (sub)pod. The following sample Podfile\nincludes all available pods – you should pick only those that you are actually\nusing in your app.\n\n```ruby\ntarget 'MyApp' do\n  use_frameworks! // remove this line if you want to link your pods statically\n  pod 'ISHPermissionKit/Motion'\n  pod 'ISHPermissionKit/Health'\n  pod 'ISHPermissionKit/Location'\n  pod 'ISHPermissionKit/Microphone'\n  pod 'ISHPermissionKit/PhotoLibrary'\n  pod 'ISHPermissionKit/Camera'\n  pod 'ISHPermissionKit/Notifications'\n  pod 'ISHPermissionKit/SocialAccounts'\n  pod 'ISHPermissionKit/Contacts'\n  pod 'ISHPermissionKit/Calendar'\n  pod 'ISHPermissionKit/Reminders'\n  pod 'ISHPermissionKit/Siri'\n  pod 'ISHPermissionKit/Speech'\n  pod 'ISHPermissionKit/MusicLibrary'\nend\n```\n\n[Providing a build configuration](#providing-a-build-configuration) manually is not\nrequired when you use CocoaPods, and you can also ignore the\n[Required Frameworks](#required-frameworks) section.\n\nSee the [official website](https://cocoapods.org/#get_started) to get started with\nCocoaPods.\n\n## ISHPermissionsViewController\n\nYou can request permission for a single category or a sequence of categories.\nThe following example presents a `ISHPermissionsViewController` for `Activity`\nand `LocationWhenInUse` permissions if needed.\n\n```objective-c\nNSArray *permissions = @[\n    @(ISHPermissionCategoryLocationWhenInUse),\n    @(ISHPermissionCategoryActivity)\n    ];\nISHPermissionsViewController *vc = [ISHPermissionsViewController permissionsViewControllerWithCategories:permissions dataSource:self];\n\nif (vc) {\n    UIViewController *presentingVC = [self.window rootViewController];\n    [presentingVC presentViewController:vc\n                               animated:YES\n                             completion:nil];\n}\n```\n\nThe designated constructor returns `nil` if non of the categories allow a user\nprompt (either because the user already granted or denied the permission, does\nnot want to be asked again, or the feature is simply not supported on the\ndevice).\n\nYou can set a `completionBlock` or `delegate` (both optional) that will be\nnotified once the `ISHPermissionsViewController` has iterated through all\ncategories. If you do not set a delegate, the view controller will simply be\ndismissed once finished, and if set, the completion block will be called. If you\ndo set a delegate, the delegate is responsible for dismissing the view\ncontroller.\n\nThe `dataSource` is required and must provide one instance of a\n`ISHPermissionRequestViewController` for each requested\n`ISHPermissionCategory`.\n\nThe `ISHPermissionRequestViewController` provides `IBAction`s to _prompt for the\nuser's permission_, _ask later_, and _don't ask_. It does not however provide\nany buttons or UI. Your subclass can create a view with text, images, and buttons\netc., explaining in greater detail why your app needs a certain permission. The\nsubclass should contain buttons that trigger at least one of the actions\nmentioned above (see the header for their signatures). A _cancel button_ should\ncall `changePermissionStateToAskAgainFromSender:`. If your subclass overwrites\nany of these three actions, you must call `super`.\n\n## ISHPermissionRequest\n\nThe `ISHPermissionRequest` can be used to determine the current state of a\npermission category. It can also be used to trigger the user prompt asking for\npermissions outside of the `ISHPermissionsViewController`.\n\nYou must use the additional (`...+All.h`) method `+requestForCategory:` to create the\nappropriate request for the given permission category.\n\nHere is how you check the permissions to access the microphone:\n\n```objective-c\nISHPermissionRequest *r = [ISHPermissionRequest requestForCategory:ISHPermissionCategoryMicrophone];\nBOOL granted = ([r permissionState] == ISHPermissionStateAuthorized);\n```\n\nThe same example for local notifications:\n\n```objective-c\nISHPermissionRequest *r = [ISHPermissionRequest requestForCategory:ISHPermissionCategoryNotificationLocal];\nBOOL granted = ([r permissionState] == ISHPermissionStateAuthorized);\n```\n\n# How to Contribute\n\nContributions are welcome. Check out the roadmap and open issues.\nAdding support for more permission types is probably\nmost rewarding, you can find a few hints on how to get started below.\n\n## Adding Support for New Permissions\n\nYou will need to create a new subclass of `ISHPermissionRequest` and add an\n`ISHPermissionCategory` (make sure to use explicit values as these may be\npersisted). Don't change existing values. Finally, wire it up in\n`ISHPermissionRequest+All` by returning your new subclass in\n`+requestForCategory:`.\n\nSubclasses must implement at least two methods:\n\n1. `- (ISHPermissionState)permissionState`\n2. `- (void)requestUserPermissionWithCompletionBlock:(ISHPermissionRequestCompletionBlock)completion`\n\nWhat these methods actually do depends on the mechanism that the system APIs\nprovide. Ideally, `permissionState` should check the system authorization state\nfirst and return appropriate internal enum values from\n`ISHPermissionState`. If the system state is unavailable or is similar to\n`kCLAuthorizationStatusNotDetermined` then this method should return\n`internalPermissionState`. You should try to map system provided states to\n`ISHPermissionState` without resorting to the `internalPermissionState` as much as\npossible.\n\nWhen requesting the permission state you should only store the result in\n`internalPermissionState` if the state cannot easily be retrieved from the\nsystem (as is the case, e.g., with activity monitoring from the designated\nco-processor).\n\nBefore a new permission can be added, you must introduce a new build flag and\nensure the library compiles with and without it. Please update this document\naccordingly, add the new build flag to the template configuration file\n([`ISHPermissionKitAppConfiguration.xcconfig`](/ISHPermissionKitAppConfiguration.xcconfig)),\nand create a new CocoaPods subspec.\n\n# Attribution\n\n*ISHPermissionKit* icon designed by\n[Jason Grube (CC BY 3.0)](http://thenounproject.com/term/fingerprint/23303/) from the\n[Noun Project](http://thenounproject.com)\n\n# More OpenSource Projects by iosphere\n\n\u003cimg src=\"https://raw.githubusercontent.com/iosphere/ISHHoverBar/master/icon.png\" align=\"center\" width=\"40\" height=\"40\"\u003e [`ISHHoverBar`](https://github.com/iosphere/ISHHoverBar) - A floating UIToolBar replacement as seen in the iOS 10 Maps app, supporting both vertical and horizontal orientation\n\n\u003cimg src=\"https://raw.githubusercontent.com/iosphere/ISHPullUp/master/icon.png\" align=\"center\" width=\"40\" height=\"40\"\u003e [`ISHPullUp`](https://github.com/iosphere/ISHPullUp) - Vertical split view controller with pull up gesture as seen in the iOS 10 Maps app\n\n# Apps Using ISHPermissionKit\n\n\u003cimg src=\"assets/app_trails.png\" align=\"center\" width=\"36\" height=\"36\"\u003e\n\u003ca href=\"http://trails.io/\" title=\"Trails · Outdoor GPS Logbook\"\u003eTrails · Outdoor GPS Logbook\u003c/a\u003e\n\n\u003cimg src=\"assets/app_sumup.png\" align=\"center\" width=\"36\" height=\"36\"\u003e\n\u003ca href=\"https://itunes.apple.com/app/sumup/id514879214\" title=\"SumUp – Accept EMV card payments\"\u003eSumUp – Accept EMV card payments\u003c/a\u003e\n\n\u003cimg src=\"assets/app_snow.png\" align=\"center\" width=\"36\" height=\"36\"\u003e\n\u003ca href=\"https://itunes.apple.com/en/app/snow-report-myswitzerland/id341755817?mt=8\" title=\"Swiss Snow Report - Current snow and weather information for the best Swiss winter sports destinations\"\u003eSwiss Snow Report\u003c/a\u003e\n\nIf your app uses ISHPermissionKit, let us know and we will include it here.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiosphere%2FISHPermissionKit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiosphere%2FISHPermissionKit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiosphere%2FISHPermissionKit/lists"}