A unified API to ask for permissions on iOS

Overview

Travis Status CocoaPods compatible Carthage compatible

Permission exposes a unified API to request permissions on iOS.

UsageExampleInstallationLicense

Usage

Permission

Permission.swift PermissionStatus.swift

let permission: Permission = .contacts

print(permission.status) // .notDetermined

permission.request { status in
    switch status {
    case .authorized:    print("authorized")
    case .denied:        print("denied")
    case .disabled:      print("disabled")
    case .notDetermined: print("not determined")
    }
}
Supported Permissions

PermissionType.swift Types/

PermissionAlert

PermissionAlert.swift

Denied and disabled alerts

When you first request a permission, a system alert is presented to the user. If you request a permission that was denied/disabled, a PermissionAlert will be presented. You might want to change the default title, message, cancel and settings text:

let alert = permission.deniedAlert // or permission.disabledAlert

alert.title    = "Please allow access to your contacts"
alert.message  = nil
alert.cancel   = "Cancel"
alert.settings = "Settings"

Set permission.presentDeniedAlert = false or permission.presentDisabledAlert = false if you don't want to present these alerts.

Pre-permission alerts

In order not to burn your only chance of displaying the system alert, you can present a pre-permission alert. See this article for more informations.

permission.presentPrePermissionAlert = true

let alert = permission.prePermissionAlert

alert.title   = "Let Foo Access Photos?"
alert.message = "This lets you choose which photos you want to add to your Foo profile"
alert.cancel  = "Not now"
alert.confirm = "Give Access"

The system alert will only be presented if the user taps "Give Access".

PermissionSet

PermissionSet.swift

Use a PermissionSet to check the status of a group of Permission and to react when a permission is requested.

let permissionSet = PermissionSet(.contacts, .camera, .microphone, .photos)
permissionSet.delegate = self

print(permissionSet.status) // .notDetermined

// ...

func permissionSet(permissionSet: PermissionSet, willRequestPermission permission: Permission) {
    print("Will request \(permission)")
}

func permissionSet(permissionSet: PermissionSet, didRequestPermission permission: Permission) {
    switch permissionSet.status {
    case .authorized:    print("all the permissions are granted")
    case .denied:        print("at least one permission is denied")
    case .disabled:      print("at least one permission is disabled")
    case .notDetermined: print("at least one permission is not determined")
    }
}

PermissionButton

PermissionButton

A PermissionButton requests the permission when tapped and updates itself when its underlying permission status changes.

let button = PermissionButton(.photos)

PermissionButton is a subclass of UIButton. All the getters and setters of UIButton have their equivalent in PermissionButton.

button.setTitles([
    .authorized:    "Authorized",
    .denied:        "Denied",
    .disabled:      "Disabled",
    .notDetermined: "Not determined"
])

// button.setAttributedTitles
// button.setTitleColors
// button.setTitleShadowColors
// button.setImages
// button.setBackgroundImages
// etc.

Third-party libraries:

Example

class PermissionsViewController: UIViewController, PermissionSetDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let label = UILabel()

        let contacts   = PermissionButton(.contacts)
        let camera     = PermissionButton(.camera)
        let microphone = PermissionButton(.microphone)
        let photos     = PermissionButton(.photos)

        contacts.setTitles([
            .notDetermined: "Contacts - NotDetermined"
            .authorized:    "Contacts - Authorized",
            .denied:        "Contacts - Denied"
        ])

        contacts.setTitleColors([
            .notDetermined: .black,
            .authorized:    .green,
            .denied:        .red
        ])

        // ...

        let permissionSet = PermissionSet(contacts, camera, microphone, photos)

        permissionSet.delegate = self

        label.text = String(describing: permissionSet.status)

        for subview in [label, contacts, camera, microphone, photos] {
            view.addSubview(subview)
        }
    }

    func permissionSet(permissionSet: PermissionSet, didRequestPermission permission: Permission) {
        label.text = String(permissionSet.status)
    }
}

Installation

Carthage

Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Permission into your Xcode project using Carthage, specify it in your Cartfile:

github "delba/Permission"
Configuration

Due to Apple's new policy regarding permission access, binaries may be rejected due to a perceived attempt to access privacy-sensitive data without a usage key, and then further rejected for not actually requesting permissions.

