├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Package.swift
├── PermissionsKit.podspec
├── README.md
└── Sources
├── BluetoothPermission
├── BluetoothHandler.swift
└── BluetoothPermission.swift
├── CalendarPermission
└── CalendarPermission.swift
├── CameraPermission
└── CameraPermission.swift
├── ContactsPermission
└── ContactsPermission.swift
├── FaceIDPermission
└── FaceIDPermission.swift
├── HealthPermission
└── HealthPermission.swift
├── LocationPermission
├── Handlers
│ ├── LocationAlwaysHandler.swift
│ └── LocationWhenInUseHandler.swift
├── LocationAccuracy.swift
└── LocationPermission.swift
├── MediaLibraryPermission
└── MediaLibraryPermission.swift
├── MicrophonePermission
└── MicrophonePermission.swift
├── MotionPermission
└── MotionPermission.swift
├── NotificationPermission
├── NotificationAccess+userNotifcationAuthorizationOptions.swift
└── NotificationPermission.swift
├── PermissionsKit
├── Data
│ └── Text.swift
├── Permission.swift
└── Resources
│ └── Localization
│ ├── ar.lproj
│ └── Localizable.strings
│ ├── de.lproj
│ └── Localizable.strings
│ ├── en.lproj
│ └── Localizable.strings
│ ├── es.lproj
│ └── Localizable.strings
│ ├── fa.lproj
│ └── Localizable.strings
│ ├── fr.lproj
│ └── Localizable.strings
│ ├── it.lproj
│ └── Localizable.strings
│ ├── nl.lproj
│ └── Localizable.strings
│ ├── pl.lproj
│ └── Localizable.strings
│ ├── pt.lproj
│ └── Localizable.strings
│ ├── ru.lproj
│ └── Localizable.strings
│ ├── uk.lproj
│ └── Localizable.strings
│ ├── zh-Hant.lproj
│ └── Localizable.strings
│ └── zh_Hans.lproj
│ └── Localizable.strings
├── PhotoLibraryPermission
└── PhotoLibraryPermission.swift
├── RemindersPermission
└── RemindersPermission.swift
├── SiriPermission
└── SiriPermission.swift
├── SpeechRecognizerPermission
└── SpeechPermission.swift
└── TrackingPermission
└── TrackingPermission.swift
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [sparrowcode]
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ivanvorobei
7 | ---
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ivanvorobei
7 | ---
8 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Goal
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # macOS Files
2 | .DS_Store
3 | .Trashes
4 |
5 | # Swift Package Manager
6 | .swiftpm
7 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | hello@ivanvorobei.io.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Here provided info about contribution process and recommendations.
4 |
5 | ## Codestyle
6 |
7 | ### Marks
8 |
9 | For clean struct code good is using marks.
10 |
11 | ```swift
12 | class Example {
13 |
14 | // MARK: - Init
15 |
16 | init() {}
17 | }
18 | ```
19 |
20 | Here you find all which using in project:
21 |
22 | - // MARK: - Init
23 | - // MARK: - Lifecycle
24 | - // MARK: - Layout
25 | - // MARK: - Public
26 | - // MARK: - Private
27 | - // MARK: - Internal
28 | - // MARK: - Models
29 | - // MARK: - Ovveride
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Sparrow Code
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.9
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "PermissionsKit",
7 | defaultLocalization: "en",
8 | platforms: [
9 | .iOS(.v12),
10 | .tvOS(.v12),
11 | .watchOS(.v4),
12 | .macOS(.v13)
13 | ],
14 | products: [
15 | .library(
16 | name: "CameraPermission",
17 | targets: ["CameraPermission"]
18 | ),
19 | .library(
20 | name: "PhotoLibraryPermission",
21 | targets: ["PhotoLibraryPermission"]
22 | ),
23 | .library(
24 | name: "NotificationPermission",
25 | targets: ["NotificationPermission"]
26 | ),
27 | .library(
28 | name: "MicrophonePermission",
29 | targets: ["MicrophonePermission"]
30 | ),
31 | .library(
32 | name: "CalendarPermission",
33 | targets: ["CalendarPermission"]
34 | ),
35 | .library(
36 | name: "ContactsPermission",
37 | targets: ["ContactsPermission"]
38 | ),
39 | .library(
40 | name: "RemindersPermission",
41 | targets: ["RemindersPermission"]
42 | ),
43 | .library(
44 | name: "SpeechRecognizerPermission",
45 | targets: ["SpeechRecognizerPermission"]
46 | ),
47 | .library(
48 | name: "LocationPermission",
49 | targets: ["LocationPermission"]
50 | ),
51 | .library(
52 | name: "MotionPermission",
53 | targets: ["MotionPermission"]
54 | ),
55 | .library(
56 | name: "MediaLibraryPermission",
57 | targets: ["MediaLibraryPermission"]
58 | ),
59 | .library(
60 | name: "BluetoothPermission",
61 | targets: ["BluetoothPermission"]
62 | ),
63 | .library(
64 | name: "TrackingPermission",
65 | targets: ["TrackingPermission"]
66 | ),
67 | .library(
68 | name: "FaceIDPermission",
69 | targets: ["FaceIDPermission"]
70 | ),
71 | .library(
72 | name: "SiriPermission",
73 | targets: ["SiriPermission"]
74 | ),
75 | .library(
76 | name: "HealthPermission",
77 | targets: ["HealthPermission"]
78 | ),
79 | ],
80 | dependencies: [],
81 | targets: [
82 | .target(
83 | name: "PermissionsKit",
84 | resources: [
85 | .process("Resources")
86 | ],
87 | swiftSettings: [
88 | .define("PERMISSIONSKIT_SPM")
89 | ]
90 | ),
91 | .target(
92 | name: "CameraPermission",
93 | dependencies: [.target(name: "PermissionsKit")],
94 | swiftSettings: [
95 | .define("PERMISSIONSKIT_CAMERA"),
96 | .define("PERMISSIONSKIT_SPM")
97 | ]
98 | ),
99 | .target(
100 | name: "PhotoLibraryPermission",
101 | dependencies: [.target(name: "PermissionsKit")],
102 | swiftSettings: [
103 | .define("PERMISSIONSKIT_PHOTOLIBRARY"),
104 | .define("PERMISSIONSKIT_SPM")
105 | ]
106 | ),
107 | .target(
108 | name: "NotificationPermission",
109 | dependencies: [.target(name: "PermissionsKit")],
110 | swiftSettings: [
111 | .define("PERMISSIONSKIT_NOTIFICATION"),
112 | .define("PERMISSIONSKIT_SPM")
113 | ]
114 | ),
115 | .target(
116 | name: "MicrophonePermission",
117 | dependencies: [.target(name: "PermissionsKit")],
118 | swiftSettings: [
119 | .define("PERMISSIONSKIT_MICROPHONE"),
120 | .define("PERMISSIONSKIT_SPM")
121 | ]
122 | ),
123 | .target(
124 | name: "CalendarPermission",
125 | dependencies: [.target(name: "PermissionsKit")],
126 | swiftSettings: [
127 | .define("PERMISSIONSKIT_CALENDAR"),
128 | .define("PERMISSIONSKIT_SPM")
129 | ]
130 | ),
131 | .target(
132 | name: "ContactsPermission",
133 | dependencies: [.target(name: "PermissionsKit")],
134 | swiftSettings: [
135 | .define("PERMISSIONSKIT_CONTACTS"),
136 | .define("PERMISSIONSKIT_SPM")
137 | ]
138 | ),
139 | .target(
140 | name: "RemindersPermission",
141 | dependencies: [.target(name: "PermissionsKit")],
142 | swiftSettings: [
143 | .define("PERMISSIONSKIT_REMINDERS"),
144 | .define("PERMISSIONSKIT_SPM")
145 | ]
146 | ),
147 | .target(
148 | name: "SpeechRecognizerPermission",
149 | dependencies: [.target(name: "PermissionsKit")],
150 | swiftSettings: [
151 | .define("PERMISSIONSKIT_SPEECH"),
152 | .define("PERMISSIONSKIT_SPM")
153 | ]
154 | ),
155 | .target(
156 | name: "LocationPermission",
157 | dependencies: [
158 | .target(name: "PermissionsKit")
159 | ],
160 | swiftSettings: [
161 | .define("PERMISSIONSKIT_LOCATION"),
162 | .define("PERMISSIONSKIT_SPM")
163 | ]
164 | ),
165 | .target(
166 | name: "MotionPermission",
167 | dependencies: [.target(name: "PermissionsKit")],
168 | swiftSettings: [
169 | .define("PERMISSIONSKIT_MOTION"),
170 | .define("PERMISSIONSKIT_SPM")
171 | ]
172 | ),
173 | .target(
174 | name: "MediaLibraryPermission",
175 | dependencies: [.target(name: "PermissionsKit")],
176 | swiftSettings: [
177 | .define("PERMISSIONSKIT_MEDIA_LIBRARY"),
178 | .define("PERMISSIONSKIT_SPM")
179 | ]
180 | ),
181 | .target(
182 | name: "BluetoothPermission",
183 | dependencies: [.target(name: "PermissionsKit")],
184 | swiftSettings: [
185 | .define("PERMISSIONSKIT_BLUETOOTH"),
186 | .define("PERMISSIONSKIT_SPM")
187 | ]
188 | ),
189 | .target(
190 | name: "TrackingPermission",
191 | dependencies: [.target(name: "PermissionsKit")],
192 | swiftSettings: [
193 | .define("PERMISSIONSKIT_TRACKING"),
194 | .define("PERMISSIONSKIT_SPM")
195 | ]
196 | ),
197 | .target(
198 | name: "FaceIDPermission",
199 | dependencies: [.target(name: "PermissionsKit")],
200 | swiftSettings: [
201 | .define("PERMISSIONSKIT_FACEID"),
202 | .define("PERMISSIONSKIT_SPM")
203 | ]
204 | ),
205 | .target(
206 | name: "SiriPermission",
207 | dependencies: [.target(name: "PermissionsKit")],
208 | swiftSettings: [
209 | .define("PERMISSIONSKIT_SIRI"),
210 | .define("PERMISSIONSKIT_SPM")
211 | ]
212 | ),
213 | .target(
214 | name: "HealthPermission",
215 | dependencies: [.target(name: "PermissionsKit")],
216 | swiftSettings: [
217 | .define("PERMISSIONSKIT_HEALTH"),
218 | .define("PERMISSIONSKIT_SPM")
219 | ]
220 | ),
221 | ],
222 | swiftLanguageVersions: [.v5]
223 | )
224 |
--------------------------------------------------------------------------------
/PermissionsKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "PermissionsKit"
4 | s.version = "11.0.0"
5 | s.summary = "Ask permissions with ready-use interface. You can check status permission and if it has been requested before. Support SwiftUI."
6 | s.homepage = "https://github.com/sparrowcode/PermissionsKit"
7 | s.source = { :git => "https://github.com/sparrowcode/PermissionsKit.git", :tag => s.version }
8 | s.license = { :type => "MIT", :file => "LICENSE" }
9 | s.author = { "Sparrow Code" => "hello@sparrowcode.io" }
10 |
11 | s.requires_arc = true
12 | s.ios.framework = 'UIKit'
13 | s.tvos.framework = 'UIKit'
14 | s.swift_version = ['4.2', '5.0']
15 | s.ios.deployment_target = "11.0"
16 | s.tvos.deployment_target = "11.0"
17 |
18 | s.default_subspec = 'Core'
19 |
20 | s.subspec 'Core' do |subspec|
21 | subspec.source_files = "Sources/PermissionsKit/**/*.swift"
22 | subspec.pod_target_xcconfig = {
23 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_COCOAPODS"
24 | }
25 | subspec.resource_bundles = {
26 | "PermissionsKit" => [
27 | "Sources/PermissionsKit/Resources/Localization/*.lproj/*.strings"
28 | ]
29 | }
30 | end
31 |
32 | s.subspec 'CameraPermission' do |subspec|
33 | subspec.dependency 'PermissionsKit/Core'
34 | subspec.source_files = "Sources/CameraPermission/**/*.swift"
35 | subspec.pod_target_xcconfig = {
36 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_CAMERA PERMISSIONSKIT_COCOAPODS"
37 | }
38 | end
39 |
40 | s.subspec 'PhotoLibraryPermission' do |subspec|
41 | subspec.dependency 'PermissionsKit/Core'
42 | subspec.source_files = "Sources/PhotoLibraryPermission/**/*.swift"
43 | subspec.pod_target_xcconfig = {
44 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_PHOTOLIBRARY PERMISSIONSKIT_COCOAPODS"
45 | }
46 | end
47 |
48 | s.subspec 'NotificationPermission' do |subspec|
49 | subspec.dependency 'PermissionsKit/Core'
50 | subspec.source_files = "Sources/NotificationPermission/**/*.swift"
51 | subspec.pod_target_xcconfig = {
52 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_NOTIFICATION PERMISSIONSKIT_COCOAPODS"
53 | }
54 | end
55 |
56 | s.subspec 'MicrophonePermission' do |subspec|
57 | subspec.dependency 'PermissionsKit/Core'
58 | subspec.source_files = "Sources/MicrophonePermission/**/*.swift"
59 | subspec.pod_target_xcconfig = {
60 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_MICROPHONE PERMISSIONSKIT_COCOAPODS"
61 | }
62 | end
63 |
64 | s.subspec 'CalendarPermission' do |subspec|
65 | subspec.dependency 'PermissionsKit/Core'
66 | subspec.source_files = "Sources/CalendarPermission/**/*.swift"
67 | subspec.pod_target_xcconfig = {
68 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_CALENDAR PERMISSIONSKIT_COCOAPODS"
69 | }
70 | end
71 |
72 | s.subspec 'ContactsPermission' do |subspec|
73 | subspec.dependency 'PermissionsKit/Core'
74 | subspec.source_files = "Sources/ContactsPermission/**/*.swift"
75 | subspec.pod_target_xcconfig = {
76 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_CONTACTS PERMISSIONSKIT_COCOAPODS"
77 | }
78 | end
79 |
80 | s.subspec 'RemindersPermission' do |subspec|
81 | subspec.dependency 'PermissionsKit/Core'
82 | subspec.source_files = "Sources/RemindersPermission/**/*.swift"
83 | subspec.pod_target_xcconfig = {
84 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_REMINDERS PERMISSIONSKIT_COCOAPODS"
85 | }
86 | end
87 |
88 | s.subspec 'SpeechRecognizerPermission' do |subspec|
89 | subspec.dependency 'PermissionsKit/Core'
90 | subspec.source_files = "Sources/SpeechRecognizerPermission/**/*.swift"
91 | subspec.pod_target_xcconfig = {
92 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_SPEECH PERMISSIONSKIT_COCOAPODS"
93 | }
94 | end
95 |
96 | s.subspec 'LocationPermission' do |subspec|
97 | subspec.dependency 'PermissionsKit/Core'
98 | subspec.source_files = "Sources/LocationPermission/**/*.swift"
99 | subspec.pod_target_xcconfig = {
100 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_LOCATION PERMISSIONSKIT_COCOAPODS"
101 | }
102 | end
103 |
104 | s.subspec 'MotionPermission' do |subspec|
105 | subspec.dependency 'PermissionsKit/Core'
106 | subspec.source_files = "Sources/MotionPermission/**/*.swift"
107 | subspec.pod_target_xcconfig = {
108 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_MOTION PERMISSIONSKIT_COCOAPODS"
109 | }
110 | end
111 |
112 | s.subspec 'MediaLibraryPermission' do |subspec|
113 | subspec.dependency 'PermissionsKit/Core'
114 | subspec.source_files = "Sources/MediaLibraryPermission/**/*.swift"
115 | subspec.pod_target_xcconfig = {
116 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_MEDIA_LIBRARY PERMISSIONSKIT_COCOAPODS"
117 | }
118 | end
119 |
120 | s.subspec 'BluetoothPermission' do |subspec|
121 | subspec.dependency 'PermissionsKit/Core'
122 | subspec.source_files = "Sources/BluetoothPermission/**/*.swift"
123 | subspec.pod_target_xcconfig = {
124 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_BLUETOOTH PERMISSIONSKIT_COCOAPODS"
125 | }
126 | end
127 |
128 | s.subspec 'TrackingPermission' do |subspec|
129 | subspec.dependency 'PermissionsKit/Core'
130 | subspec.source_files = "Sources/TrackingPermission/**/*.swift"
131 | subspec.pod_target_xcconfig = {
132 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_TRACKING PERMISSIONSKIT_COCOAPODS"
133 | }
134 | end
135 |
136 | s.subspec 'FaceIDPermission' do |subspec|
137 | subspec.dependency 'PermissionsKit/Core'
138 | subspec.source_files = "Sources/FaceIDPermission/**/*.swift"
139 | subspec.pod_target_xcconfig = {
140 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_FACEID PERMISSIONSKIT_COCOAPODS"
141 | }
142 | end
143 |
144 | s.subspec 'SiriPermission' do |subspec|
145 | subspec.dependency 'PermissionsKit/Core'
146 | subspec.source_files = "Sources/SiriPermission/**/*.swift"
147 | subspec.pod_target_xcconfig = {
148 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_SIRI PERMISSIONSKIT_COCOAPODS"
149 | }
150 | end
151 |
152 | s.subspec 'HealthPermission' do |subspec|
153 | subspec.dependency 'PermissionsKit/Core'
154 | subspec.source_files = "Sources/HealthPermission/**/*.swift"
155 | subspec.pod_target_xcconfig = {
156 | "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSIONSKIT_HEALTH PERMISSIONSKIT_COCOAPODS"
157 | }
158 | end
159 | end
160 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PermissionsKit
2 |
3 | Universal API for request permission and get its statuses — available `.authorized`, `.denied` & `.notDetermined`.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ### iOS Dev Community
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | ## Navigate
36 |
37 | - [Permissions](#permissions)
38 | - [Installation](#installation)
39 | - [Swift Package Manager](#swift-package-manager)
40 | - [CocoaPods](#cocoapods)
41 | - [Why Modules](#why-modules)
42 | - [Usage](#request-permission)
43 | - [Request Permission](#request-permission)
44 | - [Get Status Permission](#get-status-permission)
45 | - [Keys in Info.plist](#keys-in-infoplist)
46 | - [Localisations](#localisation)
47 | - [Apps Using](#apps-using)
48 |
49 | ### Permissions
50 |
51 | | Icon | Permission | Key for `Info.plist` | Get Status | Make Request |
52 | | :--: | :---------- | :------------------- | :--------: | :----------: |
53 | |
| Bluetooth | NSBluetoothAlwaysUsageDescription, NSBluetoothPeripheralUsageDescription | ✅ | ✅ |
54 | |
| Calendar | NSCalendarsUsageDescription, NSCalendarsFullAccessUsageDescription, NSCalendarsWriteOnlyAccessUsageDescription | ✅ | ✅ |
55 | |
| Camera | NSCameraUsageDescription | ✅ | ✅ |
56 | |
| Contacts | NSContactsUsageDescription | ✅ | ✅ |
57 | |
| FaceID | NSFaceIDUsageDescription | ☑️ | ✅ |
58 | |
| Health | NSHealthUpdateUsageDescription, NSHealthShareUsageDescription | ✅ | ✅ |
59 | |
| Location | NSLocationAlwaysAndWhenInUseUsageDescription NSLocationWhenInUseUsageDescription | ✅ | ✅ |
60 | |
| Media Library | NSAppleMusicUsageDescription | ✅ | ✅ |
61 | |
| Microphone | NSMicrophoneUsageDescription | ✅ | ✅ |
62 | |
| Motion | NSMotionUsageDescription | ✅ | ✅ |
63 | |
| Notification | | ✅ | ✅ |
64 | |
| Photo Library | NSPhotoLibraryUsageDescription, NSPhotoLibraryAddUsageDescription | ✅ | ✅ |
65 | |
| Reminders | NSRemindersUsageDescription, NSRemindersFullAccessUsageDescription | ✅ | ✅ |
66 | |
| Siri | NSSiriUsageDescription | ✅ | ✅ |
67 | |
| Speech Recognizer | NSSpeechRecognitionUsageDescription | ✅ | ✅ |
68 | |
| Tracking | NSUserTrackingUsageDescription | ✅ | ✅ |
69 |
70 | ## Installation
71 |
72 | Ready to use on iOS 12+. Supports iOS, macOS, visionOS, tvOS & watchOS. Working with `UIKit` and `SwiftUI`.
73 |
74 | ### Swift Package Manager
75 |
76 | In Xcode go to Project -> Your Project Name -> `Package Dependencies` -> Tap *Plus*. Insert url:
77 |
78 | ```
79 | https://github.com/sparrowcode/PermissionsKit
80 | ```
81 |
82 | Next, choose the permissions that you need. But don't add all of them, because apple will reject app.
83 | Or adding it to the `dependencies` of your `Package.swift`:
84 |
85 | ```swift
86 | dependencies: [
87 | .package(url: "https://github.com/sparrowcode/PermissionsKit", .upToNextMajor(from: "11.0.0"))
88 | ]
89 | ```
90 |
91 | and choose valid targets.
92 |
93 | ### CocoaPods:
94 |
95 | This is an outdated way. I advise you to use [SPM](#swift-package-manager). However, I will continue to support Cocoapods for some time.
96 |
97 | Cocoapods Installation
98 |
99 | [CocoaPods](https://cocoapods.org) is a dependency manager. For usage and installation instructions, visit their website. To integrate using CocoaPods, specify it in your `Podfile`:
100 |
101 | ```ruby
102 | pod 'PermissionsKit/NotificationPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
103 | ```
104 |
105 | Due to Apple's new policy regarding permission access you need to specifically define what kind of permissions you want to access using subspecs.
106 |
107 | ```ruby
108 | pod 'PermissionsKit/CameraPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
109 | pod 'PermissionsKit/ContactsPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
110 | pod 'PermissionsKit/CalendarPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
111 | pod 'PermissionsKit/PhotoLibraryPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
112 | pod 'PermissionsKit/NotificationPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
113 | pod 'PermissionsKit/MicrophonePermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
114 | pod 'PermissionsKit/RemindersPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
115 | pod 'PermissionsKit/SpeechRecognizerPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
116 | pod 'PermissionsKit/LocationPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
117 | pod 'PermissionsKit/MotionPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
118 | pod 'PermissionsKit/MediaLibraryPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
119 | pod 'PermissionsKit/BluetoothPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
120 | pod 'PermissionsKit/TrackingPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
121 | pod 'PermissionsKit/FaceIDPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
122 | pod 'PermissionsKit/SiriPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
123 | pod 'PermissionsKit/HealthPermission', :git => 'https://github.com/sparrowcode/PermissionsKit'
124 | ```
125 |
126 |
127 | ## Why Modules
128 |
129 | If you put all your code into one package and compile it, the Apple Review Team will see a lot of calls to the permissions API. Most likely, they will ask you to provide a valid reason for why you really need those permissions. Using modules allows you to compile only the parts of the code that are actually in use. Just select only what you need.
130 |
131 | > [!WARNING]
132 | > Import only the permissions you really need.
133 |
134 | ## Request Permission
135 |
136 | ```swift
137 | import PermissionsKit
138 | import NotificationPermission
139 |
140 | PermissionsKit.Permission.notification([.alert, .badge, .sound]).request {
141 |
142 | }
143 | ```
144 |
145 | ## Get Status Permission
146 |
147 | ```swift
148 | import PermissionsKit
149 | import NotificationPermission
150 |
151 | let authorized = Permission.notification.authorized
152 | ```
153 |
154 | > [!WARNING]
155 | > For FaceID permission no way detect if request `.authorized` or `.notDetermined` accurate. Status `.denied` detect well. For now for both states return `.notDetermined`.
156 |
157 | ## Keys in `Info.plist`
158 |
159 | You need to add some strings to the `Info.plist` file with descriptions per Apple's requirements. You can get a plist of keys for permissions as follows:
160 |
161 | ```swift
162 | let key = Permission.bluetooth.usageDescriptionKey
163 | ```
164 |
165 | > [!NOTE]
166 | > Do not use the description as the name of the key. Xcode can't build this.
167 |
168 | ### Localisation
169 |
170 | If you use xliff localization export, keys will be create automatically. If you prefer do the localization file manually, you need to create `InfoPlist.strings`, select languages on the right side menu and add keys as keys in plist-file. See:
171 |
172 | ```
173 | "NSCameraUsageDescription" = "Here description of usage camera";
174 | ```
175 |
176 | ## Apps Using
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 | If you use a `PermissionsKit`, add your app via Pull Request.
194 |
--------------------------------------------------------------------------------
/Sources/BluetoothPermission/BluetoothHandler.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_BLUETOOTH
23 | import Foundation
24 | import CoreBluetooth
25 |
26 | class BluetoothHandler: NSObject, CBCentralManagerDelegate {
27 |
28 | var completion: ()->Void = {}
29 |
30 | // MARK: - Init
31 |
32 | static let shared: BluetoothHandler = .init()
33 |
34 | override init() {
35 | super.init()
36 | }
37 |
38 | // MARK: - Manager
39 |
40 | var manager: CBCentralManager?
41 |
42 | func reqeustUpdate() {
43 | if manager == nil {
44 | self.manager = CBCentralManager(delegate: self, queue: nil, options: [:])
45 | } else {
46 | completion()
47 | }
48 | }
49 |
50 | func centralManagerDidUpdateState(_ central: CBCentralManager) {
51 | if #available(iOS 13.0, tvOS 13, *) {
52 |
53 | let authorization: CBManagerAuthorization = {
54 | #if os(visionOS)
55 | return CBManager.authorization
56 | #else
57 | return central.authorization
58 | #endif
59 | }()
60 |
61 | switch authorization {
62 | case .notDetermined:
63 | break
64 | default:
65 | self.completion()
66 | }
67 | } else {
68 | switch CBPeripheralManager.authorizationStatus() {
69 | case .notDetermined:
70 | break
71 | default:
72 | self.completion()
73 | }
74 | }
75 | }
76 | }
77 | #endif
78 |
--------------------------------------------------------------------------------
/Sources/BluetoothPermission/BluetoothPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if PERMISSIONSKIT_BLUETOOTH
27 | import Foundation
28 | import CoreBluetooth
29 | import CloudKit
30 |
31 | public extension Permission {
32 |
33 | static var bluetooth: BluetoothPermission {
34 | return BluetoothPermission()
35 | }
36 | }
37 |
38 | public class BluetoothPermission: Permission {
39 |
40 | open override var kind: Permission.Kind { .bluetooth }
41 | open var usageDescriptionKey: String? { "NSBluetoothAlwaysUsageDescription" }
42 |
43 | public override var status: Permission.Status {
44 | if #available(iOS 13.1, tvOS 13.1, *) {
45 | switch CBCentralManager.authorization {
46 | case .allowedAlways: return .authorized
47 | case .notDetermined: return .notDetermined
48 | case .restricted: return .denied
49 | case .denied: return .denied
50 | @unknown default: return .denied
51 | }
52 | } else if #available(iOS 13.0, tvOS 13.0, *) {
53 | switch CBCentralManager().authorization {
54 | case .allowedAlways: return .authorized
55 | case .notDetermined: return .notDetermined
56 | case .restricted: return .denied
57 | case .denied: return .denied
58 | @unknown default: return .denied
59 | }
60 | } else {
61 | switch CBPeripheralManager.authorizationStatus() {
62 | case .authorized: return .authorized
63 | case .denied: return .denied
64 | case .restricted: return .denied
65 | case .notDetermined: return .notDetermined
66 | @unknown default: return .denied
67 | }
68 | }
69 | }
70 |
71 | public override func request(completion: @escaping () -> Void) {
72 | BluetoothHandler.shared.completion = completion
73 | BluetoothHandler.shared.reqeustUpdate()
74 | }
75 | }
76 | #endif
77 |
78 |
--------------------------------------------------------------------------------
/Sources/CalendarPermission/CalendarPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_CALENDAR
27 | import Foundation
28 | import EventKit
29 |
30 | public extension Permission {
31 |
32 | static func calendar(access: CalendarAccess) -> CalendarPermission {
33 | CalendarPermission(kind: .calendar(access: access))
34 | }
35 | }
36 |
37 | public class CalendarPermission: Permission {
38 |
39 | private var _kind: Permission.Kind
40 |
41 | // MARK: - Init
42 |
43 | init(kind: Permission.Kind) {
44 | self._kind = kind
45 | }
46 |
47 | open override var kind: Permission.Kind { self._kind }
48 | open var usageDescriptionKey: String? {
49 | if #available(iOS 17, *) {
50 | switch kind {
51 | case .calendar(let access):
52 | switch access {
53 | case .full:
54 | return "NSCalendarsFullAccessUsageDescription"
55 | case .write:
56 | return "NSCalendarsWriteOnlyAccessUsageDescription"
57 | }
58 | default:
59 | fatalError()
60 | }
61 | } else {
62 | return "NSCalendarsUsageDescription"
63 | }
64 | }
65 |
66 | public override var status: Permission.Status {
67 | // Fix when status first time response with other state.
68 | let _ = EKEventStore.authorizationStatus(for: EKEntityType.event)
69 |
70 | switch EKEventStore.authorizationStatus(for: EKEntityType.event) {
71 | case .authorized: return .authorized
72 | case .denied: return .denied
73 | case .fullAccess: return .authorized
74 | case .notDetermined: return .notDetermined
75 | case .restricted: return .denied
76 | case .writeOnly:
77 | if #available(iOS 17, *) {
78 | switch kind {
79 | case .calendar(let access):
80 | switch access {
81 | case .full:
82 | return .denied
83 | case .write:
84 | return .authorized
85 | }
86 | default:
87 | fatalError()
88 | }
89 | } else {
90 | return .authorized
91 | }
92 | @unknown default: return .denied
93 | }
94 | }
95 |
96 | public override func request(completion: @escaping () -> Void) {
97 |
98 | let eventStore = EKEventStore()
99 |
100 | if #available(iOS 17.0, *) {
101 |
102 | let requestWriteOnly = {
103 | eventStore.requestWriteOnlyAccessToEvents { (accessGranted: Bool, error: Error?) in
104 | DispatchQueue.main.async {
105 | completion()
106 | }
107 | }
108 | }
109 |
110 | let requestFull = {
111 | eventStore.requestFullAccessToEvents { (accessGranted: Bool, error: Error?) in
112 | DispatchQueue.main.async {
113 | completion()
114 | }
115 | }
116 | }
117 |
118 | switch kind {
119 | case .calendar(let access):
120 | if access == .write {
121 | requestWriteOnly()
122 | } else {
123 | requestFull()
124 | }
125 | default:
126 | requestFull()
127 | }
128 | } else {
129 | eventStore.requestAccess(to: EKEntityType.event) { (accessGranted: Bool, error: Error?) in
130 | DispatchQueue.main.async {
131 | completion()
132 | }
133 | }
134 | }
135 | }
136 | }
137 | #endif
138 |
--------------------------------------------------------------------------------
/Sources/CameraPermission/CameraPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_CAMERA
27 | import Foundation
28 | import AVFoundation
29 |
30 | @available(iOS 11.0, macCatalyst 14.0, *)
31 | public extension Permission {
32 |
33 | static var camera: CameraPermission {
34 | return CameraPermission()
35 | }
36 | }
37 |
38 | @available(iOS 11.0, macCatalyst 14.0, *)
39 | public class CameraPermission: Permission {
40 |
41 | open override var kind: Permission.Kind { .camera }
42 | open var usageDescriptionKey: String? { "NSCameraUsageDescription" }
43 |
44 | public override var status: Permission.Status {
45 | switch AVCaptureDevice.authorizationStatus(for: AVMediaType.video) {
46 | case .authorized: return .authorized
47 | case .denied: return .denied
48 | case .notDetermined: return .notDetermined
49 | case .restricted: return .denied
50 | @unknown default: return .denied
51 | }
52 | }
53 |
54 | public override func request(completion: @escaping () -> Void) {
55 | AVCaptureDevice.requestAccess(for: AVMediaType.video, completionHandler: {
56 | finished in
57 | DispatchQueue.main.async {
58 | completion()
59 | }
60 | })
61 | }
62 | }
63 | #endif
64 |
--------------------------------------------------------------------------------
/Sources/ContactsPermission/ContactsPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_CONTACTS
27 | import Foundation
28 | import Contacts
29 |
30 | public extension Permission {
31 |
32 | static var contacts: ContactsPermission {
33 | return ContactsPermission()
34 | }
35 | }
36 |
37 | public class ContactsPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .contacts }
40 | open var usageDescriptionKey: String? { "NSContactsUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | let authorizationStatus = CNContactStore.authorizationStatus(for: .contacts)
44 | if #available(iOS 18.0, *), authorizationStatus == .limited {
45 | return .authorized
46 | }
47 | switch authorizationStatus {
48 | case .authorized: return .authorized
49 | case .denied: return .denied
50 | case .notDetermined: return .notDetermined
51 | case .restricted: return .denied
52 | @unknown default: return .denied
53 | }
54 | }
55 |
56 | public override func request(completion: @escaping () -> Void) {
57 | let store = CNContactStore()
58 | store.requestAccess(for: .contacts, completionHandler: { (granted, error) in
59 | DispatchQueue.main.async {
60 | completion()
61 | }
62 | })
63 | }
64 | }
65 | #endif
66 |
--------------------------------------------------------------------------------
/Sources/FaceIDPermission/FaceIDPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_FACEID
27 | import Foundation
28 | import LocalAuthentication
29 |
30 | public extension Permission {
31 |
32 | static var faceID: FaceIDPermission {
33 | return FaceIDPermission()
34 | }
35 | }
36 |
37 | public class FaceIDPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .faceID }
40 | open var usageDescriptionKey: String? { "NSFaceIDUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | let context = LAContext()
44 |
45 | var error: NSError?
46 | let isReady = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error)
47 |
48 | guard context.biometryType == .faceID else {
49 | return .notSupported
50 | }
51 |
52 | switch error?.code {
53 | case nil where isReady:
54 | return .notDetermined
55 | case LAError.biometryNotAvailable.rawValue:
56 | return .denied
57 | case LAError.biometryNotEnrolled.rawValue:
58 | return .notSupported
59 | default:
60 | return .notSupported
61 | }
62 | }
63 |
64 | public override func request(completion: @escaping () -> Void) {
65 | LAContext().evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: " ") { _, _ in
66 | DispatchQueue.main.async {
67 | completion()
68 | }
69 | }
70 | }
71 | }
72 | #endif
73 |
--------------------------------------------------------------------------------
/Sources/HealthPermission/HealthPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_HEALTH
27 | import Foundation
28 | import HealthKit
29 |
30 | public extension Permission {
31 |
32 | static var health: HealthPermission {
33 | return HealthPermission()
34 | }
35 | }
36 |
37 | public class HealthPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .health }
40 |
41 | open var readingUsageDescriptionKey: String? { "NSHealthUpdateUsageDescription" }
42 | open var writingUsageDescriptionKey: String? { "NSHealthShareUsageDescription" }
43 |
44 | public static func status(for type: HKObjectType) -> Permission.Status {
45 | switch HKHealthStore().authorizationStatus(for: type) {
46 | case .sharingAuthorized: return .authorized
47 | case .sharingDenied: return .denied
48 | case .notDetermined: return .notDetermined
49 | @unknown default: return .denied
50 | }
51 | }
52 |
53 | public static func request(forReading readingTypes: Set, writing writingTypes: Set, completion: @escaping (() -> Void)) {
54 | HKHealthStore().requestAuthorization(toShare: writingTypes, read: readingTypes) { _, _ in
55 | DispatchQueue.main.async {
56 | completion()
57 | }
58 | }
59 | }
60 |
61 | public override var canBePresentWithCustomInterface: Bool { false }
62 |
63 | // MARK: - Locked
64 |
65 | @available(*, unavailable)
66 | open override var authorized: Bool { fatalError() }
67 |
68 | @available(*, unavailable)
69 | open override var denied: Bool { fatalError() }
70 |
71 | @available(*, unavailable)
72 | open override var notDetermined: Bool { fatalError() }
73 |
74 | @available(*, unavailable)
75 | public override var status: Permission.Status { fatalError() }
76 |
77 | @available(*, unavailable)
78 | open override func request(completion: @escaping ()->Void) { fatalError() }
79 | }
80 | #endif
81 |
--------------------------------------------------------------------------------
/Sources/LocationPermission/Handlers/LocationAlwaysHandler.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_LOCATION
27 | import Foundation
28 | import MapKit
29 |
30 | class LocationAlwaysHandler: NSObject, CLLocationManagerDelegate {
31 |
32 | // MARK: - Location Manager
33 |
34 | lazy var locationManager = CLLocationManager()
35 |
36 | func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
37 | if status == .notDetermined {
38 | return
39 | }
40 | completionHandler()
41 | }
42 |
43 | @available(iOS 14.0, *)
44 | func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
45 | if manager.authorizationStatus == .notDetermined {
46 | return
47 | }
48 | completionHandler()
49 | }
50 |
51 | // MARK: - Process
52 |
53 | var completionHandler: () -> Void = {}
54 |
55 | func requestPermission(_ completionHandler: @escaping () -> Void) {
56 | self.completionHandler = completionHandler
57 |
58 | let status = CLLocationManager.authorizationStatus()
59 |
60 | switch status {
61 | case .notDetermined:
62 | locationManager.delegate = self
63 | locationManager.requestAlwaysAuthorization()
64 | case .authorizedWhenInUse:
65 | locationManager.delegate = self
66 | locationManager.requestAlwaysAuthorization()
67 | default:
68 | self.completionHandler()
69 | }
70 | }
71 |
72 | // MARK: - Init
73 |
74 | static var shared: LocationAlwaysHandler?
75 |
76 | override init() {
77 | super.init()
78 | }
79 |
80 | deinit {
81 | locationManager.delegate = nil
82 | }
83 | }
84 | #endif
85 |
--------------------------------------------------------------------------------
/Sources/LocationPermission/Handlers/LocationWhenInUseHandler.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if PERMISSIONSKIT_LOCATION
27 | import Foundation
28 | import MapKit
29 |
30 | class LocationWhenInUseHandler: NSObject, CLLocationManagerDelegate {
31 |
32 | // MARK: - Location Manager
33 |
34 | lazy var locationManager = CLLocationManager()
35 |
36 | #if !os(visionOS)
37 | func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
38 | if status == .notDetermined {
39 | return
40 | }
41 | completionHandler()
42 | }
43 | #endif
44 |
45 |
46 | @available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, visionOS 1.0, *)
47 | func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
48 | if manager.authorizationStatus == .notDetermined {
49 | return
50 | }
51 | completionHandler()
52 | }
53 |
54 | // MARK: - Process
55 |
56 | var completionHandler: () -> Void = {}
57 |
58 | func requestPermission(_ completionHandler: @escaping () -> Void) {
59 | self.completionHandler = completionHandler
60 |
61 | let status: CLAuthorizationStatus = {
62 | #if os(visionOS)
63 | locationManager.authorizationStatus
64 | #elseif os(macOS)
65 | locationManager.authorizationStatus
66 | #else
67 | CLLocationManager.authorizationStatus()
68 | #endif
69 | }()
70 |
71 | switch status {
72 | case .notDetermined:
73 | locationManager.delegate = self
74 | locationManager.requestWhenInUseAuthorization()
75 | case .authorizedWhenInUse:
76 | locationManager.delegate = self
77 | locationManager.requestWhenInUseAuthorization()
78 | default:
79 | self.completionHandler()
80 | }
81 | }
82 |
83 | // MARK: - Init
84 |
85 | static var shared: LocationWhenInUseHandler?
86 |
87 | override init() {
88 | super.init()
89 | }
90 |
91 | deinit {
92 | locationManager.delegate = nil
93 | }
94 | }
95 | #endif
96 |
--------------------------------------------------------------------------------
/Sources/LocationPermission/LocationAccuracy.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | import Foundation
23 | import MapKit
24 |
25 | extension CLLocationManager {
26 |
27 | public func setAccuracy(_ value: LocationAccuracy) {
28 | desiredAccuracy = value.coreLocationAccuracy
29 | }
30 | }
31 |
32 | public enum LocationAccuracy {
33 |
34 | case best
35 | case bestForNavigation
36 | case nearestTenMeters
37 | case hundredMeters
38 | case kilometer
39 | case threeKilometers
40 | case reduced
41 |
42 | var coreLocationAccuracy: CLLocationAccuracy {
43 | switch self {
44 | case .best: return kCLLocationAccuracyBest
45 | case .bestForNavigation: return kCLLocationAccuracyBestForNavigation
46 | case .nearestTenMeters: return kCLLocationAccuracyNearestTenMeters
47 | case .hundredMeters: return kCLLocationAccuracyHundredMeters
48 | case .kilometer: return kCLLocationAccuracyKilometer
49 | case .threeKilometers: return kCLLocationAccuracyThreeKilometers
50 | case .reduced:
51 | if #available(iOS 14.0, tvOS 14.0, watchOS 7.0, *) {
52 | return kCLLocationAccuracyReduced
53 | } else {
54 | return kCLLocationAccuracyThreeKilometers
55 | }
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Sources/LocationPermission/LocationPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_LOCATION
27 | import Foundation
28 | import EventKit
29 |
30 | public extension Permission {
31 |
32 | static func location(access: LocationAccess) -> LocationPermission {
33 | LocationPermission(kind: .location(access: access))
34 | }
35 | }
36 |
37 | public class LocationPermission: Permission {
38 |
39 | private var _kind: Permission.Kind
40 |
41 | // MARK: - Init
42 |
43 | init(kind: Permission.Kind) {
44 | self._kind = kind
45 | }
46 |
47 | open override var kind: Permission.Kind { self._kind }
48 | open var usageDescriptionKey: String? {
49 | switch _kind {
50 | case .location(let access):
51 | switch access {
52 | case .whenInUse:
53 | return "NSLocationWhenInUseUsageDescription"
54 | case .always:
55 | return "NSLocationAlwaysAndWhenInUseUsageDescription"
56 | }
57 | default:
58 | fatalError()
59 | }
60 | }
61 |
62 | public override var status: Permission.Status {
63 | let authorizationStatus: CLAuthorizationStatus = {
64 | let locationManager = CLLocationManager()
65 | if #available(iOS 14.0, tvOS 14.0, *) {
66 | return locationManager.authorizationStatus
67 | } else {
68 | return CLLocationManager.authorizationStatus()
69 | }
70 | }()
71 |
72 | switch authorizationStatus {
73 | #if os(iOS)
74 | case .authorized: return .authorized
75 | #endif
76 | case .denied: return .denied
77 | case .notDetermined: return .notDetermined
78 | case .restricted: return .denied
79 | case .authorizedAlways:
80 | if case .location(let access) = _kind, access == .always {
81 | return .authorized
82 | }
83 | return .denied
84 | case .authorizedWhenInUse:
85 | if case .location(let access) = _kind, access == .whenInUse {
86 | return .authorized
87 | }
88 | return .denied
89 | @unknown default: return .denied
90 | }
91 | }
92 |
93 | public var isPrecise: Bool {
94 | #if os(iOS)
95 | if #available(iOS 14.0, *) {
96 | switch CLLocationManager().accuracyAuthorization {
97 | case .fullAccuracy: return true
98 | case .reducedAccuracy: return false
99 | @unknown default: return false
100 | }
101 | }
102 | #endif
103 | return false
104 | }
105 |
106 | public override func request(completion: @escaping () -> Void) {
107 | switch _kind {
108 | case .location(let access):
109 | switch access {
110 | case .whenInUse:
111 | LocationWhenInUseHandler.shared = LocationWhenInUseHandler()
112 | LocationWhenInUseHandler.shared?.requestPermission() {
113 | DispatchQueue.main.async {
114 | completion()
115 | LocationWhenInUseHandler.shared = nil
116 | }
117 | }
118 | case .always:
119 | LocationAlwaysHandler.shared = LocationAlwaysHandler()
120 | LocationAlwaysHandler.shared?.requestPermission() {
121 | DispatchQueue.main.async {
122 | completion()
123 | LocationAlwaysHandler.shared = nil
124 | }
125 | }
126 | }
127 | default:
128 | fatalError()
129 | }
130 | }
131 | }
132 | #endif
133 |
--------------------------------------------------------------------------------
/Sources/MediaLibraryPermission/MediaLibraryPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_MEDIA_LIBRARY
27 | import Foundation
28 | import MediaPlayer
29 |
30 | public extension Permission {
31 |
32 | static var mediaLibrary: MediaLibraryPermission {
33 | return MediaLibraryPermission()
34 | }
35 | }
36 |
37 | public class MediaLibraryPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .mediaLibrary }
40 | open var usageDescriptionKey: String? { "NSAppleMusicUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | switch MPMediaLibrary.authorizationStatus() {
44 | case .authorized: return .authorized
45 | case .denied: return .denied
46 | case .notDetermined: return .notDetermined
47 | case .restricted: return .denied
48 | @unknown default: return .denied
49 | }
50 | }
51 |
52 | public override func request(completion: @escaping () -> Void) {
53 | MPMediaLibrary.requestAuthorization() { status in
54 | DispatchQueue.main.async {
55 | completion()
56 | }
57 | }
58 | }
59 | }
60 | #endif
61 |
--------------------------------------------------------------------------------
/Sources/MicrophonePermission/MicrophonePermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if (os(iOS) || os(macOS)) && PERMISSIONSKIT_MICROPHONE
27 | import Foundation
28 | import AVFoundation
29 |
30 | public extension Permission {
31 |
32 | static var microphone: MicrophonePermission {
33 | return MicrophonePermission()
34 | }
35 | }
36 |
37 | public class MicrophonePermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .microphone }
40 | open var usageDescriptionKey: String? { "NSMicrophoneUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | #if os(iOS)
44 | switch AVAudioSession.sharedInstance().recordPermission {
45 | case .granted: return .authorized
46 | case .denied: return .denied
47 | case .undetermined: return .notDetermined
48 | @unknown default: return .denied
49 | }
50 | #elseif os(macOS)
51 | switch AVCaptureDevice.authorizationStatus(for: .audio) {
52 | case .denied: return .denied
53 | case .notDetermined: return .notDetermined
54 | case .restricted: return .denied
55 | case .authorized: return .authorized
56 | @unknown default: return .denied
57 | }
58 | #endif
59 | }
60 |
61 | public override func request(completion: @escaping () -> Void) {
62 | #if os(iOS)
63 | AVAudioSession.sharedInstance().requestRecordPermission {
64 | granted in
65 | DispatchQueue.main.async {
66 | completion()
67 | }
68 | }
69 | #elseif os(macOS)
70 | AVCaptureDevice.requestAccess(for: .audio) { _ in
71 | DispatchQueue.main.async {
72 | completion()
73 | }
74 | }
75 | #endif
76 | }
77 | }
78 | #endif
79 |
--------------------------------------------------------------------------------
/Sources/MotionPermission/MotionPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_MOTION
27 | import Foundation
28 | import CoreMotion
29 |
30 | public extension Permission {
31 |
32 | static var motion: MotionPermission {
33 | return MotionPermission()
34 | }
35 | }
36 |
37 | public class MotionPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .motion }
40 | open var usageDescriptionKey: String? { "NSMotionUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | switch CMMotionActivityManager.authorizationStatus() {
44 | case .authorized: return .authorized
45 | case .denied: return .denied
46 | case .notDetermined: return .notDetermined
47 | case .restricted: return .denied
48 | @unknown default: return .denied
49 | }
50 | }
51 |
52 | public override func request(completion: @escaping () -> Void) {
53 | let manager = CMMotionActivityManager()
54 | let today = Date()
55 |
56 | manager.queryActivityStarting(from: today, to: today, to: OperationQueue.main, withHandler: { (activities: [CMMotionActivity]?, error: Error?) -> () in
57 | completion()
58 | manager.stopActivityUpdates()
59 | })
60 | }
61 | }
62 | #endif
63 |
--------------------------------------------------------------------------------
/Sources/NotificationPermission/NotificationAccess+userNotifcationAuthorizationOptions.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | import PermissionsKit
23 | import UserNotifications
24 |
25 | extension Permission.NotificationAccess {
26 |
27 | var userNotifcationAuthorizationOptions: UNAuthorizationOptions {
28 | switch self {
29 | case .badge:
30 | .badge
31 | case .sound:
32 | .sound
33 | case .alert:
34 | .alert
35 | case .carPlay:
36 | .carPlay
37 | case .criticalAlert:
38 | .criticalAlert
39 | case .providesAppNotificationSettings:
40 | .providesAppNotificationSettings
41 | case .provisional:
42 | .provisional
43 | case .announcement:
44 | if #available(iOS 13.0, watchOS 6.0, *) {
45 | .announcement
46 | } else {
47 | .alert
48 | }
49 | case .timeSensitive:
50 | if #available(iOS 15.0, tvOS 15.0, watchOS 8.0, *) {
51 | .timeSensitive
52 | } else {
53 | .alert
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Sources/NotificationPermission/NotificationPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if PERMISSIONSKIT_NOTIFICATION
27 | import UserNotifications
28 |
29 | public extension Permission {
30 |
31 | static func notification(_ access: Set = [.alert, .badge, .sound]) -> NotificationPermission {
32 | return NotificationPermission(kind: .notification(access: access))
33 | }
34 | }
35 |
36 | public class NotificationPermission: Permission {
37 |
38 | private var _kind: Permission.Kind
39 | open override var kind: Permission.Kind { self._kind }
40 |
41 | init(kind: Permission.Kind) {
42 | self._kind = kind
43 | }
44 |
45 | public override var status: Permission.Status {
46 | guard let authorizationStatus = fetchAuthorizationStatus() else { return .notDetermined }
47 | switch authorizationStatus {
48 | case .authorized: return .authorized
49 | case .denied: return .denied
50 | case .notDetermined: return .notDetermined
51 | case .provisional: return .authorized
52 | case .ephemeral: return .authorized
53 | @unknown default: return .denied
54 | }
55 | }
56 |
57 | private func fetchAuthorizationStatus() -> UNAuthorizationStatus? {
58 | var notificationSettings: UNNotificationSettings?
59 | let semaphore = DispatchSemaphore(value: 0)
60 | DispatchQueue.global().async {
61 | UNUserNotificationCenter.current().getNotificationSettings { setttings in
62 | notificationSettings = setttings
63 | semaphore.signal()
64 | }
65 | }
66 | semaphore.wait()
67 | return notificationSettings?.authorizationStatus
68 | }
69 |
70 | public override func request(completion: @escaping () -> Void) {
71 | let center = UNUserNotificationCenter.current()
72 | switch _kind {
73 | case .notification(let access):
74 | center.requestAuthorization(options: UNAuthorizationOptions(access.map { $0.userNotifcationAuthorizationOptions })) { (granted, error) in
75 | DispatchQueue.main.async {
76 | completion()
77 | }
78 | }
79 | default:
80 | fatalError()
81 | }
82 | }
83 | }
84 | #endif
85 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Data/Text.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | import Foundation
23 |
24 | enum Texts {
25 |
26 | static func permission_name(for kind: Permission.Kind) -> String {
27 | switch kind {
28 | case .camera:
29 | return NSLocalizedString("permission camera name", bundle: bundle, comment: "")
30 | case .photoLibrary:
31 | return NSLocalizedString("permission photoLibrary name", bundle: bundle, comment: "")
32 | case .microphone:
33 | return NSLocalizedString("permission microphone name", bundle: bundle, comment: "")
34 | case .calendar(access: .full), .calendar(access: .write):
35 | return NSLocalizedString("permission calendar name", bundle: bundle, comment: "")
36 | case .contacts:
37 | return NSLocalizedString("permission contacts name", bundle: bundle, comment: "")
38 | case .reminders:
39 | return NSLocalizedString("permission reminders name", bundle: bundle, comment: "")
40 | case .speech:
41 | return NSLocalizedString("permission speech name", bundle: bundle, comment: "")
42 | case .motion:
43 | return NSLocalizedString("permission motion name", bundle: bundle, comment: "")
44 | case .mediaLibrary:
45 | return NSLocalizedString("permission media library name", bundle: bundle, comment: "")
46 | case .bluetooth:
47 | return NSLocalizedString("permission bluetooth name", bundle: bundle, comment: "")
48 | case .notification:
49 | return NSLocalizedString("permission notification name", bundle: bundle, comment: "")
50 | case .location(access: .whenInUse):
51 | return NSLocalizedString("permission location when in use name", bundle: bundle, comment: "")
52 | case .location(access: .always):
53 | return NSLocalizedString("permission location always name", bundle: bundle, comment: "")
54 | case .tracking:
55 | return NSLocalizedString("permission tracking name", bundle: bundle, comment: "")
56 | case .faceID:
57 | return NSLocalizedString("permission faceid name", bundle: bundle, comment: "")
58 | case .siri:
59 | return NSLocalizedString("permission siri name", bundle: bundle, comment: "")
60 | case .health:
61 | return NSLocalizedString("permission health name", bundle: bundle, comment: "")
62 | }
63 | }
64 |
65 | // MARK: - Internal
66 |
67 | static var bundle: Bundle {
68 |
69 | // If installed via SPM, will be available bundle .module.
70 |
71 | #if PERMISSIONSKIT_SPM
72 | return .module
73 | #else
74 |
75 | // If installed via Cocoapods, should use bundle from podspec.
76 |
77 | let path = Bundle(for: Permission.self).path(forResource: "PermissionsKit", ofType: "bundle") ?? ""
78 | let bundle = Bundle(path: path) ?? Bundle.main
79 | return bundle
80 | #endif
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Permission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | import Foundation
23 |
24 | #if os(iOS)
25 | import UIKit
26 | #endif
27 |
28 | open class Permission {
29 |
30 | open var authorized: Bool {
31 | return status == .authorized
32 | }
33 |
34 | open var denied: Bool {
35 | return status == .denied
36 | }
37 |
38 | open var notDetermined: Bool {
39 | return status == .notDetermined
40 | }
41 |
42 | open var debugName: String {
43 | return kind.name
44 | }
45 |
46 | open var localisedName: String {
47 | return Texts.permission_name(for: kind)
48 | }
49 |
50 | /**
51 | PermissionsKit: Open settings page.
52 | For most permissions its app page in settings app.
53 | You can overide it if your permission need open custom page.
54 | */
55 | #if os(iOS)
56 | @available(iOSApplicationExtension, unavailable)
57 | open func openSettingPage() {
58 | DispatchQueue.main.async {
59 | guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
60 | if UIApplication.shared.canOpenURL(settingsUrl) {
61 | UIApplication.shared.open(settingsUrl, completionHandler: nil)
62 | }
63 | }
64 | }
65 | #endif
66 |
67 | // MARK: Must Ovveride
68 |
69 | open var kind: Permission.Kind {
70 | preconditionFailure("This method must be overridden.")
71 | }
72 |
73 | open var status: Permission.Status {
74 | preconditionFailure("This method must be overridden.")
75 | }
76 |
77 | open func request(completion: @escaping ()->Void) {
78 | preconditionFailure("This method must be overridden.")
79 | }
80 |
81 | open var canBePresentWithCustomInterface: Bool {
82 | return true
83 | }
84 |
85 | // MARK: Internal
86 |
87 | public init() {}
88 |
89 | // MARK: - Models
90 |
91 | @objc public enum Status: Int, CustomStringConvertible {
92 |
93 | case authorized
94 | case denied
95 | case notDetermined
96 | case notSupported
97 |
98 | public var description: String {
99 | switch self {
100 | case .authorized: return "authorized"
101 | case .denied: return "denied"
102 | case .notDetermined: return "not determined"
103 | case .notSupported: return "not supported"
104 | }
105 | }
106 | }
107 |
108 | public enum Kind {
109 |
110 | case camera
111 | case notification(access: Set)
112 | case photoLibrary
113 | case microphone
114 | case calendar(access: CalendarAccess)
115 | case contacts
116 | case reminders
117 | case speech
118 | case location(access: LocationAccess)
119 | case motion
120 | case mediaLibrary
121 | case bluetooth
122 | case tracking
123 | case faceID
124 | case siri
125 | case health
126 |
127 | public var name: String {
128 | switch self {
129 | case .camera:
130 | return "Camera"
131 | case .photoLibrary:
132 | return "Photo Library"
133 | case .microphone:
134 | return "Microphone"
135 | case .calendar(access: .write):
136 | return "Calendar Only Write"
137 | case .calendar(access: .full):
138 | return "Calendar"
139 | case .contacts:
140 | return "Contacts"
141 | case .reminders:
142 | return "Reminders"
143 | case .speech:
144 | return "Speech"
145 | case .location(access: .always):
146 | return "Location Always"
147 | case .location(access: .whenInUse):
148 | return "Location When Use"
149 | case .motion:
150 | return "Motion"
151 | case .mediaLibrary:
152 | return "Media Library"
153 | case .bluetooth:
154 | return "Bluetooth"
155 | case .notification:
156 | return "Notification"
157 | case .tracking:
158 | return "Tracking"
159 | case .faceID:
160 | return "FaceID"
161 | case .siri:
162 | return "Siri"
163 | case .health:
164 | return "Health"
165 | }
166 | }
167 | }
168 |
169 | public enum CalendarAccess {
170 |
171 | case full
172 | case write
173 | }
174 |
175 | public enum LocationAccess {
176 |
177 | case whenInUse
178 | case always
179 | }
180 |
181 | public enum NotificationAccess {
182 |
183 | case badge
184 | case sound
185 | case alert
186 | case carPlay
187 | case criticalAlert
188 | case providesAppNotificationSettings
189 | case provisional
190 |
191 | @available(iOS, introduced: 13.0, deprecated: 15.0, message: "Only from iOS 13.0 to 15.0")
192 | case announcement
193 | @available(iOS, introduced: 15.0, deprecated: 15.0, message: "Only with iOS 15.0")
194 | case timeSensitive
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/ar.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "الكاميرا";
2 |
3 | "permission photoLibrary name" = "الاستوديو";
4 |
5 | "permission microphone name" = "المايكروفون";
6 |
7 | "permission calendar name" = "التقويم";
8 |
9 | "permission contacts name" = "جهات الاتصال";
10 |
11 | "permission reminders name" = "التذكيرات";
12 |
13 | "permission speech name" = "التحدث";=
14 |
15 | "permission motion name" = "الحركة";
16 |
17 | "permission media library name" = "الموسيقى";
18 |
19 | "permission bluetooth name" = "البلوتوث";
20 |
21 | "permission notification name" = "الإشعارات";
22 |
23 | "permission location when in use name" = "الموقع عند الاستخدام";
24 |
25 | "permission location always name" = "الموقع دائما";
26 |
27 | "permission tracking name" = "تتبع";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "سيري";
32 |
33 | "permission health name" = "الصحة";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/de.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 |
2 | "action allow" = "Erlauben";
3 |
4 | "action allowed" = "Berechtigt";
5 |
6 | "titles header" = "Geben Sie die Erlaubnis";
7 |
8 | "titles sub header" = "Berechtigungsanfrage";
9 |
10 | "titles description" = "Dies sind die Berechtigungen, die die App benötigt, um korrekt zu funktionieren. Bitte lesen Sie die Beschreibung für jede Berechtigung.";
11 |
12 | "titles comment" = "Berechtigungen sind notwendig, damit die Anwendung funktioniert und korrekt arbeitet.";
13 |
14 | "permission camera name" = "Kamera";
15 |
16 | "permission camera description" = "Zugriff auf die Kamera gewähren";
17 |
18 | "permission photoLibrary name" = "Foto-Bibliothek";
19 |
20 | "permission microphone name" = "Mikrofon";
21 |
22 | "permission calendar name" = "Kalender";
23 |
24 | "permission contacts name" = "Kontakte";
25 |
26 | "permission contacts description" = "Zugriff für Ihre Kontakte und Telefone";
27 |
28 | "permission reminders name" = "Erinnerungen";
29 |
30 | "permission speech name" = "Sprechen";
31 |
32 | "permission motion name" = "Bewegung";
33 |
34 | "permission media library name" = "Medienbibliothek";
35 |
36 | "permission bluetooth name" = "Bluetooth";
37 |
38 | "permission notification name" = "Benachrichtigung";
39 |
40 | "permission location when in use name" = "Standort bei Verwendung";
41 |
42 | "permission location always name" = "Standort Immer";
43 |
44 | "permission tracking name" = "Nachverfolgung";
45 |
46 | "permission faceid name" = "FaceID";
47 |
48 | "permission faceid description" = "Erlauben Sie die Verwendung von FaceID";
49 |
50 | "permission siri name" = "Siri";
51 |
52 | "permission health name" = "Gesundheit";
53 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Camera";
2 |
3 | "permission photoLibrary name" = "Photo Library";
4 |
5 | "permission microphone name" = "Microphone";
6 |
7 | "permission calendar name" = "Calendar";
8 |
9 | "permission contacts name" = "Contacts";
10 |
11 | "permission reminders name" = "Reminders";
12 |
13 | "permission speech name" = "Speech";
14 |
15 | "permission motion name" = "Motion";
16 |
17 | "permission media library name" = "Media Library";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notification";
22 |
23 | "permission location when in use name" = "Location When Use";
24 |
25 | "permission location always name" = "Location Always";
26 |
27 | "permission tracking name" = "Tracking";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Health";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/es.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Cámara";
2 |
3 | "permission photoLibrary name" = "Fotos";
4 |
5 | "permission microphone name" = "Micrófono";
6 |
7 | "permission calendar name" = "Calendario";
8 |
9 | "permission contacts name" = "Contactos";
10 |
11 | "permission reminders name" = "Recordatorios";
12 |
13 | "permission speech name" = "Discurso";
14 |
15 | "permission motion name" = "Movimiento";
16 |
17 | "permission media library name" = "Contenidos y Apple music";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notificaciones";
22 |
23 | "permission location when in use name" = "Al usar la app";
24 |
25 | "permission location always name" = "Siempre";
26 |
27 | "permission tracking name" = "Rastreo";
28 |
29 | "permission faceid name" = "Face ID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Salud";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/fa.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "دوربین";
2 |
3 | "permission photoLibrary name" = "گالری";
4 |
5 | "permission microphone name" = "میکروفون";
6 |
7 | "permission calendar name" = "تقویم";
8 |
9 | "permission contacts name" = "مخاطبین";
10 |
11 | "permission reminders name" = "یادآوری ها";
12 |
13 | "permission speech name" = "گفتار";
14 |
15 | "permission motion name" = "حرکت";
16 |
17 | "permission media library name" = "مدیا";
18 |
19 | "permission bluetooth name" = "بلوتوث";
20 |
21 | "permission notification name" = "اعلانات";
22 |
23 | "permission location when in use name" = "موقعیت مکانی هنگام استفاده";
24 |
25 | "permission location always name" = "موقعیت مکانی همیشه";
26 |
27 | "permission tracking name" = "ردیابی";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "سیری";
32 |
33 | "permission health name" = "سلامت";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/fr.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Caméra";
2 |
3 | "permission photoLibrary name" = "Photothèque";
4 |
5 | "permission microphone name" = "Microphone";
6 |
7 | "permission calendar name" = "Calendrier";
8 |
9 | "permission contacts name" = "Contacts";
10 |
11 | "permission reminders name" = "Rappels";
12 |
13 | "permission speech name" = "Voix";
14 |
15 | "permission motion name" = "Mouvement";
16 |
17 | "permission media library name" = "Médiathèque";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notification";
22 |
23 | "permission location when in use name" = "Localisation lors de l'utilisation";
24 |
25 | "permission location always name" = "Localisation Toujours";
26 |
27 | "permission tracking name" = "Suivi du site";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Santé";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/it.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Camera";
2 |
3 | "permission photoLibrary name" = "Photo Library";
4 |
5 | "permission microphone name" = "Microphone";
6 |
7 | "permission calendar name" = "Calendar";
8 |
9 | "permission contacts name" = "Contacts";
10 |
11 | "permission reminders name" = "Reminders";
12 |
13 | "permission speech name" = "Speech";
14 |
15 | "permission motion name" = "Motion";
16 |
17 | "permission media library name" = "Media Library";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notification";
22 |
23 | "permission location when in use name" = "Location When Use";
24 |
25 | "permission location always name" = "Posizione sempre";
26 |
27 | "permission tracking name" = "Tracking";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Salute";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/nl.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Camera";
2 |
3 | "permission photoLibrary name" = "Foto Bibliotheek";
4 |
5 | "permission microphone name" = "Microfoon";
6 |
7 | "permission calendar name" = "Kalender";
8 |
9 | "permission contacts name" = "Contacten";
10 |
11 | "permission reminders name" = "Herinneringen";
12 |
13 | "permission speech name" = "Spraak";
14 |
15 | "permission motion name" = "Beweging";
16 |
17 | "permission media library name" = "Media Bibliotheek";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notificatie";
22 |
23 | "permission location when in use name" = "Locatie tijdens gebruik";
24 |
25 | "permission location always name" = "Locatie Altijd";
26 |
27 | "permission tracking name" = "Volgen";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Gezondheid";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/pl.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Kamera";
2 |
3 | "permission photoLibrary name" = "Biblioteka zdjęć";
4 |
5 | "permission microphone name" = "Mikrofon";
6 |
7 | "permission calendar name" = "Kalendarz";
8 |
9 | "permission contacts name" = "Kontakty";
10 |
11 | "permission reminders name" = "Przypomnienia";
12 |
13 | "permission speech name" = "Mowa";
14 |
15 | "permission motion name" = "Motion";
16 |
17 | "permission media library name" = "Biblioteka mediów";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Powiadomienia";
22 |
23 | "permission location when in use name" = "Lokalizacja podczas używania";
24 |
25 | "permission location always name" = "Lokalizacja zawsze";
26 |
27 | "permission tracking name" = "Śledzenie";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Zdrowie";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/pt.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Câmara";
2 |
3 | "permission photoLibrary name" = "Biblioteca de fotos";
4 |
5 | "permission microphone name" = "Microfone";
6 |
7 | "permission calendar name" = "Calendário";
8 |
9 | "permission contacts name" = "Contactos";
10 |
11 | "permission reminders name" = "Lembretes";
12 |
13 | "permission speech name" = "Discurso";
14 |
15 | "permission motion name" = "Moção";
16 |
17 | "permission media library name" = "Mediateca";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Notificação";
22 |
23 | "permission location when in use name" = "Localização Quando Usar";
24 |
25 | "permission location always name" = "Localização Sempre";
26 |
27 | "permission tracking name" = "Rastreamento";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Saúde";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/ru.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Камера";
2 |
3 | "permission photoLibrary name" = "Галерея";
4 |
5 | "permission microphone name" = "Микрофон";
6 |
7 | "permission calendar name" = "Календарь";
8 |
9 | "permission contacts name" = "Контакты";
10 |
11 | "permission reminders name" = "Напоминания";
12 |
13 | "permission speech name" = "Распознавание Речи";
14 |
15 | "permission motion name" = "Движение";
16 |
17 | "permission media library name" = "Медиа библиотека";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Уведомления";
22 |
23 | "permission location when in use name" = "Локация, когда открыто приложение";
24 |
25 | "permission location always name" = "Локация";
26 |
27 | "permission tracking name" = "Отслеживание";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Здоровье";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/uk.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "Камера";
2 |
3 | "permission photoLibrary name" = "Фототека";
4 |
5 | "permission microphone name" = "Мікрофон";
6 |
7 | "permission calendar name" = "Календар";
8 |
9 | "permission contacts name" = "Контакти";
10 |
11 | "permission reminders name" = "Нагадування";
12 |
13 | "permission speech name" = "Мовлення";
14 |
15 | "permission motion name" = "Рух";
16 |
17 | "permission media library name" = "Медіатека";
18 |
19 | "permission bluetooth name" = "Bluetooth";
20 |
21 | "permission notification name" = "Повідомлення";
22 |
23 | "permission location when in use name" = "Розташування під час використання";
24 |
25 | "permission location always name" = "Розташування Завжди";
26 |
27 | "permission tracking name" = "Відстеження";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "Здоров'я";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/zh-Hant.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "相機";
2 |
3 | "permission photoLibrary name" = "相簿";
4 |
5 | "permission microphone name" = "麥克風";
6 |
7 | "permission calendar name" = "日曆";
8 |
9 | "permission contacts name" = "通訊錄";
10 |
11 | "permission reminders name" = "提醒事項";
12 |
13 | "permission speech name" = "語音辨識";
14 |
15 | "permission motion name" = "運動";
16 |
17 | "permission media library name" = "媒體櫃";
18 |
19 | "permission bluetooth name" = "藍芽";
20 |
21 | "permission notification name" = "推播通知";
22 |
23 | "permission location when in use name" = "在使用 App 期間取用位置";
24 |
25 | "permission location always name" = "總是取用位置";
26 |
27 | "permission tracking name" = "追蹤";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "健康";
34 |
--------------------------------------------------------------------------------
/Sources/PermissionsKit/Resources/Localization/zh_Hans.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | "permission camera name" = "相机";
2 |
3 | "permission photoLibrary name" = "照片图库";
4 |
5 | "permission microphone name" = "麦克风";
6 |
7 | "permission calendar name" = "日历";
8 |
9 | "permission contacts name" = "通讯录";
10 |
11 | "permission reminders name" = "提醒事项";
12 |
13 | "permission speech name" = "语音识别";
14 |
15 | "permission motion name" = "运动";
16 |
17 | "permission media library name" = "媒体";
18 |
19 | "permission bluetooth name" = "蓝牙";
20 |
21 | "permission notification name" = "通知";
22 |
23 | "permission location when in use name" = "使用 App 期间访问位置";
24 |
25 | "permission location always name" = "始终访问位置";
26 |
27 | "permission tracking name" = "跟踪";
28 |
29 | "permission faceid name" = "FaceID";
30 |
31 | "permission siri name" = "Siri";
32 |
33 | "permission health name" = "健康";
34 |
--------------------------------------------------------------------------------
/Sources/PhotoLibraryPermission/PhotoLibraryPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if PERMISSIONSKIT_PHOTOLIBRARY
27 | import Photos
28 |
29 | public extension Permission {
30 |
31 | static var photoLibrary: PhotoLibraryPermission {
32 | return PhotoLibraryPermission()
33 | }
34 | }
35 |
36 | public class PhotoLibraryPermission: Permission {
37 |
38 | open override var kind: Permission.Kind { .photoLibrary }
39 |
40 | open var fullAccessUsageDescriptionKey: String? {
41 | "NSPhotoLibraryUsageDescription"
42 | }
43 |
44 | open var addingOnlyUsageDescriptionKey: String? {
45 | "NSPhotoLibraryAddUsageDescription"
46 | }
47 |
48 | public override var status: Permission.Status {
49 | switch PHPhotoLibrary.authorizationStatus() {
50 | case .authorized: return .authorized
51 | case .denied: return .denied
52 | case .notDetermined: return .notDetermined
53 | case .restricted: return .denied
54 | case .limited: return .authorized
55 | @unknown default: return .denied
56 | }
57 | }
58 |
59 | public override func request(completion: @escaping () -> Void) {
60 | PHPhotoLibrary.requestAuthorization({
61 | finished in
62 | DispatchQueue.main.async {
63 | completion()
64 | }
65 | })
66 | }
67 | }
68 | #endif
69 |
70 |
--------------------------------------------------------------------------------
/Sources/RemindersPermission/RemindersPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_REMINDERS
27 | import Foundation
28 | import EventKit
29 |
30 | public extension Permission {
31 |
32 | static var reminders: RemindersPermission {
33 | return RemindersPermission()
34 | }
35 | }
36 |
37 | public class RemindersPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .reminders }
40 | open var usageDescriptionKey: String? { "NSRemindersUsageDescription" }
41 | open var usageFullAccessDescriptionKey: String? { "NSRemindersFullAccessUsageDescription" }
42 |
43 | public override var status: Permission.Status {
44 | switch EKEventStore.authorizationStatus(for: EKEntityType.reminder) {
45 | case .authorized: return .authorized
46 | case .denied: return .denied
47 | case .fullAccess: return .authorized
48 | case .notDetermined: return .notDetermined
49 | case .restricted: return .denied
50 | case .writeOnly: return .authorized
51 | @unknown default: return .denied
52 | }
53 | }
54 |
55 | public override func request(completion: @escaping () -> Void) {
56 |
57 | let eventStore = EKEventStore()
58 |
59 | if #available(iOS 17.0, *) {
60 | eventStore.requestFullAccessToReminders { (accessGranted: Bool, error: Error?) in
61 | DispatchQueue.main.async {
62 | completion()
63 | }
64 | }
65 | } else {
66 | eventStore.requestAccess(to: EKEntityType.reminder) { (accessGranted: Bool, error: Error?) in
67 | DispatchQueue.main.async {
68 | completion()
69 | }
70 | }
71 | }
72 | }
73 | }
74 | #endif
75 |
--------------------------------------------------------------------------------
/Sources/SiriPermission/SiriPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if os(iOS) && PERMISSIONSKIT_SIRI
27 | import Foundation
28 | import Intents
29 |
30 | public extension Permission {
31 |
32 | static var siri: SiriPermission {
33 | return SiriPermission()
34 | }
35 | }
36 |
37 | public class SiriPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .siri }
40 | open var usageDescriptionKey: String? { "NSSiriUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | switch INPreferences.siriAuthorizationStatus() {
44 | case .authorized: return .authorized
45 | case .denied: return .denied
46 | case .notDetermined: return .notDetermined
47 | case .restricted: return .denied
48 | @unknown default: return .denied
49 | }
50 | }
51 |
52 | public override func request(completion: @escaping () -> Void) {
53 | INPreferences.requestSiriAuthorization { _ in
54 | DispatchQueue.main.async {
55 | completion()
56 | }
57 | }
58 | }
59 | }
60 | #endif
61 |
--------------------------------------------------------------------------------
/Sources/SpeechRecognizerPermission/SpeechPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if (os(iOS) || os(macOS)) && PERMISSIONSKIT_SPEECH
27 | import Foundation
28 | import Speech
29 |
30 | public extension Permission {
31 |
32 | static var speech: SpeechPermission {
33 | return SpeechPermission()
34 | }
35 | }
36 |
37 | public class SpeechPermission: Permission {
38 |
39 | open override var kind: Permission.Kind { .speech }
40 | open var usageDescriptionKey: String? { "NSSpeechRecognitionUsageDescription" }
41 |
42 | public override var status: Permission.Status {
43 | switch SFSpeechRecognizer.authorizationStatus() {
44 | case .authorized: return .authorized
45 | case .denied: return .denied
46 | case .notDetermined: return .notDetermined
47 | case .restricted: return .denied
48 | @unknown default: return .denied
49 | }
50 | }
51 |
52 | public override func request(completion: @escaping () -> Void) {
53 | SFSpeechRecognizer.requestAuthorization { status in
54 | DispatchQueue.main.async {
55 | completion()
56 | }
57 | }
58 | }
59 | }
60 | #endif
61 |
--------------------------------------------------------------------------------
/Sources/TrackingPermission/TrackingPermission.swift:
--------------------------------------------------------------------------------
1 | // The MIT License (MIT)
2 | // Copyright © 2022 Sparrow Code LTD (https://sparrowcode.io, hello@sparrowcode.io)
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in all
12 | // copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | // SOFTWARE.
21 |
22 | #if PERMISSIONSKIT_SPM
23 | import PermissionsKit
24 | #endif
25 |
26 | #if PERMISSIONSKIT_TRACKING
27 | import AppTrackingTransparency
28 |
29 | @available(iOS 14, tvOS 14, *)
30 | public extension Permission {
31 |
32 | static var tracking: TrackingPermission {
33 | return TrackingPermission()
34 | }
35 | }
36 |
37 | @available(iOS 14, tvOS 14, *)
38 | public class TrackingPermission: Permission {
39 |
40 | open override var kind: Permission.Kind { .tracking }
41 | open var usageDescriptionKey: String? { "NSUserTrackingUsageDescription" }
42 |
43 | public override var status: Permission.Status {
44 | switch ATTrackingManager.trackingAuthorizationStatus {
45 | case .authorized: return .authorized
46 | case .denied: return .denied
47 | case .notDetermined: return .notDetermined
48 | case .restricted : return .denied
49 | @unknown default: return .denied
50 | }
51 | }
52 |
53 | public override func request(completion: @escaping () -> Void) {
54 | ATTrackingManager.requestTrackingAuthorization { _ in
55 | DispatchQueue.main.async {
56 | completion()
57 | }
58 | }
59 | }
60 | }
61 | #endif
62 |
--------------------------------------------------------------------------------