├── KPermission
├── Icons
│ ├── close.png
│ ├── Camera.png
│ ├── Motion.png
│ ├── Speech.png
│ ├── Calander.png
│ ├── Contacts.png
│ ├── Location.png
│ ├── Microphone.png
│ ├── Reminder.png
│ ├── Notification.png
│ ├── Media Library.png
│ └── Photo Library.png
├── Sources
│ ├── Permissions
│ │ ├── CameraPermission.swift
│ │ ├── MicPermission.swift
│ │ ├── ContactsPermission.swift
│ │ ├── PhotoLibPermission.swift
│ │ ├── MediaLibPermission.swift
│ │ ├── SpeechPermission.swift
│ │ ├── CalendarPermission.swift
│ │ ├── MotionPermission.swift
│ │ ├── NotificationPermission.swift
│ │ └── LocationPermission.swift
│ ├── KPermission.swift
│ ├── KPermissionTableCell.swift
│ ├── KPermissionTableView.swift
│ └── KPermissionView.swift
├── KPermission.h
├── Info.plist
└── View
│ └── KPermissionListView.xib
├── KPermission.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ ├── kenan.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ └── kenanatmaca.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── xcuserdata
│ ├── kenan.xcuserdatad
│ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── kenanatmaca.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── KPermission.podspec
├── LICENSE
└── README.md
/KPermission/Icons/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/close.png
--------------------------------------------------------------------------------
/KPermission/Icons/Camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Camera.png
--------------------------------------------------------------------------------
/KPermission/Icons/Motion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Motion.png
--------------------------------------------------------------------------------
/KPermission/Icons/Speech.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Speech.png
--------------------------------------------------------------------------------
/KPermission/Icons/Calander.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Calander.png
--------------------------------------------------------------------------------
/KPermission/Icons/Contacts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Contacts.png
--------------------------------------------------------------------------------
/KPermission/Icons/Location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Location.png
--------------------------------------------------------------------------------
/KPermission/Icons/Microphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Microphone.png
--------------------------------------------------------------------------------
/KPermission/Icons/Reminder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Reminder.png
--------------------------------------------------------------------------------
/KPermission/Icons/Notification.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Notification.png
--------------------------------------------------------------------------------
/KPermission/Icons/Media Library.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Media Library.png
--------------------------------------------------------------------------------
/KPermission/Icons/Photo Library.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission/Icons/Photo Library.png
--------------------------------------------------------------------------------
/KPermission.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/KPermission.xcodeproj/project.xcworkspace/xcuserdata/kenan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission.xcodeproj/project.xcworkspace/xcuserdata/kenan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/KPermission.xcodeproj/project.xcworkspace/xcuserdata/kenanatmaca.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KenanAtmaca/KPermission/HEAD/KPermission.xcodeproj/project.xcworkspace/xcuserdata/kenanatmaca.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/KPermission.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/KPermission.xcodeproj/xcuserdata/kenan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | KPermission.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/KPermission.xcodeproj/xcuserdata/kenanatmaca.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | KPermission.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/CameraPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import AVFoundation
8 |
9 | class CameraPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | AVCaptureDevice.requestAccess(for: .video) { (result) in
13 | success(result)
14 | }
15 | }
16 |
17 | var isAuth: Bool {
18 | return AVCaptureDevice.authorizationStatus(for: .video) == .authorized
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/MicPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import AVFoundation
8 |
9 | class MicPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | AVAudioSession.sharedInstance().requestRecordPermission { (result) in
13 | success(result)
14 | }
15 | }
16 |
17 | var isAuth: Bool {
18 | return AVAudioSession.sharedInstance().recordPermission == .granted
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/KPermission/KPermission.h:
--------------------------------------------------------------------------------
1 | //
2 | // KPermission.h
3 | // KPermission
4 | //
5 | // Created by Kenan Atmaca on 9.08.2019.
6 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for KPermission.
12 | FOUNDATION_EXPORT double KPermissionVersionNumber;
13 |
14 | //! Project version string for KPermission.
15 | FOUNDATION_EXPORT const unsigned char KPermissionVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/ContactsPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import Contacts
8 |
9 | class ContactsPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | CNContactStore().requestAccess(for: .contacts) { (result, error) in
13 | guard error == nil else {
14 | success(false)
15 | return
16 | }
17 | success(result)
18 | }
19 | }
20 |
21 | var isAuth: Bool {
22 | return CNContactStore.authorizationStatus(for: .contacts) == .authorized
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/PhotoLibPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import Photos
8 |
9 | class PhotoLibPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | PHPhotoLibrary.requestAuthorization { (status) in
13 | switch (status) {
14 | case .authorized: success(true)
15 | case .denied, .notDetermined, .restricted: success(false)
16 | @unknown default: success(false)
17 | }
18 | }
19 | }
20 |
21 | var isAuth: Bool {
22 | return PHPhotoLibrary.authorizationStatus() == .authorized
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/MediaLibPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import MediaPlayer
8 |
9 | class MediaLibPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | MPMediaLibrary.requestAuthorization { (status) in
13 | switch (status) {
14 | case .authorized: success(true)
15 | case .denied, .notDetermined, .restricted: success(false)
16 | @unknown default: success(false)
17 | }
18 | }
19 | }
20 |
21 | var isAuth: Bool {
22 | return MPMediaLibrary.authorizationStatus() == .authorized
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/SpeechPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import Speech
8 |
9 | class SpeechPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | SFSpeechRecognizer.requestAuthorization { (status) in
13 | switch (status) {
14 | case .authorized: success(true)
15 | case .denied, .notDetermined, .restricted: success(false)
16 | @unknown default: success(false)
17 | }
18 | }
19 | }
20 |
21 | var isAuth: Bool {
22 | return SFSpeechRecognizer.authorizationStatus() == .authorized
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/KPermission/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/CalendarPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import EventKit
8 |
9 | class CalendarPermission: KAuthProtocol {
10 |
11 | var type:EKEntityType!
12 |
13 | init(type: EKEntityType) {
14 | self.type = type
15 | }
16 |
17 | func auth(success: @escaping (Bool) -> Void) {
18 | EKEventStore.init().requestAccess(to: type) { (result, error) in
19 | guard error == nil else {
20 | success(false)
21 | return
22 | }
23 | success(result)
24 | }
25 | }
26 |
27 | var isAuth: Bool {
28 | return EKEventStore.authorizationStatus(for: type) == .authorized
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/MotionPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import CoreMotion
8 |
9 | class MotionPermission: KAuthProtocol {
10 |
11 | private lazy var manager = CMMotionActivityManager()
12 |
13 | func auth(success: @escaping (Bool) -> Void) {
14 | manager.queryActivityStarting(from: Date(), to: Date(), to: OperationQueue.main) { (activity, error) in
15 | guard error == nil else {
16 | success(false)
17 | return
18 | }
19 | success(true)
20 | self.manager.stopActivityUpdates()
21 | }
22 | }
23 |
24 | var isAuth: Bool {
25 | return CMMotionActivityManager.authorizationStatus() == .authorized
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/KPermission.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "KPermission"
4 | s.version = "1.0.4"
5 | s.summary = "Easy request permissions on iOS"
6 | s.description = <<-DESC
7 | Easy request permissions on iOS
8 | DESC
9 | s.homepage = "https://github.com/KenanAtmaca/KPermission"
10 | s.license = { :type => "MIT", :file => "LICENSE" }
11 | s.author = { "KenanAtmaca" => "mail.kenanatmaca@gmail.com" }
12 | s.social_media_url = "https://twitter.com/uikenan"
13 |
14 | s.platform = :ios, "11.0"
15 | s.requires_arc = true
16 | s.ios.deployment_target = "11.0"
17 |
18 | s.source = { :git => "https://github.com/KenanAtmaca/KPermission", :tag => "#{s.version}" }
19 | s.source_files = "KPermission", "KPermission/**/*.{h,m,swift}"
20 | s.resources = "KPermission/**/*.{xib,png}"
21 | s.resource_bundles = {
22 | 'KPermission' => [
23 | 'KPermission/**/*.{xib,png}'
24 | ]
25 | }
26 |
27 | s.swift_version = '4.2'
28 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.2'}
29 | end
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Kenan Atmaca
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 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/NotificationPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import UserNotifications
8 |
9 | class NotificationPermission: KAuthProtocol {
10 |
11 | func auth(success: @escaping (Bool) -> Void) {
12 | UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (result, error) in
13 | guard error == nil else {
14 | success(false)
15 | return
16 | }
17 | success(result)
18 | }
19 | }
20 |
21 | var isAuth: Bool {
22 | var status:Bool = false
23 | let semaphore = DispatchSemaphore(value: 0)
24 | UNUserNotificationCenter.current().getNotificationSettings { (result) in
25 | switch (result.authorizationStatus) {
26 | case .authorized:
27 | status = true
28 | semaphore.signal()
29 | case .denied, .notDetermined, .provisional:
30 | status = false
31 | semaphore.signal()
32 | @unknown default: status = false
33 | }
34 | }
35 | semaphore.wait()
36 | return status
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/KPermission/Sources/Permissions/LocationPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 | import CoreLocation
8 |
9 | class LocationPermission:NSObject, KAuthProtocol {
10 |
11 | private var locationManager:CLLocationManager = CLLocationManager()
12 | private var status:Bool = false
13 |
14 | override init() {
15 | super.init()
16 | self.locationManager.delegate = self
17 | }
18 |
19 | func auth(success: @escaping (Bool) -> Void) {
20 | if CLLocationManager.locationServicesEnabled() {
21 | locationManager.requestWhenInUseAuthorization()
22 | success(self.status)
23 | }
24 | }
25 |
26 | var isAuth: Bool {
27 | switch (CLLocationManager.authorizationStatus()) {
28 | case .authorizedAlways, .authorizedWhenInUse: return true
29 | case .denied, .notDetermined, .restricted: return false
30 | @unknown default: return false
31 | }
32 | }
33 | }
34 |
35 | extension LocationPermission: CLLocationManagerDelegate {
36 | func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
37 | switch status {
38 | case .authorizedAlways, .authorizedWhenInUse:
39 | self.status = true
40 | NotificationCenter.default.post(name: .init("ReloadPermissionStatus"), object: nil, userInfo: ["permissionType": KPermissionType.location])
41 | case .denied, .notDetermined, .restricted:
42 | self.status = false
43 | @unknown default: break
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KPermission
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## Advantages
14 | - [X] Simply use.
15 | - [X] Easy permission request.
16 |
17 |
18 | ## Requirements
19 |
20 | - Xcode 9.0 +
21 | - iOS 11.0 or greater
22 |
23 |
24 | ## Installation
25 |
26 | ### CocoaPods
27 |
28 | 1. Install [CocoaPods](http://cocoapods.org)
29 | 2. Add this repo to your `Podfile`
30 |
31 | ```ruby
32 | platform :ios, '11.0'
33 |
34 | target 'ProjectName' do
35 | use_frameworks!
36 | pod 'KPermission'
37 | end
38 | ```
39 |
40 | 3. Run `pod install`
41 | 4. Open up the new `.xcworkspace` that CocoaPods generated
42 | 5. Whenever you want to use the library: `import KPermission`
43 |
44 | ### Manually
45 |
46 | 1. Simply download the `KPermission` source files and import them into your project.
47 |
48 | ## Usage
49 |
50 |
51 |
52 |
53 |
54 | ```Swift
55 | KPermission.shared.view.show(view: self.view, types: [.camera, .photoLibrary], animation: .scale)
56 | ```
57 | Permission types:
58 | - Camera
59 | - Photo Library
60 | - Notification
61 | - Location
62 | - Microphone
63 | - Calander
64 | - Contacts
65 | - Reminder
66 | - Motion
67 | - Media Library
68 | - Speech
69 |
70 |
71 | ## License
72 | Usage is provided under the [MIT License](http://http//opensource.org/licenses/mit-license.php). See LICENSE for the full details.
73 |
--------------------------------------------------------------------------------
/KPermission/Sources/KPermission.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 |
8 | protocol KAuthProtocol: class {
9 | func auth(success: @escaping (_ flag:Bool) -> Void)
10 | var isAuth:Bool { get }
11 | }
12 |
13 | public enum KPermissionType: String, CustomStringConvertible {
14 |
15 | case camera = "Camera"
16 | case photoLibrary = "Photo Library"
17 | case notification = "Notification"
18 | case location = "Location"
19 | case microphone = "Microphone"
20 | case calendar = "Calander"
21 | case contacts = "Contacts"
22 | case reminder = "Reminder"
23 | case motion = "Motion"
24 | case mediaLibrary = "Media Library"
25 | case speech = "Speech"
26 |
27 | public var description: String {
28 | get {
29 | return self.rawValue
30 | }
31 | }
32 | }
33 |
34 | open class KPermission {
35 |
36 | static public let shared = KPermission()
37 | lazy public var view = KPermissionView()
38 |
39 | func allowPermission(permission: KPermissionType) -> KAuthProtocol {
40 | switch (permission) {
41 | case .camera: return CameraPermission()
42 | case .photoLibrary: return PhotoLibPermission()
43 | case .notification: return NotificationPermission()
44 | case .location: return LocationPermission()
45 | case .microphone: return MicPermission()
46 | case .calendar: return CalendarPermission(type: .event)
47 | case .contacts: return ContactsPermission()
48 | case .reminder: return CalendarPermission(type: .reminder)
49 | case .motion: return MotionPermission()
50 | case .mediaLibrary: return MediaLibPermission()
51 | case .speech: return SpeechPermission()
52 | }
53 | }
54 |
55 | func goPermissionSettings() {
56 | if let settingsUrl = URL(string: UIApplication.openSettingsURLString) {
57 | UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/KPermission/Sources/KPermissionTableCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 |
8 | protocol KPermissionTableAction: class {
9 | func tapAllowAction(cell: KPermissionTableCell)
10 | }
11 |
12 | class KPermissionTableCell: UITableViewCell {
13 |
14 | @IBOutlet weak var permissionImage: UIImageView!
15 | @IBOutlet weak var permissionTitle: UILabel!
16 | @IBOutlet weak var checkImageButton: UIButton!
17 |
18 | weak var actionDelegate: KPermissionTableAction?
19 |
20 | var status:Bool = false {
21 | didSet {
22 | DispatchQueue.main.async {
23 | self.status == true ? self.setAllowed() : self.setAllow()
24 | }
25 | }
26 | }
27 |
28 | static var id = String(describing: self)
29 |
30 | var data: KPermissionType! {
31 | didSet {
32 | permissionTitle.text = data.description
33 | permissionImage.image = UIImage(named: data.description, in: Bundle(for: KPermission.self), compatibleWith: nil) ?? UIImage()
34 | permissionImage.image = permissionImage.image?.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
35 | }
36 | }
37 |
38 | override func awakeFromNib() {
39 | super.awakeFromNib()
40 | self.selectionStyle = .none
41 | checkImageButton.addTarget(self, action: #selector(allowButtonAction), for: .touchUpInside)
42 | }
43 |
44 | private func setAllow() {
45 | checkImageButton.setTitle("ALLOW", for: .normal)
46 | checkImageButton.tag = 500
47 | checkImageButton.backgroundColor = .clear
48 | checkImageButton.layer.borderWidth = 1
49 | checkImageButton.layer.borderColor = UIColor(red: 0 / 255, green: 122 / 255, blue: 255 / 255, alpha: 1).cgColor
50 | checkImageButton.setTitleColor(UIColor(red: 0 / 255, green: 122 / 255, blue: 255 / 255, alpha: 1), for: .normal)
51 | checkImageButton.layer.cornerRadius = 5
52 | permissionImage.tintColor = UIColor(red: 205 / 255, green: 205 / 255, blue: 205 / 255, alpha: 1.0)
53 | }
54 |
55 | private func setAllowed() {
56 | checkImageButton.setTitle("ALLOWED", for: .normal)
57 | checkImageButton.layer.borderWidth = 0
58 | checkImageButton.backgroundColor = UIColor(red: 0 / 255, green: 122 / 255, blue: 255 / 255, alpha: 1)
59 | checkImageButton.setTitleColor(.white, for: .normal)
60 | checkImageButton.layer.cornerRadius = 5
61 | permissionImage.tintColor = .black
62 | }
63 |
64 | func setSettings() {
65 | checkImageButton.setTitle("SETTINGS", for: .normal)
66 | checkImageButton.tag = 404
67 | checkImageButton.backgroundColor = .clear
68 | checkImageButton.layer.borderWidth = 1
69 | checkImageButton.layer.borderColor = UIColor.lightGray.cgColor
70 | checkImageButton.setTitleColor(.lightGray, for: .normal)
71 | checkImageButton.layer.cornerRadius = 5
72 | permissionImage.tintColor = UIColor(red: 205 / 255, green: 205 / 255, blue: 205 / 255, alpha: 1.0)
73 | }
74 |
75 | @objc func allowButtonAction() {
76 | actionDelegate?.tapAllowAction(cell: self)
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/KPermission/Sources/KPermissionTableView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 |
8 | class KPermissionTableView: UITableView {
9 |
10 | private var permission:KAuthProtocol? = nil
11 |
12 | var types: [KPermissionType] = [] {
13 | didSet {
14 | reloadData()
15 | }
16 | }
17 |
18 | override init(frame: CGRect, style: UITableView.Style) {
19 | super.init(frame: frame, style: style)
20 | NotificationCenter.default.addObserver(self, selector: #selector(reloadPermissionObserve), name: NSNotification.Name.init(rawValue: "ReloadPermissionStatus"), object: nil)
21 | NotificationCenter.default.addObserver(self, selector: #selector(reloadAppActive), name: UIApplication.willEnterForegroundNotification, object: nil)
22 | self.separatorColor = UIColor.lightGray
23 | self.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
24 | self.delegate = self
25 | self.dataSource = self
26 | loadNib()
27 | }
28 |
29 | required init?(coder aDecoder: NSCoder) {
30 | fatalError("init(coder:) has not been implemented")
31 | }
32 |
33 | private func loadNib() {
34 | let tableViewBundle = Bundle(for: KPermission.self)
35 | self.register(UINib(nibName: "KPermissionListView", bundle: tableViewBundle), forCellReuseIdentifier: KPermissionTableCell.id)
36 | }
37 |
38 | private func reloadPermissionsStatus(cell: KPermissionTableCell) {
39 | let permission = KPermission.shared.allowPermission(permission: cell.data)
40 | cell.status = permission.isAuth
41 | }
42 |
43 | @objc private func reloadPermissionObserve(_ notification: Notification) {
44 | if let type = notification.userInfo?["permissionType"] as? KPermissionType {
45 | let permission = KPermission.shared.allowPermission(permission: type)
46 | if let typesRowIndex = types.firstIndex(of: type) {
47 | let index = IndexPath(row: typesRowIndex, section: 0)
48 | DispatchQueue.main.async {
49 | if let permissionCell = self.cellForRow(at: index) as? KPermissionTableCell {
50 | permissionCell.status = permission.isAuth
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
57 | @objc func reloadAppActive() {
58 | self.reloadData()
59 | }
60 |
61 | deinit {
62 | NotificationCenter.default.removeObserver(self, name: .init(rawValue: "ReloadPermissionStatus"), object: nil)
63 | NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
64 | }
65 | }
66 |
67 | extension KPermissionTableView: UITableViewDelegate, UITableViewDataSource, KPermissionTableAction {
68 |
69 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
70 | return types.count
71 | }
72 |
73 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
74 | guard let cell = tableView.dequeueReusableCell(withIdentifier: KPermissionTableCell.id) as? KPermissionTableCell else { return UITableViewCell() }
75 | cell.data = types[indexPath.row]
76 | cell.actionDelegate = self
77 | reloadPermissionsStatus(cell: cell)
78 | return cell
79 | }
80 |
81 | func tapAllowAction(cell: KPermissionTableCell) {
82 | guard !cell.status else { return }
83 | permission = KPermission.shared.allowPermission(permission: cell.data)
84 | permission?.auth { (status) in
85 | if !status {
86 | DispatchQueue.main.async {
87 | if cell.checkImageButton.tag != 404 {
88 | cell.setSettings()
89 | } else {
90 | KPermission.shared.goPermissionSettings()
91 | }
92 | }
93 | return
94 | } else {
95 | cell.status = self.permission?.isAuth ?? false
96 | }
97 | }
98 | }
99 |
100 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
101 | return 70
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/KPermission/View/KPermissionListView.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
32 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/KPermission/Sources/KPermissionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Kenan Atmaca on 2.08.2019.
3 | // Copyright © 2019 Kenan Atmaca. All rights reserved.
4 | //
5 |
6 | import UIKit
7 |
8 | open class KPermissionView:UIView {
9 |
10 | public enum KPermissionViewAnimationType {
11 | case top
12 | case bottom
13 | case left
14 | case right
15 | case scale
16 | case alpha
17 | }
18 |
19 | private var blackView:UIView = {
20 | let view = UIView()
21 | view.backgroundColor = UIColor.black.withAlphaComponent(0.8)
22 | view.translatesAutoresizingMaskIntoConstraints = false
23 | return view
24 | }()
25 |
26 | private var contentView:UIView = {
27 | let view = UIView()
28 | view.backgroundColor = .white
29 | view.clipsToBounds = true
30 | view.layer.cornerRadius = 10
31 | view.translatesAutoresizingMaskIntoConstraints = false
32 | return view
33 | }()
34 |
35 | private var closeButton:UIButton = {
36 | let button = UIButton()
37 | button.setImage(UIImage(named: "close", in: Bundle(for: KPermission.self), compatibleWith: nil), for: .normal)
38 | button.imageView?.contentMode = UIView.ContentMode.scaleAspectFit
39 | button.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
40 | button.layer.cornerRadius = 16
41 | button.clipsToBounds = true
42 | button.alpha = 0.8
43 | button.backgroundColor = .white
44 | button.translatesAutoresizingMaskIntoConstraints = false
45 | return button
46 | }()
47 |
48 | private var titleLabel:UILabel = {
49 | let label = UILabel()
50 | label.text = "Need Permissions"
51 | label.font = UIFont.monospacedDigitSystemFont(ofSize: 25, weight: .bold)
52 | label.translatesAutoresizingMaskIntoConstraints = false
53 | return label
54 | }()
55 |
56 | private var subtitleLabel:UILabel = {
57 | let label = UILabel()
58 | label.text = "Permission Request"
59 | label.textColor = UIColor.gray
60 | label.font = UIFont.monospacedDigitSystemFont(ofSize: 20, weight: .medium)
61 | label.translatesAutoresizingMaskIntoConstraints = false
62 | return label
63 | }()
64 |
65 | private var kTableView:KPermissionTableView = {
66 | let table = KPermissionTableView()
67 | table.translatesAutoresizingMaskIntoConstraints = false
68 | return table
69 | }()
70 |
71 | var animationDuration:TimeInterval = 1.0
72 |
73 | public override init(frame: CGRect) {
74 | super.init(frame: frame)
75 | }
76 |
77 | required public init?(coder aDecoder: NSCoder) {
78 | fatalError("init(coder:) has not been implemented")
79 | }
80 |
81 | public func show(view:UIView, types: [KPermissionType], animation: KPermissionViewAnimationType? = nil) {
82 | kTableView.types = types
83 | self.frame = UIScreen.main.bounds
84 | self.backgroundColor = .white
85 | self.addSubview(blackView)
86 | blackView.addSubview(contentView)
87 | contentView.addSubview(titleLabel)
88 | contentView.addSubview(subtitleLabel)
89 | contentView.addSubview(kTableView)
90 | self.addSubview(closeButton)
91 | let contentSize = CGFloat(types.count * 70) + 90
92 |
93 | blackView.alpha = 1
94 | blackView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
95 | blackView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
96 | blackView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
97 | blackView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
98 |
99 | contentView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
100 | contentView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
101 | contentView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.85).isActive = true
102 |
103 | if contentSize <= self.frame.height * 0.8 {
104 | contentView.heightAnchor.constraint(equalToConstant: contentSize).isActive = true
105 | } else {
106 | contentView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.8).isActive = true
107 | }
108 |
109 | closeButton.alpha = 1
110 | closeButton.bottomAnchor.constraint(equalTo: contentView.topAnchor, constant: 20).isActive = true
111 | closeButton.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 10).isActive = true
112 | closeButton.widthAnchor.constraint(equalToConstant: 32).isActive = true
113 | closeButton.heightAnchor.constraint(equalToConstant: 32).isActive = true
114 |
115 | titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20).isActive = true
116 | titleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20).isActive = true
117 |
118 | subtitleLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 5).isActive = true
119 | subtitleLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 20).isActive = true
120 |
121 | kTableView.topAnchor.constraint(equalTo: subtitleLabel.bottomAnchor, constant: 10).isActive = true
122 | kTableView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0).isActive = true
123 | kTableView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0).isActive = true
124 | kTableView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true
125 |
126 | view.addSubview(self)
127 |
128 | if let animation = animation { setAnimation(type: animation) }
129 | }
130 |
131 | private func setAnimation(type: KPermissionViewAnimationType) {
132 | switch type {
133 | case .alpha:
134 | blackView.alpha = 0
135 | closeButton.alpha = 0
136 | UIView.animate(withDuration: animationDuration) {
137 | self.blackView.alpha = 1
138 | self.closeButton.alpha = 0.6
139 | }
140 | case .top: setPositionAnimations(x: 0, y: -300)
141 | case .bottom: setPositionAnimations(x: 0, y: 500)
142 | case .left: setPositionAnimations(x: -200, y: 0)
143 | case .right: setPositionAnimations(x: 200, y: 0)
144 | case .scale: setPositionAnimations(x: 0.5, y: 0.5, scale: true)
145 | }
146 | }
147 |
148 | private func setPositionAnimations(x: CGFloat, y: CGFloat, scale:Bool = false) {
149 | self.contentView.transform = scale == false ? CGAffineTransform.init(translationX: x, y: y) : CGAffineTransform.init(scaleX: x, y: y)
150 | self.closeButton.alpha = 0
151 | UIView.animate(withDuration: animationDuration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: .curveEaseIn, animations: {
152 | self.contentView.transform = CGAffineTransform.identity
153 | self.closeButton.alpha = 0.8
154 | }) { (_) in }
155 | }
156 |
157 | @objc private func closeAction() {
158 | UIView.animate(withDuration: 0.3, animations: {
159 | self.blackView.alpha = 0
160 | self.closeButton.alpha = 0
161 | }) { (_) in
162 | self.removeFromSuperview()
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/KPermission.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6E8D5B0F22FD8E9C001E3033 /* KPermission.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E8D5B0D22FD8E9C001E3033 /* KPermission.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 6E8D5B2022FD8F85001E3033 /* MediaLibPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1622FD8F85001E3033 /* MediaLibPermission.swift */; };
12 | 6E8D5B2122FD8F85001E3033 /* MotionPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1722FD8F85001E3033 /* MotionPermission.swift */; };
13 | 6E8D5B2222FD8F85001E3033 /* NotificationPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1822FD8F85001E3033 /* NotificationPermission.swift */; };
14 | 6E8D5B2322FD8F85001E3033 /* PhotoLibPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1922FD8F85001E3033 /* PhotoLibPermission.swift */; };
15 | 6E8D5B2422FD8F85001E3033 /* LocationPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1A22FD8F85001E3033 /* LocationPermission.swift */; };
16 | 6E8D5B2522FD8F85001E3033 /* CameraPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1B22FD8F85001E3033 /* CameraPermission.swift */; };
17 | 6E8D5B2622FD8F85001E3033 /* SpeechPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1C22FD8F85001E3033 /* SpeechPermission.swift */; };
18 | 6E8D5B2722FD8F85001E3033 /* CalendarPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1D22FD8F85001E3033 /* CalendarPermission.swift */; };
19 | 6E8D5B2822FD8F85001E3033 /* MicPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1E22FD8F85001E3033 /* MicPermission.swift */; };
20 | 6E8D5B2922FD8F85001E3033 /* ContactsPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B1F22FD8F85001E3033 /* ContactsPermission.swift */; };
21 | 6E8D5B3022FD8FBA001E3033 /* KPermissionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B2B22FD8FBA001E3033 /* KPermissionView.swift */; };
22 | 6E8D5B3122FD8FBA001E3033 /* KPermissionListView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B2C22FD8FBA001E3033 /* KPermissionListView.xib */; };
23 | 6E8D5B3222FD8FBA001E3033 /* KPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B2D22FD8FBA001E3033 /* KPermission.swift */; };
24 | 6E8D5B3322FD8FBA001E3033 /* KPermissionTableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B2E22FD8FBA001E3033 /* KPermissionTableCell.swift */; };
25 | 6E8D5B3422FD8FBA001E3033 /* KPermissionTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D5B2F22FD8FBA001E3033 /* KPermissionTableView.swift */; };
26 | 6E8D5B4322FD90F4001E3033 /* Contacts.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3722FD90F4001E3033 /* Contacts.png */; };
27 | 6E8D5B4422FD90F4001E3033 /* close.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3822FD90F4001E3033 /* close.png */; };
28 | 6E8D5B4522FD90F4001E3033 /* Media Library.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3922FD90F4001E3033 /* Media Library.png */; };
29 | 6E8D5B4622FD90F4001E3033 /* Calander.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3A22FD90F4001E3033 /* Calander.png */; };
30 | 6E8D5B4722FD90F4001E3033 /* Microphone.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3B22FD90F4001E3033 /* Microphone.png */; };
31 | 6E8D5B4822FD90F4001E3033 /* Motion.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3C22FD90F4001E3033 /* Motion.png */; };
32 | 6E8D5B4922FD90F4001E3033 /* Notification.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3D22FD90F4001E3033 /* Notification.png */; };
33 | 6E8D5B4A22FD90F4001E3033 /* Photo Library.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3E22FD90F4001E3033 /* Photo Library.png */; };
34 | 6E8D5B4B22FD90F4001E3033 /* Reminder.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B3F22FD90F4001E3033 /* Reminder.png */; };
35 | 6E8D5B4C22FD90F4001E3033 /* Speech.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B4022FD90F4001E3033 /* Speech.png */; };
36 | 6E8D5B4D22FD90F4001E3033 /* Camera.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B4122FD90F4001E3033 /* Camera.png */; };
37 | 6E8D5B4E22FD90F4001E3033 /* Location.png in Resources */ = {isa = PBXBuildFile; fileRef = 6E8D5B4222FD90F4001E3033 /* Location.png */; };
38 | /* End PBXBuildFile section */
39 |
40 | /* Begin PBXFileReference section */
41 | 6E8D5B0A22FD8E9C001E3033 /* KPermission.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KPermission.framework; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 6E8D5B0D22FD8E9C001E3033 /* KPermission.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KPermission.h; sourceTree = ""; };
43 | 6E8D5B0E22FD8E9C001E3033 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | 6E8D5B1622FD8F85001E3033 /* MediaLibPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaLibPermission.swift; sourceTree = ""; };
45 | 6E8D5B1722FD8F85001E3033 /* MotionPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MotionPermission.swift; sourceTree = ""; };
46 | 6E8D5B1822FD8F85001E3033 /* NotificationPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationPermission.swift; sourceTree = ""; };
47 | 6E8D5B1922FD8F85001E3033 /* PhotoLibPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoLibPermission.swift; sourceTree = ""; };
48 | 6E8D5B1A22FD8F85001E3033 /* LocationPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationPermission.swift; sourceTree = ""; };
49 | 6E8D5B1B22FD8F85001E3033 /* CameraPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraPermission.swift; sourceTree = ""; };
50 | 6E8D5B1C22FD8F85001E3033 /* SpeechPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeechPermission.swift; sourceTree = ""; };
51 | 6E8D5B1D22FD8F85001E3033 /* CalendarPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarPermission.swift; sourceTree = ""; };
52 | 6E8D5B1E22FD8F85001E3033 /* MicPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MicPermission.swift; sourceTree = ""; };
53 | 6E8D5B1F22FD8F85001E3033 /* ContactsPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactsPermission.swift; sourceTree = ""; };
54 | 6E8D5B2B22FD8FBA001E3033 /* KPermissionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KPermissionView.swift; sourceTree = ""; };
55 | 6E8D5B2C22FD8FBA001E3033 /* KPermissionListView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KPermissionListView.xib; sourceTree = ""; };
56 | 6E8D5B2D22FD8FBA001E3033 /* KPermission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KPermission.swift; sourceTree = ""; };
57 | 6E8D5B2E22FD8FBA001E3033 /* KPermissionTableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KPermissionTableCell.swift; sourceTree = ""; };
58 | 6E8D5B2F22FD8FBA001E3033 /* KPermissionTableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KPermissionTableView.swift; sourceTree = ""; };
59 | 6E8D5B3722FD90F4001E3033 /* Contacts.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Contacts.png; sourceTree = ""; };
60 | 6E8D5B3822FD90F4001E3033 /* close.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = close.png; sourceTree = ""; };
61 | 6E8D5B3922FD90F4001E3033 /* Media Library.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Media Library.png"; sourceTree = ""; };
62 | 6E8D5B3A22FD90F4001E3033 /* Calander.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Calander.png; sourceTree = ""; };
63 | 6E8D5B3B22FD90F4001E3033 /* Microphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Microphone.png; sourceTree = ""; };
64 | 6E8D5B3C22FD90F4001E3033 /* Motion.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Motion.png; sourceTree = ""; };
65 | 6E8D5B3D22FD90F4001E3033 /* Notification.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Notification.png; sourceTree = ""; };
66 | 6E8D5B3E22FD90F4001E3033 /* Photo Library.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Photo Library.png"; sourceTree = ""; };
67 | 6E8D5B3F22FD90F4001E3033 /* Reminder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Reminder.png; sourceTree = ""; };
68 | 6E8D5B4022FD90F4001E3033 /* Speech.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Speech.png; sourceTree = ""; };
69 | 6E8D5B4122FD90F4001E3033 /* Camera.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Camera.png; sourceTree = ""; };
70 | 6E8D5B4222FD90F4001E3033 /* Location.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Location.png; sourceTree = ""; };
71 | /* End PBXFileReference section */
72 |
73 | /* Begin PBXFrameworksBuildPhase section */
74 | 6E8D5B0722FD8E9C001E3033 /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | /* End PBXFrameworksBuildPhase section */
82 |
83 | /* Begin PBXGroup section */
84 | 6E8D5B0022FD8E9C001E3033 = {
85 | isa = PBXGroup;
86 | children = (
87 | 6E8D5B0C22FD8E9C001E3033 /* KPermission */,
88 | 6E8D5B0B22FD8E9C001E3033 /* Products */,
89 | );
90 | sourceTree = "";
91 | };
92 | 6E8D5B0B22FD8E9C001E3033 /* Products */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 6E8D5B0A22FD8E9C001E3033 /* KPermission.framework */,
96 | );
97 | name = Products;
98 | sourceTree = "";
99 | };
100 | 6E8D5B0C22FD8E9C001E3033 /* KPermission */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 6E8D5B3622FD9050001E3033 /* Icons */,
104 | 6E8D5B3522FD8FC6001E3033 /* View */,
105 | 6E8D5B2A22FD8F9A001E3033 /* Sources */,
106 | 6E8D5B0D22FD8E9C001E3033 /* KPermission.h */,
107 | 6E8D5B0E22FD8E9C001E3033 /* Info.plist */,
108 | );
109 | path = KPermission;
110 | sourceTree = "";
111 | };
112 | 6E8D5B1522FD8F85001E3033 /* Permissions */ = {
113 | isa = PBXGroup;
114 | children = (
115 | 6E8D5B1622FD8F85001E3033 /* MediaLibPermission.swift */,
116 | 6E8D5B1722FD8F85001E3033 /* MotionPermission.swift */,
117 | 6E8D5B1822FD8F85001E3033 /* NotificationPermission.swift */,
118 | 6E8D5B1922FD8F85001E3033 /* PhotoLibPermission.swift */,
119 | 6E8D5B1A22FD8F85001E3033 /* LocationPermission.swift */,
120 | 6E8D5B1B22FD8F85001E3033 /* CameraPermission.swift */,
121 | 6E8D5B1C22FD8F85001E3033 /* SpeechPermission.swift */,
122 | 6E8D5B1D22FD8F85001E3033 /* CalendarPermission.swift */,
123 | 6E8D5B1E22FD8F85001E3033 /* MicPermission.swift */,
124 | 6E8D5B1F22FD8F85001E3033 /* ContactsPermission.swift */,
125 | );
126 | path = Permissions;
127 | sourceTree = "";
128 | };
129 | 6E8D5B2A22FD8F9A001E3033 /* Sources */ = {
130 | isa = PBXGroup;
131 | children = (
132 | 6E8D5B1522FD8F85001E3033 /* Permissions */,
133 | 6E8D5B2D22FD8FBA001E3033 /* KPermission.swift */,
134 | 6E8D5B2B22FD8FBA001E3033 /* KPermissionView.swift */,
135 | 6E8D5B2F22FD8FBA001E3033 /* KPermissionTableView.swift */,
136 | 6E8D5B2E22FD8FBA001E3033 /* KPermissionTableCell.swift */,
137 | );
138 | path = Sources;
139 | sourceTree = "";
140 | };
141 | 6E8D5B3522FD8FC6001E3033 /* View */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 6E8D5B2C22FD8FBA001E3033 /* KPermissionListView.xib */,
145 | );
146 | path = View;
147 | sourceTree = "";
148 | };
149 | 6E8D5B3622FD9050001E3033 /* Icons */ = {
150 | isa = PBXGroup;
151 | children = (
152 | 6E8D5B3A22FD90F4001E3033 /* Calander.png */,
153 | 6E8D5B4122FD90F4001E3033 /* Camera.png */,
154 | 6E8D5B3822FD90F4001E3033 /* close.png */,
155 | 6E8D5B3722FD90F4001E3033 /* Contacts.png */,
156 | 6E8D5B4222FD90F4001E3033 /* Location.png */,
157 | 6E8D5B3922FD90F4001E3033 /* Media Library.png */,
158 | 6E8D5B3B22FD90F4001E3033 /* Microphone.png */,
159 | 6E8D5B3C22FD90F4001E3033 /* Motion.png */,
160 | 6E8D5B3D22FD90F4001E3033 /* Notification.png */,
161 | 6E8D5B3E22FD90F4001E3033 /* Photo Library.png */,
162 | 6E8D5B3F22FD90F4001E3033 /* Reminder.png */,
163 | 6E8D5B4022FD90F4001E3033 /* Speech.png */,
164 | );
165 | path = Icons;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXHeadersBuildPhase section */
171 | 6E8D5B0522FD8E9C001E3033 /* Headers */ = {
172 | isa = PBXHeadersBuildPhase;
173 | buildActionMask = 2147483647;
174 | files = (
175 | 6E8D5B0F22FD8E9C001E3033 /* KPermission.h in Headers */,
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | };
179 | /* End PBXHeadersBuildPhase section */
180 |
181 | /* Begin PBXNativeTarget section */
182 | 6E8D5B0922FD8E9C001E3033 /* KPermission */ = {
183 | isa = PBXNativeTarget;
184 | buildConfigurationList = 6E8D5B1222FD8E9C001E3033 /* Build configuration list for PBXNativeTarget "KPermission" */;
185 | buildPhases = (
186 | 6E8D5B0522FD8E9C001E3033 /* Headers */,
187 | 6E8D5B0622FD8E9C001E3033 /* Sources */,
188 | 6E8D5B0722FD8E9C001E3033 /* Frameworks */,
189 | 6E8D5B0822FD8E9C001E3033 /* Resources */,
190 | );
191 | buildRules = (
192 | );
193 | dependencies = (
194 | );
195 | name = KPermission;
196 | productName = KPermission;
197 | productReference = 6E8D5B0A22FD8E9C001E3033 /* KPermission.framework */;
198 | productType = "com.apple.product-type.framework";
199 | };
200 | /* End PBXNativeTarget section */
201 |
202 | /* Begin PBXProject section */
203 | 6E8D5B0122FD8E9C001E3033 /* Project object */ = {
204 | isa = PBXProject;
205 | attributes = {
206 | LastUpgradeCheck = 1020;
207 | ORGANIZATIONNAME = "Kenan Atmaca";
208 | TargetAttributes = {
209 | 6E8D5B0922FD8E9C001E3033 = {
210 | CreatedOnToolsVersion = 10.2.1;
211 | };
212 | };
213 | };
214 | buildConfigurationList = 6E8D5B0422FD8E9C001E3033 /* Build configuration list for PBXProject "KPermission" */;
215 | compatibilityVersion = "Xcode 9.3";
216 | developmentRegion = en;
217 | hasScannedForEncodings = 0;
218 | knownRegions = (
219 | en,
220 | );
221 | mainGroup = 6E8D5B0022FD8E9C001E3033;
222 | productRefGroup = 6E8D5B0B22FD8E9C001E3033 /* Products */;
223 | projectDirPath = "";
224 | projectRoot = "";
225 | targets = (
226 | 6E8D5B0922FD8E9C001E3033 /* KPermission */,
227 | );
228 | };
229 | /* End PBXProject section */
230 |
231 | /* Begin PBXResourcesBuildPhase section */
232 | 6E8D5B0822FD8E9C001E3033 /* Resources */ = {
233 | isa = PBXResourcesBuildPhase;
234 | buildActionMask = 2147483647;
235 | files = (
236 | 6E8D5B4422FD90F4001E3033 /* close.png in Resources */,
237 | 6E8D5B4E22FD90F4001E3033 /* Location.png in Resources */,
238 | 6E8D5B4722FD90F4001E3033 /* Microphone.png in Resources */,
239 | 6E8D5B4C22FD90F4001E3033 /* Speech.png in Resources */,
240 | 6E8D5B4922FD90F4001E3033 /* Notification.png in Resources */,
241 | 6E8D5B4622FD90F4001E3033 /* Calander.png in Resources */,
242 | 6E8D5B4A22FD90F4001E3033 /* Photo Library.png in Resources */,
243 | 6E8D5B4522FD90F4001E3033 /* Media Library.png in Resources */,
244 | 6E8D5B4322FD90F4001E3033 /* Contacts.png in Resources */,
245 | 6E8D5B4B22FD90F4001E3033 /* Reminder.png in Resources */,
246 | 6E8D5B4822FD90F4001E3033 /* Motion.png in Resources */,
247 | 6E8D5B4D22FD90F4001E3033 /* Camera.png in Resources */,
248 | 6E8D5B3122FD8FBA001E3033 /* KPermissionListView.xib in Resources */,
249 | );
250 | runOnlyForDeploymentPostprocessing = 0;
251 | };
252 | /* End PBXResourcesBuildPhase section */
253 |
254 | /* Begin PBXSourcesBuildPhase section */
255 | 6E8D5B0622FD8E9C001E3033 /* Sources */ = {
256 | isa = PBXSourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | 6E8D5B3222FD8FBA001E3033 /* KPermission.swift in Sources */,
260 | 6E8D5B2122FD8F85001E3033 /* MotionPermission.swift in Sources */,
261 | 6E8D5B2922FD8F85001E3033 /* ContactsPermission.swift in Sources */,
262 | 6E8D5B2522FD8F85001E3033 /* CameraPermission.swift in Sources */,
263 | 6E8D5B3422FD8FBA001E3033 /* KPermissionTableView.swift in Sources */,
264 | 6E8D5B3022FD8FBA001E3033 /* KPermissionView.swift in Sources */,
265 | 6E8D5B3322FD8FBA001E3033 /* KPermissionTableCell.swift in Sources */,
266 | 6E8D5B2322FD8F85001E3033 /* PhotoLibPermission.swift in Sources */,
267 | 6E8D5B2622FD8F85001E3033 /* SpeechPermission.swift in Sources */,
268 | 6E8D5B2022FD8F85001E3033 /* MediaLibPermission.swift in Sources */,
269 | 6E8D5B2222FD8F85001E3033 /* NotificationPermission.swift in Sources */,
270 | 6E8D5B2722FD8F85001E3033 /* CalendarPermission.swift in Sources */,
271 | 6E8D5B2422FD8F85001E3033 /* LocationPermission.swift in Sources */,
272 | 6E8D5B2822FD8F85001E3033 /* MicPermission.swift in Sources */,
273 | );
274 | runOnlyForDeploymentPostprocessing = 0;
275 | };
276 | /* End PBXSourcesBuildPhase section */
277 |
278 | /* Begin XCBuildConfiguration section */
279 | 6E8D5B1022FD8E9C001E3033 /* Debug */ = {
280 | isa = XCBuildConfiguration;
281 | buildSettings = {
282 | ALWAYS_SEARCH_USER_PATHS = NO;
283 | CLANG_ANALYZER_NONNULL = YES;
284 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
285 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
286 | CLANG_CXX_LIBRARY = "libc++";
287 | CLANG_ENABLE_MODULES = YES;
288 | CLANG_ENABLE_OBJC_ARC = YES;
289 | CLANG_ENABLE_OBJC_WEAK = YES;
290 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
291 | CLANG_WARN_BOOL_CONVERSION = YES;
292 | CLANG_WARN_COMMA = YES;
293 | CLANG_WARN_CONSTANT_CONVERSION = YES;
294 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
295 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
296 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
297 | CLANG_WARN_EMPTY_BODY = YES;
298 | CLANG_WARN_ENUM_CONVERSION = YES;
299 | CLANG_WARN_INFINITE_RECURSION = YES;
300 | CLANG_WARN_INT_CONVERSION = YES;
301 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
302 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
303 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
305 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
306 | CLANG_WARN_STRICT_PROTOTYPES = YES;
307 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
308 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
309 | CLANG_WARN_UNREACHABLE_CODE = YES;
310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
311 | CODE_SIGN_IDENTITY = "iPhone Developer";
312 | COPY_PHASE_STRIP = NO;
313 | CURRENT_PROJECT_VERSION = 1;
314 | DEBUG_INFORMATION_FORMAT = dwarf;
315 | ENABLE_STRICT_OBJC_MSGSEND = YES;
316 | ENABLE_TESTABILITY = YES;
317 | GCC_C_LANGUAGE_STANDARD = gnu11;
318 | GCC_DYNAMIC_NO_PIC = NO;
319 | GCC_NO_COMMON_BLOCKS = YES;
320 | GCC_OPTIMIZATION_LEVEL = 0;
321 | GCC_PREPROCESSOR_DEFINITIONS = (
322 | "DEBUG=1",
323 | "$(inherited)",
324 | );
325 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
326 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
327 | GCC_WARN_UNDECLARED_SELECTOR = YES;
328 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
329 | GCC_WARN_UNUSED_FUNCTION = YES;
330 | GCC_WARN_UNUSED_VARIABLE = YES;
331 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
332 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
333 | MTL_FAST_MATH = YES;
334 | ONLY_ACTIVE_ARCH = YES;
335 | SDKROOT = iphoneos;
336 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
337 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
338 | VERSIONING_SYSTEM = "apple-generic";
339 | VERSION_INFO_PREFIX = "";
340 | };
341 | name = Debug;
342 | };
343 | 6E8D5B1122FD8E9C001E3033 /* Release */ = {
344 | isa = XCBuildConfiguration;
345 | buildSettings = {
346 | ALWAYS_SEARCH_USER_PATHS = NO;
347 | CLANG_ANALYZER_NONNULL = YES;
348 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
349 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
350 | CLANG_CXX_LIBRARY = "libc++";
351 | CLANG_ENABLE_MODULES = YES;
352 | CLANG_ENABLE_OBJC_ARC = YES;
353 | CLANG_ENABLE_OBJC_WEAK = YES;
354 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
355 | CLANG_WARN_BOOL_CONVERSION = YES;
356 | CLANG_WARN_COMMA = YES;
357 | CLANG_WARN_CONSTANT_CONVERSION = YES;
358 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
359 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
360 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
361 | CLANG_WARN_EMPTY_BODY = YES;
362 | CLANG_WARN_ENUM_CONVERSION = YES;
363 | CLANG_WARN_INFINITE_RECURSION = YES;
364 | CLANG_WARN_INT_CONVERSION = YES;
365 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
366 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
367 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
368 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
369 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
370 | CLANG_WARN_STRICT_PROTOTYPES = YES;
371 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
372 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
373 | CLANG_WARN_UNREACHABLE_CODE = YES;
374 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
375 | CODE_SIGN_IDENTITY = "iPhone Developer";
376 | COPY_PHASE_STRIP = NO;
377 | CURRENT_PROJECT_VERSION = 1;
378 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
379 | ENABLE_NS_ASSERTIONS = NO;
380 | ENABLE_STRICT_OBJC_MSGSEND = YES;
381 | GCC_C_LANGUAGE_STANDARD = gnu11;
382 | GCC_NO_COMMON_BLOCKS = YES;
383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
385 | GCC_WARN_UNDECLARED_SELECTOR = YES;
386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
387 | GCC_WARN_UNUSED_FUNCTION = YES;
388 | GCC_WARN_UNUSED_VARIABLE = YES;
389 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
390 | MTL_ENABLE_DEBUG_INFO = NO;
391 | MTL_FAST_MATH = YES;
392 | SDKROOT = iphoneos;
393 | SWIFT_COMPILATION_MODE = wholemodule;
394 | SWIFT_OPTIMIZATION_LEVEL = "-O";
395 | VALIDATE_PRODUCT = YES;
396 | VERSIONING_SYSTEM = "apple-generic";
397 | VERSION_INFO_PREFIX = "";
398 | };
399 | name = Release;
400 | };
401 | 6E8D5B1322FD8E9C001E3033 /* Debug */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | CODE_SIGN_IDENTITY = "";
405 | CODE_SIGN_STYLE = Automatic;
406 | DEFINES_MODULE = YES;
407 | DEVELOPMENT_TEAM = 2B24WNBC56;
408 | DYLIB_COMPATIBILITY_VERSION = 1;
409 | DYLIB_CURRENT_VERSION = 1;
410 | DYLIB_INSTALL_NAME_BASE = "@rpath";
411 | INFOPLIST_FILE = KPermission/Info.plist;
412 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
413 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
414 | LD_RUNPATH_SEARCH_PATHS = (
415 | "$(inherited)",
416 | "@executable_path/Frameworks",
417 | "@loader_path/Frameworks",
418 | );
419 | PRODUCT_BUNDLE_IDENTIFIER = com.kenan.KPermission;
420 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
421 | SKIP_INSTALL = YES;
422 | SWIFT_VERSION = 5.0;
423 | TARGETED_DEVICE_FAMILY = 1;
424 | };
425 | name = Debug;
426 | };
427 | 6E8D5B1422FD8E9C001E3033 /* Release */ = {
428 | isa = XCBuildConfiguration;
429 | buildSettings = {
430 | CODE_SIGN_IDENTITY = "";
431 | CODE_SIGN_STYLE = Automatic;
432 | DEFINES_MODULE = YES;
433 | DEVELOPMENT_TEAM = 2B24WNBC56;
434 | DYLIB_COMPATIBILITY_VERSION = 1;
435 | DYLIB_CURRENT_VERSION = 1;
436 | DYLIB_INSTALL_NAME_BASE = "@rpath";
437 | INFOPLIST_FILE = KPermission/Info.plist;
438 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
439 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
440 | LD_RUNPATH_SEARCH_PATHS = (
441 | "$(inherited)",
442 | "@executable_path/Frameworks",
443 | "@loader_path/Frameworks",
444 | );
445 | PRODUCT_BUNDLE_IDENTIFIER = com.kenan.KPermission;
446 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
447 | SKIP_INSTALL = YES;
448 | SWIFT_VERSION = 5.0;
449 | TARGETED_DEVICE_FAMILY = 1;
450 | };
451 | name = Release;
452 | };
453 | /* End XCBuildConfiguration section */
454 |
455 | /* Begin XCConfigurationList section */
456 | 6E8D5B0422FD8E9C001E3033 /* Build configuration list for PBXProject "KPermission" */ = {
457 | isa = XCConfigurationList;
458 | buildConfigurations = (
459 | 6E8D5B1022FD8E9C001E3033 /* Debug */,
460 | 6E8D5B1122FD8E9C001E3033 /* Release */,
461 | );
462 | defaultConfigurationIsVisible = 0;
463 | defaultConfigurationName = Release;
464 | };
465 | 6E8D5B1222FD8E9C001E3033 /* Build configuration list for PBXNativeTarget "KPermission" */ = {
466 | isa = XCConfigurationList;
467 | buildConfigurations = (
468 | 6E8D5B1322FD8E9C001E3033 /* Debug */,
469 | 6E8D5B1422FD8E9C001E3033 /* Release */,
470 | );
471 | defaultConfigurationIsVisible = 0;
472 | defaultConfigurationName = Release;
473 | };
474 | /* End XCConfigurationList section */
475 | };
476 | rootObject = 6E8D5B0122FD8E9C001E3033 /* Project object */;
477 | }
478 |
--------------------------------------------------------------------------------