As a workaround, you can provide custom build flags before building the dynamic framework to only compile with permissions you request. This is done by adding a configuration file named PermissionConfiguration.xcconfig to the root of your project. For convenience, you can use PermissionConfiguration.xcconfig in the Permission/ repo directory. Just comment out the permissions you want to use, and compile the framework.

To compile with only notifications and photos permissions:

PERMISSION_BLUETOOTH         = // PERMISSION_BLUETOOTH
PERMISSION_CAMERA            = PERMISSION_CAMERA
PERMISSION_CONTACTS          = // PERMISSION_CONTACTS
PERMISSION_EVENTS            = // PERMISSION_EVENTS
PERMISSION_LOCATION          = // PERMISSION_LOCATION
PERMISSION_MICROPHONE        = // PERMISSION_MICROPHONE
PERMISSION_MOTION            = // PERMISSION_MOTION
PERMISSION_NOTIFICATIONS     = PERMISSION_NOTIFICATIONS
PERMISSION_PHOTOS            = // PERMISSION_PHOTOS
PERMISSION_REMINDERS         = // PERMISSION_REMINDERS
PERMISSION_SPEECH_RECOGNIZER = // PERMISSION_SPEECH_RECOGNIZER
PERMISSION_MEDIA_LIBRARY     = // PERMISSION_MEDIA_LIBRARY

// Do not modify this line. Instead, remove comments above as needed to enable the categories your app uses.
PERMISSION_FLAGS= $(PERMISSION_BLUETOOTH) $(PERMISSION_CAMERA) $(PERMISSION_CONTACTS) $(PERMISSION_EVENTS) $(PERMISSION_LOCATION) $(PERMISSION_MICROPHONE) $(PERMISSION_MOTION) $(PERMISSION_NOTIFICATIONS) $(PERMISSION_PHOTOS) $(PERMISSION_REMINDERS) $(PERMISSION_SPEECH_RECOGNIZER) $(PERMISSION_MEDIA_LIBRARY)

SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(PERMISSION_FLAGS)

Cocoapods

CocoaPods is a dependency manager for Cocoa projects.

You can install it with the following command:

$ gem install cocoapods

To integrate Permission into your Xcode project using CocoaPods, specify it in your Podfile. Due to Apple's new policy regarding permission access you need to specifically define what kind of permissions you want to access using subspecs. For example if you want to access the Camera and the Notifications you define the following:

use_frameworks!

pod 'Permission/Camera'
pod 'Permission/Notifications'

Please see Permission.podspec for more information about which subspecs are available.

License

