diff --git a/Package.swift b/Package.swift index b7f729f..551703e 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,28 @@ +// swift-tools-version:5.1 +// The swift-tools-version declares the minimum version of Swift required to build this package. + import PackageDescription let package = Package( - name: "arek" + name: "arek", + platforms: [.iOS(.v11)], + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "arek", + targets: ["arek"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "arek", + dependencies: [], + path: "code/Classes"), + ], + swiftLanguageVersions: [.v5] ) diff --git a/arek.xcodeproj/project.pbxproj b/arek.xcodeproj/project.pbxproj index f0b7463..82db980 100644 --- a/arek.xcodeproj/project.pbxproj +++ b/arek.xcodeproj/project.pbxproj @@ -3,15 +3,13 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 6BB101BA1E7044BA000CA36F /* arek.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BB101B81E7044BA000CA36F /* arek.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6BB101E31E70450B000CA36F /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 6BB101C11E70450B000CA36F /* .gitkeep */; }; 6BB101E41E70450B000CA36F /* arek.png in Resources */ = {isa = PBXBuildFile; fileRef = 6BB101C21E70450B000CA36F /* arek.png */; }; 6BB101E51E70450B000CA36F /* arek_contacts.png in Resources */ = {isa = PBXBuildFile; fileRef = 6BB101C31E70450B000CA36F /* arek_contacts.png */; }; - 6BB101E61E70450B000CA36F /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 6BB101C51E70450B000CA36F /* .gitkeep */; }; 6BB101E71E70450B000CA36F /* Arek.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101C71E70450B000CA36F /* Arek.swift */; }; 6BB101E81E70450B000CA36F /* ArekConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101C91E70450B000CA36F /* ArekConfiguration.swift */; }; 6BB101E91E70450B000CA36F /* ArekLocalizationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101CA1E70450B000CA36F /* ArekLocalizationManager.swift */; }; @@ -36,6 +34,7 @@ 6BB101FC1E70450B000CA36F /* ArekBaseLocationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101E01E70450B000CA36F /* ArekBaseLocationDelegate.swift */; }; 6BB101FD1E70450B000CA36F /* ArekLocationAlways.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101E11E70450B000CA36F /* ArekLocationAlways.swift */; }; 6BB101FE1E70450B000CA36F /* ArekLocationWhenInUse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BB101E21E70450B000CA36F /* ArekLocationWhenInUse.swift */; }; + AA29FA3C25886A00002582F5 /* ArekPopupStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA29FA3B25886A00002582F5 /* ArekPopupStyle.swift */; }; B6999B072154994A00E5D92A /* ArekSiri.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6999B062154994A00E5D92A /* ArekSiri.swift */; }; /* End PBXBuildFile section */ @@ -71,6 +70,7 @@ 6BB101E01E70450B000CA36F /* ArekBaseLocationDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArekBaseLocationDelegate.swift; sourceTree = ""; }; 6BB101E11E70450B000CA36F /* ArekLocationAlways.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArekLocationAlways.swift; sourceTree = ""; }; 6BB101E21E70450B000CA36F /* ArekLocationWhenInUse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArekLocationWhenInUse.swift; sourceTree = ""; }; + AA29FA3B25886A00002582F5 /* ArekPopupStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArekPopupStyle.swift; sourceTree = ""; }; B6999B062154994A00E5D92A /* ArekSiri.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArekSiri.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -151,6 +151,7 @@ 6BB101CB1E70450B000CA36F /* ArekPermissionFrequency.swift */, 6BB101CC1E70450B000CA36F /* ArekPermissionStatus.swift */, 6BB101CD1E70450B000CA36F /* ArekPopupData.swift */, + AA29FA3B25886A00002582F5 /* ArekPopupStyle.swift */, ); path = Utilities; sourceTree = ""; @@ -235,7 +236,8 @@ 6BB101AC1E7044BA000CA36F /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0820; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1500; ORGANIZATIONNAME = "Ennio Masi"; TargetAttributes = { 6BB101B41E7044BA000CA36F = { @@ -246,10 +248,11 @@ }; buildConfigurationList = 6BB101AF1E7044BA000CA36F /* Build configuration list for PBXProject "arek" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 6BB101AB1E7044BA000CA36F; productRefGroup = 6BB101B61E7044BA000CA36F /* Products */; @@ -268,8 +271,6 @@ files = ( 6BB101E51E70450B000CA36F /* arek_contacts.png in Resources */, 6BB101E41E70450B000CA36F /* arek.png in Resources */, - 6BB101E31E70450B000CA36F /* .gitkeep in Resources */, - 6BB101E61E70450B000CA36F /* .gitkeep in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -301,6 +302,7 @@ 6BB101EB1E70450B000CA36F /* ArekPermissionStatus.swift in Sources */, 6BB101FC1E70450B000CA36F /* ArekBaseLocationDelegate.swift in Sources */, 6BB101F21E70450B000CA36F /* ArekMediaLibrary.swift in Sources */, + AA29FA3C25886A00002582F5 /* ArekPopupStyle.swift in Sources */, 6BB101EF1E70450B000CA36F /* ArekContacts.swift in Sources */, B6999B072154994A00E5D92A /* ArekSiri.swift in Sources */, 6BB101FB1E70450B000CA36F /* ArekBaseLocation.swift in Sources */, @@ -315,20 +317,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 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_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + 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; @@ -338,7 +351,8 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/Carthage/Build/iOS/**"; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + FRAMEWORK_SEARCH_PATHS = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -353,7 +367,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -369,20 +383,31 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 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_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + 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; @@ -392,7 +417,8 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/Carthage/Build/iOS/**"; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + FRAMEWORK_SEARCH_PATHS = ""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -401,10 +427,11 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -420,13 +447,21 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; INFOPLIST_FILE = arek/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = ennioma.arek; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -438,13 +473,21 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; INFOPLIST_FILE = arek/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu99 gnu++11"; PRODUCT_BUNDLE_IDENTIFIER = ennioma.arek; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; diff --git a/arek.xcodeproj/xcshareddata/xcschemes/arek.xcscheme b/arek.xcodeproj/xcshareddata/xcschemes/arek.xcscheme index 6a4e672..81d6dec 100644 --- a/arek.xcodeproj/xcshareddata/xcschemes/arek.xcscheme +++ b/arek.xcodeproj/xcshareddata/xcschemes/arek.xcscheme @@ -1,6 +1,6 @@ - - - - Void -public protocol ArekPermissionProtocol: class { +public protocol ArekPermissionProtocol: AnyObject { var identifier: String { get } /** This is the key method to know if a permission has been authorized or denied. @@ -51,6 +49,11 @@ public protocol ArekPermissionProtocol: class { func askForPermission(completion: @escaping ArekPermissionResponse) } +public protocol ArekCustomPopupProtocol: AnyObject { + func presentInitialCustomPopup(permission: ArekPermissionProtocol, title: String, message: String, allowButtonTitle: String, denyButtonTitle: String, completion: @escaping ArekPermissionResponse) + func presentReEnableCustomPopup(permission: ArekPermissionProtocol, title: String, message: String, allowButtonTitle: String, denyButtonTitle: String, openSettngs: @escaping () -> Void) +} + /** ArekBasePermission is a root class and each permission inherit from it. @@ -60,6 +63,7 @@ open class ArekBasePermission { var configuration: ArekConfiguration = ArekConfiguration(frequency: .Always, presentInitialPopup: true, presentReEnablePopup: true) var initialPopupData: ArekPopupData = ArekPopupData() var reEnablePopupData: ArekPopupData = ArekPopupData() + open var delegate: ArekCustomPopupProtocol? public init(identifier: String) { let data = ArekLocalizationManager(permission: identifier) @@ -119,173 +123,49 @@ open class ArekBasePermission { completion: @escaping ArekPermissionResponse) { switch self.initialPopupData.type as ArekPopupType { - case .codeido: - self.presentInitialCodeidoPopup(title: title, - message: message, - image: image!, - allowButtonTitle: allowButtonTitle, - denyButtonTitle: denyButtonTitle, - styling: styling, - completion: completion) - break case .native: self.presentInitialNativePopup(title: title, message: message, allowButtonTitle: allowButtonTitle, denyButtonTitle: denyButtonTitle, completion: completion) - break - } - } - - private func presentInitialCodeidoPopup(title: String, - message: String, - image: String, - allowButtonTitle: String, - denyButtonTitle: String, - styling: ArekPopupStyle?, - completion: @escaping ArekPermissionResponse) { - - let alertVC = PMAlertController(title: title, - description: message, - image: UIImage(named: image), - style: .walkthrough) - - let denyAction = PMAlertAction(title: denyButtonTitle, style: .cancel, action: { - completion(.denied) - alertVC.dismiss(animated: true, completion: nil) - }) - - let allowAction = PMAlertAction(title: allowButtonTitle, style: .default, action: { - (self as? ArekPermissionProtocol)?.askForPermission(completion: completion) - alertVC.dismiss(animated: true, completion: nil) - }) - - self.apply(styling, to: alertVC, with: message) - self.apply(styling, to: denyAction, and: allowAction) - - alertVC.addAction(denyAction) - alertVC.addAction(allowAction) - - if var topController = UIApplication.shared.keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController - } - + case .custom: DispatchQueue.main.async { - topController.present(alertVC, animated: true, completion: nil) + self.delegate?.presentInitialCustomPopup(permission: self as! ArekPermissionProtocol, title: title, message: message, allowButtonTitle: allowButtonTitle, denyButtonTitle: denyButtonTitle, completion: completion) } } } - private func apply(_ styling: ArekPopupStyle?, to denyAction: PMAlertAction, and allowAction: PMAlertAction) { - guard let styling = styling else { - return - } - - if let denyButtonTitleColor = styling.denyButtonTitleColor { - denyAction.setTitleColor(denyButtonTitleColor, for: .normal) - } - if let denyButtonTitleFont = styling.denyButtonTitleFont { - denyAction.titleLabel?.font = denyButtonTitleFont - } - if let allowButtonTitleColor = styling.allowButtonTitleColor { - allowAction.setTitleColor(allowButtonTitleColor, for: .normal) - } - if let allowButtonTitleFont = styling.allowButtonTitleFont { - allowAction.titleLabel?.font = allowButtonTitleFont - } - - } - - private func apply(_ styling: ArekPopupStyle?, to alertVC: PMAlertController, with message: String) { - guard let styling = styling else { - return - } - - if let cornerRadius = styling.cornerRadius { - alertVC.view.layer.cornerRadius = cornerRadius - } - if let alertMaskBackgroundColor = styling.maskBackgroundColor { - alertVC.alertMaskBackground.backgroundColor = alertMaskBackgroundColor - } - if let alertMaskBackgroundAlpha = styling.maskBackgroundAlpha { - alertVC.alertMaskBackground.alpha = alertMaskBackgroundAlpha - } - if let alertTitleTextColor = styling.titleTextColor { - alertVC.alertTitle.textColor = alertTitleTextColor - } - if let alertTitleFont = styling.titleFont { - alertVC.alertTitle.font = alertTitleFont - } - if let alertDescriptionFont = styling.descriptionFont { - alertVC.alertDescription.font = alertDescriptionFont - } - if let headerViewHeightConstraint = styling.headerViewHeightConstraint { - alertVC.headerViewHeightConstraint.constant = headerViewHeightConstraint - } - if let headerViewTopSpace = styling.headerViewTopSpace { - alertVC.headerViewTopSpaceConstraint.constant = headerViewTopSpace - } - if let alertDescriptionLeftSpace = styling.descriptionLeftSpace { - alertVC.alertContentStackViewLeadingConstraint.constant = alertDescriptionLeftSpace - } - if let alertDescriptionRightSpace = styling.descriptionRightSpace { - alertVC.alertContentStackViewTrailingConstraint.constant = alertDescriptionRightSpace - } - if let alertDescriptionTopSpace = styling.descriptionTopSpace { - alertVC.alertContentStackViewTopConstraint.constant = alertDescriptionTopSpace - } - if let alertButtonsLeftSpace = styling.buttonsLeftSpace { - alertVC.alertActionStackViewLeadingConstraint.constant = alertButtonsLeftSpace - } - if let alertButtonsRightSpace = styling.buttonsRightSpace { - alertVC.alertActionStackViewTrailingConstraint.constant = alertButtonsRightSpace - } - if let alertButtonsTopSpace = styling.buttonsTopSpace { - alertVC.alertActionStackViewTopConstraint.constant = alertButtonsTopSpace - } - if let alertButtonsBottomSpace = styling.buttonsBottomSpace { - alertVC.alertActionStackViewBottomConstraint.constant = alertButtonsBottomSpace - } - - if let alertDescriptionLineHeight = styling.descriptionLineHeight { - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.lineSpacing = alertDescriptionLineHeight - let attrString = NSMutableAttributedString(string: message) - attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length)) - alertVC.alertDescription.attributedText = attrString - } - } - private func presentInitialNativePopup(title: String, message: String, allowButtonTitle: String, denyButtonTitle: String, completion: @escaping ArekPermissionResponse) { - - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - - let allow = UIAlertAction(title: allowButtonTitle, style: .default) { _ in - (self as? ArekPermissionProtocol)?.askForPermission(completion: completion) - alert.dismiss(animated: true, completion: nil) - } - - let deny = UIAlertAction(title: denyButtonTitle, style: .cancel) { _ in - completion(.denied) - alert.dismiss(animated: true, completion: nil) - } - - alert.addAction(deny) - alert.addAction(allow) - - if var topController = UIApplication.shared.keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController + DispatchQueue.main.async { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) + + let allow = UIAlertAction(title: allowButtonTitle, style: .default) { _ in + (self as? ArekPermissionProtocol)?.askForPermission(completion: completion) + alert.dismiss(animated: true, completion: nil) + } + + let deny = UIAlertAction(title: denyButtonTitle, style: .cancel) { _ in + completion(.denied) + alert.dismiss(animated: true, completion: nil) } + + alert.addAction(deny) + alert.addAction(allow) + alert.preferredAction = allow + + if var topController = UIApplication.shared.keyWindow?.rootViewController { + while let presentedViewController = topController.presentedViewController { + topController = presentedViewController + } - DispatchQueue.main.async { - topController.present(alert, animated: true, completion: nil) + DispatchQueue.main.async { + topController.present(alert, animated: true, completion: nil) + } } } } @@ -311,19 +191,15 @@ open class ArekBasePermission { denyButtonTitle: String) { switch self.reEnablePopupData.type as ArekPopupType { - case .codeido: - self.presentReEnableCodeidoPopup(title: title, - message: message, - image: image!, - allowButtonTitle: allowButtonTitle, - denyButtonTitle: denyButtonTitle) - break case .native: self.presentReEnableNativePopup(title: title, message: message, allowButtonTitle: allowButtonTitle, denyButtonTitle: denyButtonTitle) - break + case .custom: + DispatchQueue.main.async { + self.delegate?.presentReEnableCustomPopup(permission: self as! ArekPermissionProtocol, title: title, message: message, allowButtonTitle: allowButtonTitle, denyButtonTitle: denyButtonTitle, openSettngs: self.openSettingsURL) + } } } @@ -331,67 +207,35 @@ open class ArekBasePermission { message: String, allowButtonTitle: String, denyButtonTitle: String) { - - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - - let allow = UIAlertAction(title: allowButtonTitle, style: .default) { _ in - alert.dismiss(animated: true, completion: nil) + DispatchQueue.main.async { + let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - guard let url = URL(string: UIApplication.openSettingsURLString) else { return } - if #available(iOS 10.0, *) { - UIApplication.shared.open(url, options: [:], completionHandler: nil) - } else { - UIApplication.shared.openURL(url) + let allow = UIAlertAction(title: allowButtonTitle, style: .default) { _ in + alert.dismiss(animated: true, completion: nil) + self.openSettingsURL() } - } - - let deny = UIAlertAction(title: denyButtonTitle, style: .cancel) { _ in - alert.dismiss(animated: true, completion: nil) - } - - alert.addAction(deny) - alert.addAction(allow) - - if var topController = UIApplication.shared.keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController + + let deny = UIAlertAction(title: denyButtonTitle, style: .cancel) { _ in + alert.dismiss(animated: true, completion: nil) } - topController.present(alert, animated: true, completion: nil) + alert.addAction(deny) + alert.addAction(allow) + alert.preferredAction = allow + + if var topController = UIApplication.shared.keyWindow?.rootViewController { + while let presentedViewController = topController.presentedViewController { + topController = presentedViewController + } + + topController.present(alert, animated: true, completion: nil) + } } - } - private func presentReEnableCodeidoPopup(title: String, - message: String, - image: String, - allowButtonTitle: String, - denyButtonTitle: String) { - - let alertVC = PMAlertController(title: title, description: message, image: UIImage(named: image), style: .walkthrough) - - alertVC.addAction(PMAlertAction(title: denyButtonTitle, style: .cancel, action: { - alertVC.dismiss(animated: true, completion: nil) - })) - - alertVC.addAction(PMAlertAction(title: allowButtonTitle, style: .default, action: { - alertVC.dismiss(animated: true, completion: nil) - guard let url = URL(string: UIApplication.openSettingsURLString) else { return } - - if #available(iOS 10.0, *) { - UIApplication.shared.open(url, options: [:], completionHandler: nil) - } else { - UIApplication.shared.openURL(url) - } - })) - - if var topController = UIApplication.shared.keyWindow?.rootViewController { - while let presentedViewController = topController.presentedViewController { - topController = presentedViewController - } - - topController.present(alertVC, animated: true, completion: nil) - } + private func openSettingsURL() { + guard let url = URL(string: UIApplication.openSettingsURLString) else { return } + UIApplication.shared.open(url, options: [:], completionHandler: nil) } open func manage(completion: @escaping ArekPermissionResponse) { @@ -412,6 +256,10 @@ open class ArekBasePermission { return completion(.authorized) case .notAvailable: break + case .limited: + return completion(.limited) + case .unknown: + return completion(.unknown) } } } diff --git a/code/Classes/Core/Utilities/ArekPermissionStatus.swift b/code/Classes/Core/Utilities/ArekPermissionStatus.swift index 9e61a93..30e67d5 100644 --- a/code/Classes/Core/Utilities/ArekPermissionStatus.swift +++ b/code/Classes/Core/Utilities/ArekPermissionStatus.swift @@ -30,4 +30,6 @@ public enum ArekPermissionStatus: String { case denied case notDetermined case notAvailable + case limited + case unknown } diff --git a/code/Classes/Core/Utilities/ArekPopupData.swift b/code/Classes/Core/Utilities/ArekPopupData.swift index a889fd5..100fdbb 100644 --- a/code/Classes/Core/Utilities/ArekPopupData.swift +++ b/code/Classes/Core/Utilities/ArekPopupData.swift @@ -26,8 +26,8 @@ import Foundation public enum ArekPopupType { - case codeido case native + case custom } public struct ArekPopupData { @@ -44,7 +44,7 @@ public struct ArekPopupData { image: String = "", allowButtonTitle: String = "", denyButtonTitle: String = "", - type: ArekPopupType = .codeido, + type: ArekPopupType = .native, styling: ArekPopupStyle? = nil) { self.title = title diff --git a/code/Classes/Core/Utilities/ArekPopupStyle.swift b/code/Classes/Core/Utilities/ArekPopupStyle.swift index 491d492..3017b01 100644 --- a/code/Classes/Core/Utilities/ArekPopupStyle.swift +++ b/code/Classes/Core/Utilities/ArekPopupStyle.swift @@ -23,7 +23,7 @@ // THE SOFTWARE. // -import Foundation +import UIKit public struct ArekPopupStyle { var cornerRadius: CGFloat? diff --git a/code/Classes/Permissions/ArekCamera.swift b/code/Classes/Permissions/ArekCamera.swift index d54df1a..709a952 100644 --- a/code/Classes/Permissions/ArekCamera.swift +++ b/code/Classes/Permissions/ArekCamera.swift @@ -45,6 +45,8 @@ open class ArekCamera: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case .authorized: return completion(.authorized) + @unknown default: + return completion(.unknown) } } diff --git a/code/Classes/Permissions/ArekCloudKit.swift b/code/Classes/Permissions/ArekCloudKit.swift index 921b5ea..4c22434 100644 --- a/code/Classes/Permissions/ArekCloudKit.swift +++ b/code/Classes/Permissions/ArekCloudKit.swift @@ -38,7 +38,7 @@ open class ArekCloudKit: ArekBasePermission, ArekPermissionProtocol { } open func status(completion: @escaping ArekPermissionResponse) { - CKContainer.default().status(forApplicationPermission: CKContainer_Application_Permissions.userDiscoverability, completionHandler: { applicationPermissionStatus, error in + CKContainer.default().status(forApplicationPermission: CKContainer.ApplicationPermissions.userDiscoverability, completionHandler: { applicationPermissionStatus, error in if error != nil { return completion(.notDetermined) @@ -53,6 +53,8 @@ open class ArekCloudKit: ArekBasePermission, ArekPermissionProtocol { return completion(.notDetermined) case .initialState: return completion(.notDetermined) + @unknown default: + return completion(.unknown) } }) @@ -67,7 +69,7 @@ open class ArekCloudKit: ArekBasePermission, ArekPermissionProtocol { switch accountStatus { case .available, .restricted: - CKContainer.default().requestApplicationPermission(CKContainer_Application_Permissions.userDiscoverability, completionHandler: { applicationPermissionStatus, error in + CKContainer.default().requestApplicationPermission(CKContainer.ApplicationPermissions.userDiscoverability, completionHandler: { applicationPermissionStatus, error in if let error = error { print("[🚨 Arek 🚨] ☁️ discoverability not determined 🤔 error: \(error)") return completion(.notDetermined) @@ -82,6 +84,8 @@ open class ArekCloudKit: ArekBasePermission, ArekPermissionProtocol { return completion(.authorized) case .couldNotComplete, .initialState: return completion(.notDetermined) + @unknown default: + return completion(.unknown) } }) case .noAccount: @@ -90,6 +94,10 @@ open class ArekCloudKit: ArekBasePermission, ArekPermissionProtocol { case .couldNotDetermine: print("[🚨 Arek 🚨] ☁️ account not determined 🤔") return completion(.notDetermined) + case .temporarilyUnavailable: + return completion(.notAvailable) + @unknown default: + return completion(.unknown) } } } diff --git a/code/Classes/Permissions/ArekContacts.swift b/code/Classes/Permissions/ArekContacts.swift index 41ed6f3..7c33533 100644 --- a/code/Classes/Permissions/ArekContacts.swift +++ b/code/Classes/Permissions/ArekContacts.swift @@ -45,6 +45,8 @@ open class ArekContacts: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case .notDetermined: return completion(.notDetermined) + @unknown default: + return completion(.unknown) } } diff --git a/code/Classes/Permissions/ArekEvents.swift b/code/Classes/Permissions/ArekEvents.swift index eea69b6..9f7f70b 100644 --- a/code/Classes/Permissions/ArekEvents.swift +++ b/code/Classes/Permissions/ArekEvents.swift @@ -46,6 +46,12 @@ open class ArekEvents: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case .notDetermined: return completion(.notDetermined) + case .fullAccess: + return completion(.authorized) + case .writeOnly: + return completion(.limited) + @unknown default: + return completion(.unknown) } } diff --git a/code/Classes/Permissions/ArekHealth.swift b/code/Classes/Permissions/ArekHealth.swift index 324d1fd..8f66636 100644 --- a/code/Classes/Permissions/ArekHealth.swift +++ b/code/Classes/Permissions/ArekHealth.swift @@ -28,12 +28,10 @@ import HealthKit open class ArekHealth: ArekBasePermission, ArekPermissionProtocol { public struct ArekHealthConfiguration { - public var hkObjectType: HKObjectType? public var hkSampleTypesToShare: Set? public var hkSampleTypesToRead: Set? - public init(hkObjectType: HKObjectType? = nil, hkSampleTypesToShare: Set? = nil, hkSampleTypesToRead: Set? = nil) { - self.hkObjectType = hkObjectType + public init(hkSampleTypesToShare: Set? = nil, hkSampleTypesToRead: Set? = nil) { self.hkSampleTypesToShare = hkSampleTypesToShare self.hkSampleTypesToRead = hkSampleTypesToRead } @@ -59,17 +57,22 @@ open class ArekHealth: ArekBasePermission, ArekPermissionProtocol { } open func status(completion: @escaping ArekPermissionResponse) { - guard let objectType = self.healthConfiguration?.hkObjectType else { - return completion(.notDetermined) - } - - switch HKHealthStore().authorizationStatus(for: objectType) { - case .notDetermined: - return completion(.notDetermined) - case .sharingDenied: - return completion(.denied) - case .sharingAuthorized: - return completion(.authorized) + HKHealthStore().getRequestStatusForAuthorization(toShare: self.healthConfiguration?.hkSampleTypesToShare ?? Set(), read: self.healthConfiguration?.hkSampleTypesToRead ?? Set()) { status, error in + DispatchQueue.main.async { + guard error == nil else { + completion(.unknown) + return + } + switch status { + case .unnecessary: + // The application has already requested authorization for all the specified data types. But authorization status could be authorized, limited or denied. + completion(.authorized) + case .shouldRequest: + completion(.notDetermined) + default: + return completion(.unknown) + } + } } } diff --git a/code/Classes/Permissions/ArekMediaLibrary.swift b/code/Classes/Permissions/ArekMediaLibrary.swift index d29cfd4..ae1249a 100644 --- a/code/Classes/Permissions/ArekMediaLibrary.swift +++ b/code/Classes/Permissions/ArekMediaLibrary.swift @@ -38,39 +38,34 @@ open class ArekMediaLibrary: ArekBasePermission, ArekPermissionProtocol { } open func status(completion: @escaping ArekPermissionResponse) { - if #available(iOS 9.3, *) { - let status = MPMediaLibrary.authorizationStatus() + let status = MPMediaLibrary.authorizationStatus() + switch status { + case .authorized: + return completion(.authorized) + case .restricted, .denied: + return completion(.denied) + case .notDetermined: + return completion(.notDetermined) + @unknown default: + return completion(.unknown) + } + } + + open func askForPermission(completion: @escaping ArekPermissionResponse) { + MPMediaLibrary.requestAuthorization { status in switch status { case .authorized: + print("[🚨 Arek 🚨] 💽 permission authorized by user ✅") return completion(.authorized) case .restricted, .denied: + print("[🚨 Arek 🚨] 💽 permission denied by user ⛔️") return completion(.denied) case .notDetermined: + print("[🚨 Arek 🚨] 💽 permission not determined 🤔") return completion(.notDetermined) + @unknown default: + return completion(.unknown) } - } else { - return completion(.notAvailable) - } - } - - open func askForPermission(completion: @escaping ArekPermissionResponse) { - if #available(iOS 9.3, *) { - MPMediaLibrary.requestAuthorization { status in - switch status { - case .authorized: - print("[🚨 Arek 🚨] 💽 permission authorized by user ✅") - return completion(.authorized) - case .restricted, .denied: - print("[🚨 Arek 🚨] 💽 permission denied by user ⛔️") - return completion(.denied) - case .notDetermined: - print("[🚨 Arek 🚨] 💽 permission not determined 🤔") - return completion(.notDetermined) - } - } - } else { - print("[🚨 Arek 🚨] 💽 permission denied by iOS ⛔️") - return completion(.notAvailable) } } } diff --git a/code/Classes/Permissions/ArekMicrophone.swift b/code/Classes/Permissions/ArekMicrophone.swift index ed997f4..2850b7c 100644 --- a/code/Classes/Permissions/ArekMicrophone.swift +++ b/code/Classes/Permissions/ArekMicrophone.swift @@ -46,6 +46,8 @@ open class ArekMicrophone: ArekBasePermission, ArekPermissionProtocol { return completion(.notDetermined) case AVAudioSession.RecordPermission.granted: return completion(.authorized) + @unknown default: + return completion(.unknown) } } diff --git a/code/Classes/Permissions/ArekMotion.swift b/code/Classes/Permissions/ArekMotion.swift index 46dd6fe..5ce83fe 100644 --- a/code/Classes/Permissions/ArekMotion.swift +++ b/code/Classes/Permissions/ArekMotion.swift @@ -44,7 +44,7 @@ open class ArekMotion: ArekBasePermission, ArekPermissionProtocol { return .notDetermined } set { - UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: newValue.rawValue), forKey: userKey) + try? UserDefaults.standard.set(NSKeyedArchiver.archivedData(withRootObject: newValue.rawValue, requiringSecureCoding: true), forKey: userKey) UserDefaults.standard.synchronize() } } diff --git a/code/Classes/Permissions/ArekNotifications.swift b/code/Classes/Permissions/ArekNotifications.swift index 78750d8..8364087 100644 --- a/code/Classes/Permissions/ArekNotifications.swift +++ b/code/Classes/Permissions/ArekNotifications.swift @@ -48,61 +48,43 @@ open class ArekNotifications: ArekBasePermission, ArekPermissionProtocol { } open func status(completion: @escaping ArekPermissionResponse) { - if #available(iOS 10.0, *) { - UNUserNotificationCenter.current().getNotificationSettings { (settings) in - switch settings.authorizationStatus { - case .notDetermined: - return completion(.notDetermined) - case .denied: - return completion(.denied) - case .authorized, - .provisional: - return completion(.authorized) - } - } - } else if #available(iOS 9.0, *) { - if let types = UIApplication.shared.currentUserNotificationSettings?.types { - if types.isEmpty { - return completion(.notDetermined) - } + UNUserNotificationCenter.current().getNotificationSettings { (settings) in + switch settings.authorizationStatus { + case .notDetermined: + return completion(.notDetermined) + case .denied: + return completion(.denied) + case .authorized, + .provisional: + return completion(.authorized) + case .ephemeral: + return completion(.limited) + @unknown default: + return completion(.unknown) } - - return completion(.authorized) } } open func askForPermission(completion: @escaping ArekPermissionResponse) { - if #available(iOS 10.0, *) { + var options: UNAuthorizationOptions = [.alert, .badge, .sound] - var options: UNAuthorizationOptions = [.alert, .badge, .sound] - - if let wantedOptions = self.wantedNotificationTypes as? UNAuthorizationOptions { - options = wantedOptions - } - - UNUserNotificationCenter.current().requestAuthorization(options: options) { (granted, error) in - if let error = error { - print("[🚨 Arek 🚨] Push notifications permission not determined 🤔, error: \(error)") - return completion(.notDetermined) - } - if granted { - self.registerForRemoteNotifications() + if let wantedOptions = self.wantedNotificationTypes as? UNAuthorizationOptions { + options = wantedOptions + } - print("[🚨 Arek 🚨] Push notifications permission authorized by user ✅") - return completion(.authorized) - } - print("[🚨 Arek 🚨] Push notifications permission denied by user ⛔️") - return completion(.denied) + UNUserNotificationCenter.current().requestAuthorization(options: options) { (granted, error) in + if let error = error { + print("[🚨 Arek 🚨] Push notifications permission not determined 🤔, error: \(error)") + return completion(.notDetermined) } - } else if #available(iOS 9.0, *) { - var options: UIUserNotificationType = [.alert, .badge, .sound] + if granted { + self.registerForRemoteNotifications() - if let wantedOptions = self.wantedNotificationTypes as? UIUserNotificationType { - options = wantedOptions + print("[🚨 Arek 🚨] Push notifications permission authorized by user ✅") + return completion(.authorized) } - - UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: options, categories: nil)) - self.registerForRemoteNotifications() + print("[🚨 Arek 🚨] Push notifications permission denied by user ⛔️") + return completion(.denied) } } diff --git a/code/Classes/Permissions/ArekPhoto.swift b/code/Classes/Permissions/ArekPhoto.swift index 9dfc32c..7825be0 100644 --- a/code/Classes/Permissions/ArekPhoto.swift +++ b/code/Classes/Permissions/ArekPhoto.swift @@ -45,6 +45,10 @@ open class ArekPhoto: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case.authorized: return completion(.authorized) + case .limited: + return completion(.limited) + @unknown default: + return completion(.unknown) } } @@ -60,6 +64,10 @@ open class ArekPhoto: ArekBasePermission, ArekPermissionProtocol { case.authorized: print("[🚨 Arek 🚨] 🌅 permission authorized by user ✅") return completion(.authorized) + case .limited: + return completion(.limited) + @unknown default: + return completion(.unknown) } } } diff --git a/code/Classes/Permissions/ArekReminders.swift b/code/Classes/Permissions/ArekReminders.swift index 372bfc1..01bc644 100644 --- a/code/Classes/Permissions/ArekReminders.swift +++ b/code/Classes/Permissions/ArekReminders.swift @@ -46,6 +46,12 @@ open class ArekReminders: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case .notDetermined: return completion(.notDetermined) + case .fullAccess: + return completion(.authorized) + case .writeOnly: + return completion(.limited) + @unknown default: + return completion(.unknown) } } diff --git a/code/Classes/Permissions/ArekSiri.swift b/code/Classes/Permissions/ArekSiri.swift index fa24fc9..1c57df0 100644 --- a/code/Classes/Permissions/ArekSiri.swift +++ b/code/Classes/Permissions/ArekSiri.swift @@ -45,6 +45,8 @@ open class ArekSiri: ArekBasePermission, ArekPermissionProtocol { return completion(.denied) case .notDetermined: return completion(.notDetermined) + @unknown default: + return completion(.unknown) } } @@ -60,6 +62,8 @@ open class ArekSiri: ArekBasePermission, ArekPermissionProtocol { case.authorized: print("[🚨 Arek 🚨] 🎤 permission authorized by user ✅") return completion(.authorized) + @unknown default: + return completion(.unknown) } } } diff --git a/code/Classes/Permissions/ArekSpeechRecognizer.swift b/code/Classes/Permissions/ArekSpeechRecognizer.swift index 2994d70..8d7f00d 100644 --- a/code/Classes/Permissions/ArekSpeechRecognizer.swift +++ b/code/Classes/Permissions/ArekSpeechRecognizer.swift @@ -38,39 +38,34 @@ open class ArekSpeechRecognizer: ArekBasePermission, ArekPermissionProtocol { } open func status(completion: @escaping ArekPermissionResponse) { - if #available(iOS 10.0, *) { - let status = SFSpeechRecognizer.authorizationStatus() + let status = SFSpeechRecognizer.authorizationStatus() + switch status { + case .authorized: + return completion(.authorized) + case .restricted, .denied: + return completion(.denied) + case .notDetermined: + return completion(.notDetermined) + @unknown default: + return completion(.unknown) + } + } + + open func askForPermission(completion: @escaping ArekPermissionResponse) { + SFSpeechRecognizer.requestAuthorization { status in switch status { case .authorized: + print("[🚨 Arek 🚨] 🗣 permission authorized by user ✅") return completion(.authorized) case .restricted, .denied: + print("[🚨 Arek 🚨] 🗣 permission denied by user ⛔️") return completion(.denied) case .notDetermined: + print("[🚨 Arek 🚨] 🗣 permission not determined 🤔") return completion(.notDetermined) + @unknown default: + return completion(.unknown) } - } else { - return completion(.notAvailable) - } - } - - open func askForPermission(completion: @escaping ArekPermissionResponse) { - if #available(iOS 10.0, *) { - SFSpeechRecognizer.requestAuthorization { status in - switch status { - case .authorized: - print("[🚨 Arek 🚨] 🗣 permission authorized by user ✅") - return completion(.authorized) - case .restricted, .denied: - print("[🚨 Arek 🚨] 🗣 permission denied by user ⛔️") - return completion(.denied) - case .notDetermined: - print("[🚨 Arek 🚨] 🗣 permission not determined 🤔") - return completion(.notDetermined) - } - } - } else { - print("[🚨 Arek 🚨] 🗣 permission only available from iOS 10 ⛔️") - return completion(.notAvailable) } } } diff --git a/code/Classes/Permissions/Bluetooth/ArekBluetooth.swift b/code/Classes/Permissions/Bluetooth/ArekBluetooth.swift index fe7078f..19542f9 100644 --- a/code/Classes/Permissions/Bluetooth/ArekBluetooth.swift +++ b/code/Classes/Permissions/Bluetooth/ArekBluetooth.swift @@ -53,7 +53,11 @@ open class ArekBluetooth: ArekBasePermission, ArekPermissionProtocol { return completion(.notAvailable) case .unknown: return completion(.notDetermined) + @unknown default: + return completion(.unknown) } + @unknown default: + return completion(.unknown) } } @@ -74,6 +78,8 @@ open class ArekBluetooth: ArekBasePermission, ArekPermissionProtocol { bluetooth.bluetoothManager?.startAdvertising(nil) bluetooth.bluetoothManager?.stopAdvertising() break + @unknown default: + return completion(.unknown) } } } diff --git a/code/Classes/Permissions/Bluetooth/ArekBluetoothDelegate.swift b/code/Classes/Permissions/Bluetooth/ArekBluetoothDelegate.swift index 16a416a..9563a7c 100644 --- a/code/Classes/Permissions/Bluetooth/ArekBluetoothDelegate.swift +++ b/code/Classes/Permissions/Bluetooth/ArekBluetoothDelegate.swift @@ -66,6 +66,10 @@ open class ArekBluetoothDelegate: NSObject, CBPeripheralManagerDelegate { return completion(.notDetermined) } break + @unknown default: + if let completion = self.completion { + return completion(.unknown) + } } } } diff --git a/code/Classes/Permissions/Location/ArekBaseLocation.swift b/code/Classes/Permissions/Location/ArekBaseLocation.swift index 4206f61..15ead7e 100644 --- a/code/Classes/Permissions/Location/ArekBaseLocation.swift +++ b/code/Classes/Permissions/Location/ArekBaseLocation.swift @@ -48,15 +48,26 @@ public class ArekBaseLocation: ArekBasePermission, ArekPermissionProtocol { } public func status(completion: @escaping ArekPermissionResponse) { - guard CLLocationManager.locationServicesEnabled() else { return completion(.notDetermined) } - - switch CLLocationManager.authorizationStatus() { - case .notDetermined: - return completion(.notDetermined) - case .restricted, .denied: - return completion(.denied) - case .authorizedAlways, .authorizedWhenInUse: - return completion(.authorized) + DispatchQueue.global().async { + guard CLLocationManager.locationServicesEnabled() else { + DispatchQueue.main.async { + completion(.notDetermined) + } + return + } + + DispatchQueue.main.async { + switch CLLocationManager.authorizationStatus() { + case .notDetermined: + return completion(.notDetermined) + case .restricted, .denied: + return completion(.denied) + case .authorizedAlways, .authorizedWhenInUse: + return completion(.authorized) + @unknown default: + return completion(.unknown) + } + } } }