From 4d06028a04afc2dbdaea39c227f1fffd9e112954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20Gu=CC=88ndu=CC=88z?= Date: Thu, 14 Sep 2017 11:44:17 +0200 Subject: [PATCH 1/5] Add UserNotifications Framework for iOS 10+ --- Permission.podspec | 33 +++++----- Permission.xcodeproj/project.pbxproj | 4 ++ PermissionConfiguration.xcconfig | 33 +++++----- Source/Permission.swift | 63 ++++++++++++++----- Source/PermissionType.swift | 13 +++- Source/PermissionTypes/Notifications.swift | 22 +++++-- .../PermissionTypes/UserNotifications.swift | 56 +++++++++++++++++ 7 files changed, 174 insertions(+), 50 deletions(-) mode change 100644 => 100755 Permission.podspec mode change 100644 => 100755 Permission.xcodeproj/project.pbxproj mode change 100644 => 100755 PermissionConfiguration.xcconfig mode change 100644 => 100755 Source/Permission.swift mode change 100644 => 100755 Source/PermissionType.swift mode change 100644 => 100755 Source/PermissionTypes/Notifications.swift create mode 100755 Source/PermissionTypes/UserNotifications.swift diff --git a/Permission.podspec b/Permission.podspec old mode 100644 new mode 100755 index 3fc73a2..b552ce9 --- a/Permission.podspec +++ b/Permission.podspec @@ -21,71 +21,76 @@ Pod::Spec.new do |s| s.subspec 'AddressBook' do |ab| ab.dependency 'Permission/Core' - ab.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_ADDRESS_BOOK" } + ab.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_ADDRESS_BOOK" } end s.subspec 'Bluetooth' do |bl| bl.dependency 'Permission/Core' - bl.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_BLUETOOTH" } + bl.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_BLUETOOTH" } end s.subspec 'Camera' do |cm| cm.dependency 'Permission/Core' - cm.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_CAMERA" } + cm.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_CAMERA" } end s.subspec 'Contacts' do |cn| cn.dependency 'Permission/Core' - cn.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_CONTACTS" } + cn.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_CONTACTS" } end s.subspec 'Events' do |ev| ev.dependency 'Permission/Core' - ev.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_EVENTS" } + ev.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_EVENTS" } end s.subspec 'Location' do |lo| lo.dependency 'Permission/Core' - lo.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_LOCATION" } + lo.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_LOCATION" } end s.subspec 'Microphone' do |mi| mi.dependency 'Permission/Core' - mi.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MICROPHONE" } + mi.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MICROPHONE" } end s.subspec 'Motion' do |mo| mo.dependency 'Permission/Core' - mo.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MOTION" } + mo.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MOTION" } end s.subspec 'Notifications' do |no| no.dependency 'Permission/Core' - no.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_NOTIFICATIONS" } + no.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_NOTIFICATIONS" } + end + + s.subspec 'UserNotifications' do |un| + un.dependency 'Permission/Core' + un.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_USER_NOTIFICATIONS" } end s.subspec 'Photos' do |ph| ph.dependency 'Permission/Core' - ph.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_PHOTOS" } + ph.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_PHOTOS" } end s.subspec 'Reminders' do |re| re.dependency 'Permission/Core' - re.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_REMINDERS" } + re.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_REMINDERS" } end s.subspec 'SpeechRecognizer' do |rs| rs.dependency 'Permission/Core' - rs.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_SPEECH_RECOGNIZER" } + rs.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_SPEECH_RECOGNIZER" } end s.subspec 'MediaLibrary' do |ml| ml.dependency 'Permission/Core' - ml.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MEDIA_LIBRARY" } + ml.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_MEDIA_LIBRARY" } end s.subspec 'Siri' do |ab| ab.dependency 'Permission/Core' - ab.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_SIRI" } + ab.pod_target_xcconfig = { "SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "PERMISSION_SIRI" } end end diff --git a/Permission.xcodeproj/project.pbxproj b/Permission.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 04a199b..cb445ec --- a/Permission.xcodeproj/project.pbxproj +++ b/Permission.xcodeproj/project.pbxproj @@ -33,6 +33,7 @@ 6DF9C2BE1C8F4FE5000710C1 /* Photos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF9C2BD1C8F4FE5000710C1 /* Photos.swift */; }; 6DF9C2C01C8F5003000710C1 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF9C2BF1C8F5003000710C1 /* Events.swift */; }; 6DF9C2C61C8F5B4C000710C1 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF9C2C51C8F5B4C000710C1 /* Location.swift */; }; + E1370D871E31F7F700C9E83D /* UserNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1370D861E31F7F700C9E83D /* UserNotifications.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -76,6 +77,7 @@ 6DF9C2BF1C8F5003000710C1 /* Events.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = ""; }; 6DF9C2C51C8F5B4C000710C1 /* Location.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = ""; }; D08FF2891DC3AD2900F28088 /* PermissionFlags.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = PermissionFlags.xcconfig; sourceTree = ""; }; + E1370D861E31F7F700C9E83D /* UserNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserNotifications.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -154,6 +156,7 @@ 6DF9C2B91C8F4FAC000710C1 /* Microphone.swift */, 6D935F5E1C9A14AB00BB39E3 /* Motion.swift */, 6DF9C2B71C8F4F8F000710C1 /* Notifications.swift */, + E1370D861E31F7F700C9E83D /* UserNotifications.swift */, 6DF9C2BD1C8F4FE5000710C1 /* Photos.swift */, 6DF9C2B51C8F4F69000710C1 /* Reminders.swift */, 3F21DC7C1E30B6DB00B3EF65 /* Siri.swift */, @@ -291,6 +294,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E1370D871E31F7F700C9E83D /* UserNotifications.swift in Sources */, 6D491E781C9CA90B00611006 /* PermissionStatus.swift in Sources */, 6D935F5F1C9A14AB00BB39E3 /* Motion.swift in Sources */, 6D935F5D1C9A0FEA00BB39E3 /* Bluetooth.swift in Sources */, diff --git a/PermissionConfiguration.xcconfig b/PermissionConfiguration.xcconfig old mode 100644 new mode 100755 index 5bf1ae5..88b2ecd --- a/PermissionConfiguration.xcconfig +++ b/PermissionConfiguration.xcconfig @@ -22,22 +22,23 @@ // SOFTWARE. // -PERMISSION_ADDRESS_BOOK = PERMISSION_ADDRESS_BOOK -PERMISSION_BLUETOOTH = PERMISSION_BLUETOOTH -PERMISSION_CAMERA = PERMISSION_CAMERA -PERMISSION_CONTACTS = PERMISSION_CONTACTS -PERMISSION_EVENTS = PERMISSION_EVENTS -PERMISSION_LOCATION = PERMISSION_LOCATION -PERMISSION_MICROPHONE = PERMISSION_MICROPHONE -PERMISSION_MOTION = PERMISSION_MOTION -PERMISSION_NOTIFICATIONS = PERMISSION_NOTIFICATIONS -PERMISSION_PHOTOS = PERMISSION_PHOTOS -PERMISSION_REMINDERS = PERMISSION_REMINDERS -PERMISSION_SPEECH_RECOGNIZER = PERMISSION_SPEECH_RECOGNIZER -PERMISSION_MEDIA_LIBRARY = PERMISSION_MEDIA_LIBRARY -PERMISSION_SIRI = PERMISSION_SIRI +PERMISSION_ADDRESS_BOOK = PERMISSION_ADDRESS_BOOK +PERMISSION_BLUETOOTH = PERMISSION_BLUETOOTH +PERMISSION_CAMERA = PERMISSION_CAMERA +PERMISSION_CONTACTS = PERMISSION_CONTACTS +PERMISSION_EVENTS = PERMISSION_EVENTS +PERMISSION_LOCATION = PERMISSION_LOCATION +PERMISSION_MICROPHONE = PERMISSION_MICROPHONE +PERMISSION_MOTION = PERMISSION_MOTION +PERMISSION_NOTIFICATIONS = PERMISSION_NOTIFICATIONS +PERMISSION_USER_NOTIFICATIONS = PERMISSION_USER_NOTIFICATIONS +PERMISSION_PHOTOS = PERMISSION_PHOTOS +PERMISSION_REMINDERS = PERMISSION_REMINDERS +PERMISSION_SPEECH_RECOGNIZER = PERMISSION_SPEECH_RECOGNIZER +PERMISSION_MEDIA_LIBRARY = PERMISSION_MEDIA_LIBRARY +PERMISSION_SIRI = PERMISSION_SIRI // Do not modify this line. Instead, remove comments above as needed to enable the categories your app uses. -PERMISSION_FLAGS = $(PERMISSION_ADDRESS_BOOK) $(PERMISSION_BLUETOOTH) $(PERMISSION_CAMERA) $(PERMISSION_CONTACTS) $(PERMISSION_EVENTS) $(PERMISSION_LOCATION) $(PERMISSION_MICROPHONE) $(PERMISSION_MOTION) $(PERMISSION_NOTIFICATIONS) $(PERMISSION_PHOTOS) $(PERMISSION_REMINDERS) $(PERMISSION_SPEECH_RECOGNIZER) $(PERMISSION_MEDIA_LIBRARY) $(PERMISSION_SIRI) +PERMISSION_FLAGS = $(PERMISSION_ADDRESS_BOOK) $(PERMISSION_BLUETOOTH) $(PERMISSION_CAMERA) $(PERMISSION_CONTACTS) $(PERMISSION_EVENTS) $(PERMISSION_LOCATION) $(PERMISSION_MICROPHONE) $(PERMISSION_MOTION) $(PERMISSION_NOTIFICATIONS) $(PERMISSION_USER_NOTIFICATIONS) $(PERMISSION_PHOTOS) $(PERMISSION_REMINDERS) $(PERMISSION_SPEECH_RECOGNIZER) $(PERMISSION_MEDIA_LIBRARY) $(PERMISSION_SIRI) -SWIFT_ACTIVE_COMPILATION_CONDITIONS= $(inherited) $(PERMISSION_FLAGS) +SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(PERMISSION_FLAGS) diff --git a/Source/Permission.swift b/Source/Permission.swift old mode 100644 new mode 100755 index 9ba0aa2..0dfdce6 --- a/Source/Permission.swift +++ b/Source/Permission.swift @@ -21,6 +21,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // +#if PERMISSION_USER_NOTIFICATIONS +import UserNotifications +#endif open class Permission: NSObject { public typealias Callback = (PermissionStatus) -> Void @@ -97,38 +100,57 @@ open class Permission: NSObject { open static let siri = Permission(type: .siri) #endif - #if PERMISSION_NOTIFICATIONS + #if PERMISSION_USER_NOTIFICATIONS + /// Variable used to retain the notifications permission. + @available(iOS 10.0, *) + fileprivate static var _userNotifications: Permission? + /// The permission to send notifications. - open static let notifications: Permission = { - let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil) - return Permission(type: .notifications(settings)) + @available(iOS 10.0, *) + open static let userNotifications: Permission = { + let settings: UNAuthorizationOptions = [.alert, .badge, .sound] + _userNotifications = Permission(type: .userNotifications(settings)) + return _userNotifications! }() + /// The permission to send notifications. + @available(iOS 10.0, *) + open static func userNotifications(options: UNAuthorizationOptions) -> Permission { + _userNotifications = Permission(type: .userNotifications(options)) + return _userNotifications! + } + #endif + + #if PERMISSION_NOTIFICATIONS /// Variable used to retain the notifications permission. fileprivate static var _notifications: Permission? + /// The permission to send notifications. + open static let notifications: Permission = { + let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil) + _notifications = Permission(type: .notifications(settings)) + return _notifications! + }() + /// The permission to send notifications. open static func notifications(types: UIUserNotificationType, categories: Set?) -> Permission { - let settings = UIUserNotificationSettings(types: types, categories: categories) - let permission = Permission(type: .notifications(settings)) - _notifications = permission - return permission + let settings = UIUserNotificationSettings(types: types, categories: categories) + _notifications = Permission(type: .notifications(settings)) + return _notifications! } /// The permission to send notifications. open static func notifications(types: UIUserNotificationType) -> Permission { let settings = UIUserNotificationSettings(types: types, categories: nil) - let permission = Permission(type: .notifications(settings)) - _notifications = permission - return permission + _notifications = Permission(type: .notifications(settings)) + return _notifications! } /// The permission to send notifications. open static func notifications(categories: Set?) -> Permission { let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: categories) - let permission = Permission(type: .notifications(settings)) - _notifications = permission - return permission + _notifications = Permission(type: .notifications(settings)) + return _notifications! } #endif @@ -154,6 +176,10 @@ open class Permission: NSObject { if case .notifications = type { return statusNotifications } #endif + #if PERMISSION_USER_NOTIFICATIONS + if case .userNotifications = type { return statusUserNotifications } + #endif + #if PERMISSION_MICROPHONE if case .microphone = type { return statusMicrophone } #endif @@ -274,7 +300,7 @@ open class Permission: NSObject { #endif #if PERMISSION_LOCATION - if case .locationAlways = type { + if case .locationAlways = type { requestLocationAlways(callback) return } @@ -292,6 +318,13 @@ open class Permission: NSObject { } #endif + #if PERMISSION_USER_NOTIFICATIONS + if case .userNotifications = type { + requestUserNotifications(callback) + return + } + #endif + #if PERMISSION_MICROPHONE if case .microphone = type { requestMicrophone(callback) diff --git a/Source/PermissionType.swift b/Source/PermissionType.swift old mode 100644 new mode 100755 index ba10853..58ed2f6 --- a/Source/PermissionType.swift +++ b/Source/PermissionType.swift @@ -21,6 +21,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // +#if PERMISSION_USER_NOTIFICATIONS +import UserNotifications +#endif public enum PermissionType { #if PERMISSION_CONTACTS @@ -36,8 +39,12 @@ public enum PermissionType { case locationWhenInUse #endif + #if PERMISSION_USER_NOTIFICATIONS + @available(iOS 10.0, *) case userNotifications(UNAuthorizationOptions) + #endif + #if PERMISSION_NOTIFICATIONS - case notifications(UIUserNotificationSettings) + case notifications(UIUserNotificationSettings) // Deprecated in iOS 10.0 #endif #if PERMISSION_MICROPHONE @@ -100,6 +107,10 @@ extension PermissionType: CustomStringConvertible { if case .notifications = self { return "Notifications" } #endif + #if PERMISSION_USER_NOTIFICATIONS + if case .userNotifications = self { return "UserNotifications" } + #endif + #if PERMISSION_MICROPHONE if case .microphone = self { return "Microphone" } #endif diff --git a/Source/PermissionTypes/Notifications.swift b/Source/PermissionTypes/Notifications.swift old mode 100644 new mode 100755 index 8b7bbf5..58fd7bb --- a/Source/PermissionTypes/Notifications.swift +++ b/Source/PermissionTypes/Notifications.swift @@ -23,12 +23,23 @@ // #if PERMISSION_NOTIFICATIONS +import ObjectiveC +private var timerKey: UInt8 = 0 + internal extension Permission { + private var timer: Timer? { + get { + return objc_getAssociatedObject(self, &timerKey) as? Timer + } + set(newValue) { + objc_setAssociatedObject(self, &timerKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN) + } + } + var statusNotifications: PermissionStatus { - if UIApplication.shared.currentUserNotificationSettings?.types.isEmpty == false { + if let settings = UIApplication.shared.currentUserNotificationSettings, settings.types.isEmpty == false { return .authorized } - return UserDefaults.standard.requestedNotifications ? .denied : .notDetermined } @@ -36,16 +47,19 @@ internal extension Permission { guard case .notifications(let settings) = type else { fatalError() } NotificationCenter.default.addObserver(self, selector: #selector(requestingNotifications), name: .UIApplicationWillResignActive) + timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(finishedRequestingNotifications), userInfo: nil, repeats: false) UIApplication.shared.registerUserNotificationSettings(settings) } - @objc func requestingNotifications() { + @objc private dynamic func requestingNotifications() { + timer?.invalidate() + NotificationCenter.default.removeObserver(self, name: .UIApplicationWillResignActive) NotificationCenter.default.addObserver(self, selector: #selector(finishedRequestingNotifications), name: .UIApplicationDidBecomeActive) } - @objc func finishedRequestingNotifications() { + @objc private dynamic func finishedRequestingNotifications() { NotificationCenter.default.removeObserver(self, name: .UIApplicationWillResignActive) NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive) diff --git a/Source/PermissionTypes/UserNotifications.swift b/Source/PermissionTypes/UserNotifications.swift new file mode 100755 index 0000000..aebd28c --- /dev/null +++ b/Source/PermissionTypes/UserNotifications.swift @@ -0,0 +1,56 @@ +// +// UserNotifications.swift +// Permission +// +// Created by Andreas Grauel on 20.01.17. +// Copyright © 2017 delba. All rights reserved. +// + +#if PERMISSION_USER_NOTIFICATIONS +import UserNotifications + +internal extension Permission { + + var statusUserNotifications: PermissionStatus { + guard #available(iOS 10.0, *) else { fatalError() } + return synchronousStatusUserNotifications + } + + func requestUserNotifications(_ callback: @escaping Callback) { + guard #available(iOS 10.0, *) else { fatalError() } + guard case .userNotifications(let settings) = type else { fatalError() } + + var status: PermissionStatus = .notDetermined + UNUserNotificationCenter.current().requestAuthorization(options: settings) { (isGranted, error) in + if error != nil { + status = .denied + } else { + status = isGranted ? .authorized : .denied + } + callback(status) + } + } + + fileprivate var synchronousStatusUserNotifications: PermissionStatus { + guard #available(iOS 10.0, *) else { fatalError() } + let semaphore = DispatchSemaphore(value: 0) + + var status: PermissionStatus = .notDetermined + + UNUserNotificationCenter.current().getNotificationSettings { settings in + switch settings.authorizationStatus { + case .authorized: + status = .authorized + case .denied: + status = .denied + case .notDetermined: + status = .notDetermined + } + semaphore.signal() + } + _ = semaphore.wait(timeout: DispatchTime.distantFuture) + + return status + } +} +#endif From ceeebb71740f25a09b3eb03d177308bf9bdb6a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20Gu=CC=88ndu=CC=88z?= Date: Tue, 7 Feb 2017 15:23:33 +0100 Subject: [PATCH 2/5] Disable button if status is authorized --- Source/PermissionButton.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/PermissionButton.swift b/Source/PermissionButton.swift index 9c61f08..051b0b0 100644 --- a/Source/PermissionButton.swift +++ b/Source/PermissionButton.swift @@ -468,6 +468,8 @@ internal extension PermissionButton { private extension PermissionButton { func render(_ state: UIControlState = .normal) { + self.isEnabled = status != .authorized + if let title = titleForStatus(status, andState: state) { super.setTitle(title, for: state) } From 972ce1d8177e3087f8b5bac2511d5aac47575a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20Gu=CC=88ndu=CC=88z?= Date: Wed, 8 Feb 2017 10:30:50 +0100 Subject: [PATCH 3/5] Add explicit update method to PermissionButton --- Source/PermissionButton.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/PermissionButton.swift b/Source/PermissionButton.swift index 051b0b0..b1f0529 100644 --- a/Source/PermissionButton.swift +++ b/Source/PermissionButton.swift @@ -450,7 +450,15 @@ open class PermissionButton: UIButton { Tells the view that its superview changed. */ open override func didMoveToSuperview() { - render(.normal) + update() + } + + /** + Tells the view that it needs to update. + Use this then an app comes to foreground and you have a PermissionButton on screen. + */ + public func update() { + render() } } From 4779a5b5fd962705f29b438bcc0310b4bcc4c281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20Gu=CC=88ndu=CC=88z?= Date: Wed, 15 Mar 2017 15:30:14 +0100 Subject: [PATCH 4/5] Use render internally to keep update public-only --- Source/PermissionButton.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/PermissionButton.swift b/Source/PermissionButton.swift index b1f0529..1ef7560 100644 --- a/Source/PermissionButton.swift +++ b/Source/PermissionButton.swift @@ -450,7 +450,7 @@ open class PermissionButton: UIButton { Tells the view that its superview changed. */ open override func didMoveToSuperview() { - update() + render() } /** From ec3c64b2290c97f1baa444418706fa2b66deb29d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20Gu=CC=88ndu=CC=88z?= Date: Thu, 14 Sep 2017 11:33:40 +0200 Subject: [PATCH 5/5] Migrate to Xcode 9 and Swift 4 --- Permission.xcodeproj/project.pbxproj | 28 +++++++++++++------ .../xcschemes/Permission.xcscheme | 4 ++- .../xcschemes/PermissionTests.xcscheme | 4 ++- Source/PermissionTypes/Camera.swift | 4 +-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Permission.xcodeproj/project.pbxproj b/Permission.xcodeproj/project.pbxproj index cb445ec..3f9a93c 100755 --- a/Permission.xcodeproj/project.pbxproj +++ b/Permission.xcodeproj/project.pbxproj @@ -241,16 +241,16 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0810; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = delba; TargetAttributes = { 6D86A9B11BEBDC7C00E3DD5A = { CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; 6D86A9BB1BEBDC7D00E3DD5A = { CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 0800; + LastSwiftMigration = 0900; }; }; }; @@ -349,14 +349,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -401,14 +407,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -450,13 +462,12 @@ GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INFOPLIST_FILE = "Source/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.delba.Permission; PRODUCT_NAME = Permission; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -472,13 +483,12 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Source/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.delba.Permission; PRODUCT_NAME = Permission; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -490,7 +500,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.delba.PermissionTests; PRODUCT_NAME = Permission; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -503,7 +513,7 @@ PRODUCT_BUNDLE_IDENTIFIER = io.delba.PermissionTests; PRODUCT_NAME = Permission; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Permission.xcodeproj/xcshareddata/xcschemes/Permission.xcscheme b/Permission.xcodeproj/xcshareddata/xcschemes/Permission.xcscheme index 240e14c..b68cab0 100644 --- a/Permission.xcodeproj/xcshareddata/xcschemes/Permission.xcscheme +++ b/Permission.xcodeproj/xcshareddata/xcschemes/Permission.xcscheme @@ -1,6 +1,6 @@