Copyright (c) 2015-2019 Damien (http://delba.io)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • [WIP] Compiled Permission Build Flags

    [WIP] Compiled Permission Build Flags

    Began sketching out an idea in order to ensure that this can be compiled with/out certain permissions, based on the developer's choice. Resolution for #57.

    Idea is to just use build flags defined in PermissionConfiguration.xcconfig to conditionally compile the individual Permission extensions with/out their dependencies. A fatalError will occur if the developer attempts to request permission for an ability they did not compile the framework with.

    TODO

    • [x] Address Book
    • [x] Bluetooth
    • [x] Contacts
    • [x] Camera
    • [x] Events
    • [x] Location
    • [x] Location Always
    • [x] Location When In Use
    • [x] Microphone
    • [x] Motion
    • [x] Notification
    • [x] Photos
    • [x] Reminders
    • [x] Speech Recognizer
    • [x] Media Library
    • [x] User Provided .xcconfig file
    • [ ] CocoaPods Support
    • [x] Carthage Support
    • [x] Update README.md
    opened by justinmakaila 22
  • Unable to access Photos permission

    Unable to access Photos permission

    Podfile:

    • pod 'Permission/Photos'

    Code:

    • let permission: Permission = .photos

    Error:

    • Type 'Permission' has no member 'photos'

    More info:

    • Xcode 8.3.1
    • Swift 3.1
    • iOS 10.3.2
    opened by theblixguy 16
  • This app attempts to access privacy-sensitive data without

    This app attempts to access privacy-sensitive data without

    When submitting the app with Xcode 8 i get an error requesting me to add keys to the .plist. Not sure what the best course of action is here. I could work around it for now by deleting the files I didn't need as adding all the keys seems like a ground for rejection. M aybe there's an option to separate them into different modules?

    Dear developer,

    We have discovered one or more issues with your recent delivery for "app-name". To process your ? delivery, the following issues must be corrected:

    This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSContactsUsageDescription key with a string value explaining to the user how the app uses this data.

    This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCalendarsUsageDescription key with a string value explaining to the user how the app uses this data.

    This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothPeripheralUsageDescription key with a string value explaining to the user how the app uses this data.

    This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.

    This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMotionUsageDescription key with a string value explaining to the user how the app uses this data.

    Once these issues have been corrected, you can then redeliver the corrected binary.

    Regards,

    The App Store team

    opened by jonandersen 16
  • Swift 3.0 release

    Swift 3.0 release

    Hey Damien! I don't know the current state of this library for Swift 3.0, but would it be possible to release alpha/beta version if it is not completed yet? Would love to update RxPermission to the newest standards 🐼 Cheers!

    opened by sunshinejr 15
  • Add UserNotifications Framework for iOS 10+

    Add UserNotifications Framework for iOS 10+

    I added a permission for the new notification framework UserNotifications in iOS 10 to request permission with the new api.

    • add permission UserNotification
    • add configuration PERMISSION_USERNOTIFICATIONS
    • add permissionType userNotifications
    • removed the file private static variable _notification cause it's never read
    • did not change the requestedNotifications default cause it returns the same information

    I tried to keep it in the structure you designed the framework.

    opened by mrgrauel 14
  • Need help configuring

    Need help configuring

    conf

    Should I copy paste that file into the root of my project then add the following?:

    PERMISSION_ADDRESS_BOOK      = // PERMISSION_ADDRESS_BOOK
    PERMISSION_BLUETOOTH         = // PERMISSION_BLUETOOTH
    PERMISSION_CAMERA            = PERMISSION_CAMERA
    PERMISSION_CONTACTS          = // PERMISSION_CONTACTS
    PERMISSION_EVENTS            = // PERMISSION_EVENTS
    PERMISSION_LOCATION          = // PERMISSION_LOCATION
    PERMISSION_MICROPHONE        = // PERMISSION_MICROPHONE
    PERMISSION_MOTION            = // PERMISSION_MOTION
    PERMISSION_NOTIFICATIONS     = PERMISSION_NOTIFICATION
    PERMISSION_PHOTOS            = // PERMISSION_PHOTOS
    PERMISSION_REMINDERS         = // PERMISSION_REMINDERS
    PERMISSION_SPEECH_RECOGNIZER = // PERMISSION_SPEECH_RECOGNIZER
    PERMISSION_MEDIA_LIBRARY     = // PERMISSION_MEDIA_LIBRARY
    
    // Do not modify this line. Instead, remove comments above as needed to enable the categories your app uses.
    PERMISSION_FLAGS= $(PERMISSION_ADDRESS_BOOK) $(PERMISSION_BLUETOOTH) $(PERMISSION_CAMERA) $(PERMISSION_CONTACTS) $(PERMISSION_EVENTS) $(PERMISSION_LOCATION) $(PERMISSION_MICROPHONE) $(PERMISSION_MOTION) $(PERMISSION_NOTIFICATIONS) $(PERMISSION_PHOTOS) $(PERMISSION_REMINDERS) $(PERMISSION_SPEECH_RECOGNIZER) $(PERMISSION_MEDIA_LIBRARY)
    
    SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(PERMISSION_FLAGS)
    

    Right now that file looks like this:

    CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Permission
    GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
    HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
    OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
    PODS_BUILD_DIR = $BUILD_DIR
    PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
    PODS_ROOT = ${SRCROOT}
    PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
    SKIP_INSTALL = YES
    

    Thanks in advance!

    opened by LarsWith 13
  • Pre-permission not working with .Bluetooth

    Pre-permission not working with .Bluetooth

    I'm having an issue using the pre-permission with the .Bluetooth Permission type. Does this have something to do with this line in Permission.swift case .Bluetooth: requestBluetooth(self.callback)?

    Still a bit new to Swift so not 100% sure what is wrong here.

    opened by jakerockland 11
  • Notifications request callback not called

    Notifications request callback not called

    It seems like the implementation of notification request callbacks is missing:

    // Notifications.swift
    38:     func requestNotifications(callback: Callback) {
    39:        // TODO: pass callback to finishedRequestingNotifications
    

    On a second node, it seems like the only correct way to implement this behaviour is with a UIApplicationDelegate class, and not with an NSTimer like it's done on line 41.

    opened by hartbit 9
  • app crash on launch(swift 3)

    app crash on launch(swift 3)

    Hello I use the branch swift-3.0 and xcode Version 8.0. I run the application on ios 10 and everything works. But if I run the application on ios 9 , app crash on launch and I get error dyld: Library not loaded: /System/Library/Frameworks/Speech.framework/Speech Referenced from: /private/var/containers/Bundle/Application/XXXXXXXX/Frameworks/Permission.framework/Permission Reason: image not found Thanks

    opened by alexkotenko 8
  • Crash when changing permissions in iOS Settings app

    Crash when changing permissions in iOS Settings app

    If I set a closure as below, then open the iOS Settings app and change the permission there, the app will crash

    permission.request { status in switch status { case .Authorized: print("authorized") case .Denied: print("denied") case .Disabled: print("disabled") case .NotDetermined: print("not determined") } }

    opened by mathiasgithub 7
  • Printing denied without the dialog is being clicked either on Don't allow or ok when asking permission for Notifications

    Printing denied without the dialog is being clicked either on Don't allow or ok when asking permission for Notifications

    Printing denied without the dialog is being clicked either on Don't allow or ok

    let permission: Permission = .Notifications(categories: nil) permission.request { status in switch status { case .Authorized: print("authorized") case .Denied: print("denied") case .Disabled: print("disabled") case .NotDetermined: print("not determined") }

    opened by gitton 7
  • Location Permission on iOS 14

    Location Permission on iOS 14

    Our tester told me a crazy bug and I found the repro steps as: Precondition: My app has 2 pages-A and B. And while the user clicks the button in page A, the app should direct to page B. And in the function “viewDidLoad” of page B, the location permission is asked. Steps:

    1. Set the location permission of my app to “Never”, and the app has not launched;
    2. Open the app, skip to page B and ask for the location permission, set it to “Ask Next Time”; and return to my app; then the app backs to page A automatically;
    3. Skip to page B again, and the popup ask you to allow the permission, select “Not Allowed”; then it backs to page A;
    4. Skip to page B again, and the app reminds the user to skip to system settings to change the permission; then change it to “Ask Next Time”;
    5. Skip to page B again, and set the system pop to “Not Allowed”, then I found no callback this time.
    opened by zhongxunchao 1
  • Is this project deprecated?

    Is this project deprecated?

    It looks like this project has been out of development for almost a year, and there are 6 pull requests in pending.

    What is the author's attitude towards this project and if you need some help with it, please let us know.

    opened by yunhao 0
  •  adapt iOS14

    adapt iOS14

    Hello, first of all, thank you very much for using your code, let me save a lot of trouble. When do you plan to adapt iOS14? Camera permissions on iOS14 have been increased by the limited type.

    opened by shen0607 1
Owner
Damien
Damien
Ask permissions on Swift. Available List, Dialog & Native interface. Can check state permission.

SPPermissions About Library for ask permissions. You can check state of permissions, available .authorized, .denied & .notDetermined. Available ready-

Ivan Vorobei 5.1k Dec 30, 2022
Cluster's reusable pre-permissions utility that lets developers ask the users on their own dialog for photos or contacts access, before making the system-based request.

Cluster's reusable pre-permissions utility that lets developers ask the users on their own dialog for photos or contacts access, before making the system-based request. This is based on the Medium post by Cluster describing the different ways to ask for iOS permissions (https://medium.com/p/96fa4eb54f2c).

Riz 1.2k Sep 29, 2022
A polite and unified way of asking for permission on iOS

ISHPermissionKit ISHPermissionKit provides a polite and unified way of asking for permission on iOS. It also provides UI to explain the permission req

iosphere GmbH 619 Nov 3, 2022
A set of SwiftUI dynamic property wrappers that provide a more familiar API for accessing the Contacts framework. (iOS, watchOS, macOS)

Connections Also available as a part of my SwiftUI+ Collection – just add it to Xcode 13+ A set of SwiftUI dynamic property wrappers that provide a mo

SwiftUI+ 9 Oct 7, 2022
AREK is a clean and easy way to request any kind of iOS permission (with some nifty features 🤖)

AREK is a clean and easy to use wrapper over any kind of iOS permission written in Swift. Why AREK could help you building a better app is well descri

Ennio Masi 961 Dec 20, 2022
A visual permission manager for iOS

VWWPermissionKit We've all been there. You get started on your latest and greatest app when you have to add logic to prompt the user for permissions b

Zakk Hoyt 144 Feb 24, 2022
A unified API to ask for permissions on iOS

PAPermissions PAPermissions is a fully customizable and ready-to-run library to handle permissions through a ViewController Right now it supports out

Pasquale Ambrosini 694 Oct 17, 2022
The "Ask Me" is simple iOS application which shows answer on the screen everytime when the user press the ask button

The "Ask Me" is simple iOS application which shows answer on the screen everytime when the user press the ask button. This application is build and design by Chetan Parate using Xcode and Swift.

Chetan Parate 0 Oct 27, 2021
An iOS pre-permissions utility that lets developers ask users on their own dialog for calendar, contacts, location, photos, reminders, twitter, push notifications and more, before making the system-based permission request.

An iOS pre-permissions utility that lets developers ask users on their own dialog for calendar, contacts, location, photos, reminders, twitter, push notifications and more, before making the system-based permission request.

Joe L 420 Dec 22, 2022
Ask permissions on Swift. Available List, Dialog & Native interface. Can check state permission.

SPPermissions About Library for ask permissions. You can check state of permissions, available .authorized, .denied & .notDetermined. Available ready-

Ivan Vorobei 5.1k Dec 30, 2022
Cluster's reusable pre-permissions utility that lets developers ask the users on their own dialog for photos or contacts access, before making the system-based request.

Cluster's reusable pre-permissions utility that lets developers ask the users on their own dialog for photos or contacts access, before making the system-based request. This is based on the Medium post by Cluster describing the different ways to ask for iOS permissions (https://medium.com/p/96fa4eb54f2c).

Riz 1.2k Sep 29, 2022
Unified API Library for: Cloud Storage, Social Log-In, Social Interaction, Payment, Email, SMS, POIs, Video & Messaging.

Unified API Library for: Cloud Storage, Social Log-In, Social Interaction, Payment, Email, SMS, POIs, Video & Messaging. Included services are Dropbox, Google Drive, OneDrive, OneDrive for Business, Box, Egnyte, PayPal, Stripe, Google Places, Foursquare, Yelp, YouTube, Vimeo, Twitch, Facebook Messenger, Telegram, Line, Viber, Facebook, GitHub, Google+, LinkedIn, Slack, Twitter, Windows Live, Yahoo, Mailjet, Sendgrid, Twilio, Nexmo, Twizo.

CloudRail 195 Nov 29, 2021
RxSwift bindings for Permissions API in iOS.

RxPermission RxSwift bindings for Permission API that helps you with Permissions in iOS. Installation RxPermission is available through CocoaPods. I c

Luke 230 Dec 27, 2022
A polite and unified way of asking for permission on iOS

ISHPermissionKit ISHPermissionKit provides a polite and unified way of asking for permission on iOS. It also provides UI to explain the permission req

iosphere GmbH 619 Nov 3, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Dec 30, 2022
Easy to use cryptographic framework for data protection: secure messaging with forward secrecy and secure data storage. Has unified APIs across 14 platforms.

Themis provides strong, usable cryptography for busy people General purpose cryptographic library for storage and messaging for iOS (Swift, Obj-C), An

Cossack Labs 1.6k Dec 30, 2022
A simple and attractive AlertView to ask permission to your users for Push Notification.

A simple and attractive AlertView **to ask permission to your users for Push Notification.** PRESENTATION Ask permission to user for push notification

Boisney Philippe 37 Mar 23, 2022
Review page interaction - handy and pretty way to ask for review.

RPInteraction Overview Review page interaction - handy and pretty way to ask for review. Inspired by dribbble shot. Requirements iOS8 Installation RPI

Nurdaulet Bolatov 27 Jul 16, 2021
Review page interaction - handy and pretty way to ask for review

RPInteraction Overview Review page interaction - handy and pretty way to ask for review. Inspired by dribbble shot. Requirements iOS8 Installation RPI

Nurdaulet Bolatov 27 Jul 16, 2021
🗣Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permissions

Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permissions. It uses i

Algolia 490 Dec 19, 2022