├── 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 | MIT Licance 7 | MIT Licance 8 | MIT Licance 9 | MIT Licance 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 | --------------------------------------------------------------------------------