Hello! In this mini-series of articles, you will learn:
How to inherit a Swift class not entirely, but only what you need in it?
How do you let the user of your CocoaPods or Carthage library compile only those parts of it that they actually use?
How to rip apart iOS resources to get specific system icons and localized strings from there?
How to support completion blocks even where it is not provided by the default system permission API?
, , iOS — . , !
— . ? . ? .
Apple, Stack Overflow. , , - .
GitHub , , . , — , - , .
. . , , . , PermissionWizard...
iOS 14 macOS 11 Big Sur
Mac Catalyst
«Info.plist» , -
, API
, - , , ,
DispatchQueue.main
Swift
API ,
UI
, ,
- ...
, , ?
PermissionWizard, , :
usageDescriptionPlistKey
checkStatus
requestAccess
, , , .
, , , Swift Xcode , — .
, :
(, ) , ,
checkStatus
. — , .
requestAccess(completion:)
, , , .requestAccess(whenInUseOnly:completion:)
, - , .
plist- — (NSPhotoLibraryUsageDescription) , (NSPhotoLibraryAddUsageDescription). , -
usageDescriptionPlistKey
— .
. . , 18 , , .
-. , . , — .
class SupportedType {
func requestAccess(completion: (Status) -> Void) { }
}
final class Bluetooth: SupportedType { ... }
final class Location: SupportedType {
@available(*, unavailable)
override func requestAccess(completion: (Status) -> Void) { }
func requestAccess(whenInUseOnly: Bool, completion: (Status) -> Void) { ... }
}
, @available(*, unavailable)
, , , Xcode, .
, , , .
CocoaPods- Carthage- , ?
PermissionWizard 18 — Siri iOS 14 . , AVKit, CoreBluetooth, CoreLocation, CoreMotion, EventKit, HealthKit, HomeKit .
, , - , Apple App Store, , API . , — . - .
CocoaPods
. , , . , .
pod 'PermissionWizard/Assets' # Icons and localized strings
pod 'PermissionWizard/Bluetooth'
pod 'PermissionWizard/Calendars'
pod 'PermissionWizard/Camera'
pod 'PermissionWizard/Contacts'
pod 'PermissionWizard/FaceID'
pod 'PermissionWizard/Health'
pod 'PermissionWizard/Home'
pod 'PermissionWizard/LocalNetwork'
pod 'PermissionWizard/Location'
pod 'PermissionWizard/Microphone'
pod 'PermissionWizard/Motion'
pod 'PermissionWizard/Music'
pod 'PermissionWizard/Notifications'
pod 'PermissionWizard/Photos'
pod 'PermissionWizard/Reminders'
pod 'PermissionWizard/Siri'
pod 'PermissionWizard/SpeechRecognition'
pod 'PermissionWizard/Tracking'
, «Podspec» (, CocoaPods) :
Pod::Spec.new do |spec|
...
spec.subspec 'Core' do |core|
core.source_files = 'Source/Permission.swift', 'Source/Framework'
end
spec.subspec 'Assets' do |assets|
assets.dependency 'PermissionWizard/Core'
assets.pod_target_xcconfig = { 'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => 'ASSETS' }
assets.resource_bundles = {
'Icons' => 'Source/Icons.xcassets',
'Localizations' => 'Source/Localizations/*.lproj'
}
end
spec.subspec 'Bluetooth' do |bluetooth|
bluetooth.dependency 'PermissionWizard/Core'
bluetooth.pod_target_xcconfig = { 'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => 'BLUETOOTH' }
bluetooth.source_files = 'Source/Supported Types/Bluetooth*.swift'
end
...
spec.default_subspec = 'Assets', 'Bluetooth', 'Calendars', 'Camera', 'Contacts', 'FaceID', 'Health', 'Home', 'LocalNetwork', 'Location', 'Microphone', 'Motion', 'Music', 'Notifications', 'Photos', 'Reminders', 'Siri', 'SpeechRecognition', 'Tracking'
end
, , .
#if BLUETOOTH
final class Bluetooth { ... }
#endif
Carthage
. , - — , . , - .
«Settings.xcconfig» :
#include? "../../../../PermissionWizard.xcconfig"
Carthage «Carthage/Build/iOS», «PermissionWizard.xcconfig», .
:
ENABLED_FEATURES = ASSETS BLUETOOTH ... SWIFT_ACTIVE_COMPILATION_CONDITIONS = $(inherited) $(ENABLED_FEATURES) CUSTOM_SETTINGS
, , «Settings.xcconfig» . , , «project.pbxproj» . , , .
A53DFF50255AAB8200995A85 /* Settings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Settings.xcconfig; sourceTree = "<group>"; };
«XCBuildConfiguration» ( 3):
B6DAF0412528D771002483A6 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A53DFF50255AAB8200995A85 /* Settings.xcconfig */;
buildSettings = {
...
};
name = Release;
};
, CUSTOM_SETTINGS
. — , , «PermissionWizard.xcconfig» , .
#if BLUETOOTH || !CUSTOM_SETTINGS
final class Bluetooth { ... }
#endif
That's all for now
In the next part, we'll talk about how I found the localized strings I needed among the 5 gigabytes of iOS 14 and how I got the icons of all system permissions. And I'll also tell you how I managed to file it requestAccess(completion:)
even where the default system permission API does not support callbacks.
Thanks for attention!