- August 28, 2025
- Mins Read
PermissionsSwiftUI displays and handles permissions in SwiftUI. It is largely inspired by SPPermissions. The UI is highly customizable and resembles an Apple style. If you like the project, please star ★.
You can install PermissionsSwiftUI into your Xcode project via SPM. To learn more about SPM, click here
For Xcode 13, navigate to Files → Add Package
https://github.com/jevonmao/PermissionsSwiftUI) and click Next.(You don’t need to add CorePermissionsSwiftUI or PermissionsSwiftUI)
(You don’t need to add CorePermissionsSwiftUI or PermissionsSwiftUI)
You can also install PermissionsSwiftUI with Cocoapods. Add pod 'PermissionsSwiftUI' in your podfile:
platform :ios, ‘14.0’
target ‘test abstract’ do
use_frameworks!
pod ‘PermissionsSwiftUI’
end
v1.4 is here! If you encounter any issues, please check out the migration guide designed to help developers resolve any deprecations and API updates.
To use PermissionsSwiftUI, simply add the JMModal modifier to any view:
.JMModal(showModal: $showModal, for: [.locationAlways, .photo, .microphone])`
Pass in a Binding<Bool> to show the modal view, and add whatever permissions you want to show. For example:
struct ContentView: View {
@State var showModal = false
var body: some View {
Button(action: {
showModal=true
}, label: {
Text(“Ask user for permissions”)
})
.JMModal(showModal: $showModal, for: [.locationAlways, .photo, .microphone])
}
}
The alert style is equally gorgeous, and allows for more versatile use. It is recommended when you have less than 3 permissions.
To show a permission pop up alert, use:
.JMAlert(showModal: $showModal, for: [.locationAlways, .photo])
Similar to the previous JMPermissions, you need to pass in a Binding<Bool> to show the view, and add whatever permissions you want to show. To quickly glance at all of PermissionsSwiftUI’s customization and configurations, check out the cheatsheet!
To customize permission texts, use the modifier setPermissionComponent() For example, you can change title, description, and image icon:
.setPermissionComponent(for: .camera,
image: AnyView(Image(systemName: “camera.fill”)),
title: “Camcorder”,
description: “App needs to record videos”)
and the result:
Or only change 1 of title and description:
setPermissionComponent(for: .tracking, title: “Trackers”)
setPermissionComponent(for: .tracking, description: “Tracking description”)
setPermissionComponent modifier on your root level view, after JMPermissions modifierThe image parameter accepts AnyView, so feel free to use SF Symbols or your custom asset:
.setPermissionComponent(for: .camera,
image: AnyView(Image(“Your-cool-image”))
Even full SwiftUI views will work😱:
.setPermissionComponent(for: .camera,
image: AnyView(YourCoolView())
You can use custom text and icons for all the supported permissions, with a single line of code.
To customize the header title, use the modifier changeHeaderTo:
.JMPermissions(showModal: $showModal, for: [.camera, .location, .calendar])
.changeHeaderTo(“App Permissions”)
To customize the header description, use the modifier changeHeaderDescriptionTo
.JMPermissions(showModal: $showModal, for: [.camera, .location, .photo])
.changeHeaderDescriptionTo(“Instagram need certain permissions in order for all the features to work.”)
To customize the bottom description, use the modifier changeBottomDescriptionTo
.JMPermissions(showModal: $showModal, for: [.camera, .location, .photo])
.changeBottomDescriptionTo(“If not allowed, you have to enable permissions in settings”)
To customize the header title, use the modifier changeHeaderTo:
You might find it incredibly useful to execute your code, or perform some update action when a PermissionsSwiftUI view appears and disappears.
You can perform some action when PermissionsSwiftUI view appears or disappears by:
.JMPermissions(showModal: $showModal, for: [.locationAlways, .photo, .microphone], onAppear: {}, onDisappear: {})
The onAppear and onDisappear closure parameters will be executed everytime PermissionsSwiftUI view appears and disappears.
The same view modifier closure for state changes are available for the JMAlert modifier:
.JMAlert(showModal: $showModal,
for: [.locationAlways, .photo],
onAppear: {print(“Appeared”)},
onDisappear: {print(“Disappeared”)})
PermissionsSwiftUI by default will automatically check for authorization status. It will only show permissions that are currently notDetermined status. (the iOS system prevents developers from asking for denied permissions. Allowed permissions will also be ignored by PermissionsSwiftUI). If all permissions are allowed or denied, PermissionsSwiftUI will not show the modal or alert at all. To set auto check authorization, use the autoCheckAuthorization parameter:
.JMModal(showModal: $showModal, for: [.camera], autoCheckAuthorization: false)
PermissionsSwiftUI by default will not have any auto dismiss behavior. You can override this behavior to make it automatically dismiss the modal or alert after the user allows the last permission item. (All permissions must be ALLOWED, if any is DENIED, it will not auto dismiss).
.JMModal(… autoDismiss: Bool) -> some View
Pass in true or false to select whether to automatically dismiss the view.
Using PermissionSwiftUI’s capabilities, developers and designers can customize all the UI colors with incredible flexibility. You can fully configure all color at all states with your custom colors.
To easily change the accent color:
.setAccentColor(to: Color(.sRGB, red: 56/255, green: 173/255,
blue: 169/255, opacity: 1))
To change the primary (default Apple blue) and tertiary (default Apple red) colors:
.setAccentColor(toPrimary: Color(.sRGB, red: 56/255, green: 173/255,
blue: 169/255, opacity: 1),
toTertiary: Color(.systemPink))
⚠️
.setAccentColor()and.setAllowButtonColor()should never be used at the same time.
To unleash the full customization of all button colors under all states, you need to pass in the AllButtonColors struct:
.setAllowButtonColor(to: .init(buttonIdle: ButtonColor(foregroundColor: Color,
backgroundColor: Color),
buttonAllowed: ButtonColor(foregroundColor: Color,
backgroundColor: Color),
buttonDenied: ButtonColor(foregroundColor: Color,
backgroundColor: Color)))
For more information regarding the above method, reference the official documentation.
PermissionsSwiftUI will by default, prevent the user from dismissing the modal and alert before all permissions have been interacted with. This means if the user has not explicitly denied or allowed EVERY permission shown, they will not be able to dismiss the PermissionsSwiftUI view. This restricts dismissal behavior can be overridden by the var restrictModalDismissal: Bool or var restrictAlertDismissal: Bool properties. To disable the default restrict dismiss behavior:
.JMModal(showModal: $show, for permissions: [.camera], restrictDismissal: false)
You can also configure with the model:
let model: PermissionStore = {
var model = PermissionStore()
model.permissions = [.camera]
model.restrictModalDismissal = false
model.restrictAlertDismissal = false
return model
}
……
.JMModal(showModal: $showModal, forModel: model)
Unlike all the other permissions, the configuration for health permission is a little different. Because Apple requires developers to explicitly set read and write types, PermissionsSwiftUI greatly simplifies the process.
The structure HKAccess is required when initializing health permission’s enum associated values. It encapsulates the read and write type permissions for the health permission.
To set read and write health types (activeEnergyBurned is used as example here):
let healthTypes = Set([HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!])
.JMModal(showModal: $show, for: [.health(categories: .init(readAndWrite: healthTypes))])
//Same exact syntax for JMAlert styles
.JMAlert(showModal: $show, for: [.health(categories: .init(readAndWrite: healthTypes))])
To set read or write individually:
let readTypes = Set([HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!])
let writeTypes = Set([HKSampleType.quantityType(forIdentifier: .appleStandTime)!])
.JMModal(showModal: $showModal, for: [.health(categories: .init(read: readTypes, write: writeTypes))])
You may also set only read or write type:
let readTypes = Set([HKSampleType.quantityType(forIdentifier: .activeEnergyBurned)!])
.JMModal(showModal: $showModal, for: [.health(categories: .init(read: readTypes))])
Customize overall accent color:
setAccentColor(to:)
setAccentColor(toPrimary:toTertiary:)
Customize title:
changeHeaderTo(_:)
Customize top description:
changeHeaderDescriptionTo(_:)
Customize each permission’s displayed text & image:
setPermissionComponent(for:image:title:description:)
setPermissionComponent(for:title:)
setPermissionComponent(for:description:)
Customize allow button’s colors:
setAllowButtonColor(to:)
Automatically dismiss after last
autoDismiss: Bool
Check authorization before showing modal or alert
autoCheckAuthorization: Bool
Prevent dismissing before all permissions interacted
restrictDismissal: Bool
Do something right before view appear
onAppear: () -> Void
Do something right before view disappear
onDisappear: (() -> Void
Here is a list of all the permissions PermissionsSwiftUI supports. Yup, even the newest tracking permission for iOS 14 so you can stay on top of your game. All permissions in PermissionsSwiftUI come with a default name, description, and a stunning Apple native SF Symbols icon.
Support for FaceID permission is work in progress and coming soon! If you don’t find a permission you need, open an issue. Even better, build it yourself and open a pull request, you can follow this step-by-step guide on adding new permissions.
This package provides you with an easy way to show tooltips over any SwiftUI view, since Apple does not provide ...
SimpleToast is a simple, lightweight, flexible and easy to use library to show toasts / popup notifications inside iOS or ...
Create Toast Views with Minimal Effort in SwiftUI Using SSToastMessage. SSToastMessage enables you to effortlessly add toast notifications, alerts, and ...