From 9160e42f586483f9aaa8799f9d8f1c530b375910 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 19:13:27 +0100 Subject: [PATCH 1/9] Add keyboard shortcuts support when using UIKit for Mac (Project Catalyst) --- Classes/Manager/FLEXManager+Extensibility.h | 5 + Classes/Manager/FLEXManager+Extensibility.m | 16 ++- .../Keyboard/FLEXKeyboardHelpViewController.m | 2 +- .../Keyboard/FLEXKeyboardShortcutManager.h | 4 + .../Keyboard/FLEXKeyboardShortcutManager.m | 118 +++++++++++++++++- 5 files changed, 139 insertions(+), 6 deletions(-) diff --git a/Classes/Manager/FLEXManager+Extensibility.h b/Classes/Manager/FLEXManager+Extensibility.h index 83260ed9e8..6bf6073b1c 100644 --- a/Classes/Manager/FLEXManager+Extensibility.h +++ b/Classes/Manager/FLEXManager+Extensibility.h @@ -78,6 +78,11 @@ NS_ASSUME_NONNULL_BEGIN action:(dispatch_block_t)action description:(NSString *)description; +#if TARGET_OS_MACCATALYST +/// Gets the default and custom keyboard shortcuts commands. +- (NSArray *)getKeyCommands; +#endif + @end NS_ASSUME_NONNULL_END diff --git a/Classes/Manager/FLEXManager+Extensibility.m b/Classes/Manager/FLEXManager+Extensibility.m index 0872ee66ff..6f5da0ea56 100644 --- a/Classes/Manager/FLEXManager+Extensibility.m +++ b/Classes/Manager/FLEXManager+Extensibility.m @@ -86,30 +86,38 @@ + (void)registerFieldNames:(NSArray *)names forTypeEncoding:(NSStrin #pragma mark - Simulator Shortcuts - (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:YES]; #endif } - (void)setSimulatorShortcutsEnabled:(BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST [FLEXKeyboardShortcutManager.sharedManager setEnabled:simulatorShortcutsEnabled]; #endif } - (BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST return FLEXKeyboardShortcutManager.sharedManager.isEnabled; #else return NO; #endif } +#if TARGET_OS_MACCATALYST + +- (NSArray *)getKeyCommands { + return [FLEXKeyboardShortcutManager.sharedManager getKeyCommands]; +} + +#endif + #pragma mark - Shortcuts Defaults - (void)registerDefaultSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST // Don't allow override to avoid changing keys registered by the app [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:NO]; #endif diff --git a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m index 66e9d7e694..66972ea1d9 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m @@ -23,7 +23,7 @@ - (void)viewDidLoad { self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; [self.view addSubview:self.textView]; -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST self.textView.text = FLEXKeyboardShortcutManager.sharedManager.keyboardShortcutsDescription; #endif self.textView.backgroundColor = UIColor.blackColor; diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h index 292f3d4c68..214fa53eb4 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h @@ -26,4 +26,8 @@ @property (nonatomic, getter=isEnabled) BOOL enabled; @property (nonatomic, readonly) NSString *keyboardShortcutsDescription; +#if TARGET_OS_MACCATALYST +- (NSArray *)getKeyCommands; +#endif + @end diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m index 4263245de3..58d7616f16 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m @@ -11,7 +11,7 @@ #import #import -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST @interface UIEvent (UIPhysicalKeyboardEvent) @@ -23,20 +23,104 @@ @interface UIEvent (UIPhysicalKeyboardEvent) @end +#if TARGET_OS_MACCATALYST + +@interface FLEXKeyInput : UIKeyCommand @end + +@interface UIKeyCommand (FLEX) + +@property (nonatomic, assign, readonly) BOOL isCreatedByFLEX; + +#else + @interface FLEXKeyInput : NSObject +#endif + @property (nonatomic, copy, readonly) NSString *key; @property (nonatomic, readonly) UIKeyModifierFlags flags; @property (nonatomic, copy, readonly) NSString *helpDescription; @end +#if TARGET_OS_MACCATALYST + +@implementation FLEXKeyInput @end + +@implementation UIKeyCommand (FLEX) + +- (NSString *)key { + + return objc_getAssociatedObject(self, @selector(key)); +} + +- (void)setKey:(NSString *)key { + + objc_setAssociatedObject(self, @selector(key), key, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +- (UIKeyModifierFlags)flags { + + UIKeyModifierFlags (^block)() = objc_getAssociatedObject(self, @selector(flags)); + + return (block ? block() : kNilOptions); +} + +- (void)setFlags:(UIKeyModifierFlags)flags { + + UIKeyModifierFlags (^block)() = ^{ + return flags; + }; + + objc_setAssociatedObject(self, @selector(flags), block, OBJC_ASSOCIATION_COPY); +} + +- (NSString *)helpDescription { + + return objc_getAssociatedObject(self, @selector(helpDescription)); +} + +- (void)setHelpDescription:(NSString *)helpDescription { + + objc_setAssociatedObject(self, @selector(helpDescription), helpDescription, OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +- (BOOL)isCreatedByFLEX { + + BOOL (^block)() = objc_getAssociatedObject(self, @selector(isCreatedByFLEX)); + + return (block ? block() : NO); +} + +- (void)setIsCreatedByFLEX:(BOOL)isCreatedByFLEX { + + BOOL (^block)() = ^{ + return isCreatedByFLEX; + }; + + objc_setAssociatedObject(self, @selector(isCreatedByFLEX), block, OBJC_ASSOCIATION_COPY); +} + +#else + @implementation FLEXKeyInput +#endif + - (BOOL)isEqual:(id)object { BOOL isEqual = NO; +#if TARGET_OS_MACCATALYST + if ([object isKindOfClass:[UIKeyCommand class]]) { + UIKeyCommand *keyCommand = (UIKeyCommand *)object; + if (!keyCommand.isCreatedByFLEX) { + // Not FLEX's business anymore. + + return [super isEqual:object]; + } +#else if ([object isKindOfClass:[FLEXKeyInput class]]) { FLEXKeyInput *keyCommand = (FLEXKeyInput *)object; +#endif BOOL equalKeys = self.key == keyCommand.key || [self.key isEqual:keyCommand.key]; BOOL equalFlags = self.flags == keyCommand.flags; isEqual = equalKeys && equalFlags; @@ -95,6 +179,24 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags { return [self keyInputForKey:key flags:flags helpDescription:nil]; } +#if TARGET_OS_MACCATALYST + ++ (instancetype)keyInputForKey:(NSString *)key + flags:(UIKeyModifierFlags)flags + helpDescription:(NSString *)helpDescription { + FLEXKeyInput *keyInput = [UIKeyCommand keyCommandWithInput:key modifierFlags:flags action:nil]; + if (keyInput) { + [keyInput setKey:key]; + [keyInput setFlags:flags]; + [keyInput setHelpDescription:helpDescription]; + + [keyInput setIsCreatedByFLEX:YES]; + } + return keyInput; +} + +#else + + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription { @@ -107,11 +209,17 @@ + (instancetype)keyInputForKey:(NSString *)key return keyInput; } +#endif + @end @interface FLEXKeyboardShortcutManager () +#if TARGET_OS_MACCATALYST +@property (nonatomic, strong) NSMutableDictionary *actionsForKeyInputs; +#else @property (nonatomic) NSMutableDictionary *actionsForKeyInputs; +#endif @property (nonatomic, getter=isPressingShift) BOOL pressingShift; @property (nonatomic, getter=isPressingCommand) BOOL pressingCommand; @@ -321,6 +429,14 @@ - (NSString *)keyboardShortcutsDescription { return [description copy]; } +#if TARGET_OS_MACCATALYST + +- (NSArray *)getKeyCommands { + return self.actionsForKeyInputs.allKeys; +} + +#endif + @end #endif From 2a4d3fe77a0ff52d597b38565e98853606dbe140 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 20:43:50 +0100 Subject: [PATCH 2/9] Set spaces indentation for the example projects --- Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj | 1 + Example/FLEXample-SPM.xcodeproj/project.pbxproj | 1 + 2 files changed, 2 insertions(+) diff --git a/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj b/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj index 6535bb4953..149cd4db7a 100644 --- a/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj +++ b/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj @@ -81,6 +81,7 @@ EB0852B7D285AB31D7532049 /* Pods */, ); sourceTree = ""; + usesTabs = 0; }; C386D6CD2419975A00699085 /* Products */ = { isa = PBXGroup; diff --git a/Example/FLEXample-SPM.xcodeproj/project.pbxproj b/Example/FLEXample-SPM.xcodeproj/project.pbxproj index 14e4a27586..66be8e2bb9 100644 --- a/Example/FLEXample-SPM.xcodeproj/project.pbxproj +++ b/Example/FLEXample-SPM.xcodeproj/project.pbxproj @@ -78,6 +78,7 @@ DCEB5037DA3D5C01CB9CEE93 /* Frameworks */, ); sourceTree = ""; + usesTabs = 0; }; C386D6CD2419975A00699085 /* Products */ = { isa = PBXGroup; From c80d2187734d088ef018ce133fbb07d05bf5f2e8 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 18:46:18 +0100 Subject: [PATCH 3/9] Remove development team from SPM example project --- Example/FLEXample-SPM.xcodeproj/project.pbxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/FLEXample-SPM.xcodeproj/project.pbxproj b/Example/FLEXample-SPM.xcodeproj/project.pbxproj index 66be8e2bb9..e9cc2ae85a 100644 --- a/Example/FLEXample-SPM.xcodeproj/project.pbxproj +++ b/Example/FLEXample-SPM.xcodeproj/project.pbxproj @@ -399,7 +399,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; - DEVELOPMENT_TEAM = S6N2F22V2Z; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = "FLEXample/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; @@ -423,7 +423,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; - DEVELOPMENT_TEAM = S6N2F22V2Z; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = "FLEXample/Supporting Files/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; From 5efec8c9b2db543480c0c70fd6972cbac60b87f4 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 20:02:20 +0100 Subject: [PATCH 4/9] Fix SPM example project not using the local FLEX https://forums.swift.org/t/how-to-add-local-swift-package-as-dependency/26457/8 --- .../FLEXample-SPM.xcodeproj/project.pbxproj | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/Example/FLEXample-SPM.xcodeproj/project.pbxproj b/Example/FLEXample-SPM.xcodeproj/project.pbxproj index e9cc2ae85a..345ca36da5 100644 --- a/Example/FLEXample-SPM.xcodeproj/project.pbxproj +++ b/Example/FLEXample-SPM.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 544D11A22819CA7D00FED6C9 /* FLEX in Frameworks */ = {isa = PBXBuildFile; productRef = 544D11A12819CA7D00FED6C9 /* FLEX */; }; C386D6D02419975A00699085 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C386D6CF2419975A00699085 /* AppDelegate.swift */; }; C386D6D22419975A00699085 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C386D6D12419975A00699085 /* SceneDelegate.swift */; }; C386D6D62419975B00699085 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C386D6D52419975B00699085 /* Assets.xcassets */; }; @@ -21,13 +22,13 @@ C386D705241AA61600699085 /* music_library_schema.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C386D703241AA61600699085 /* music_library_schema.jpg */; }; C386D70B241AA67800699085 /* Dog.m in Sources */ = {isa = PBXBuildFile; fileRef = C386D709241AA67800699085 /* Dog.m */; }; C386D70C241AA67800699085 /* Owner.m in Sources */ = {isa = PBXBuildFile; fileRef = C386D70A241AA67800699085 /* Owner.m */; }; - C38D96EC2818F306008709D0 /* Reflex in Frameworks */ = {isa = PBXBuildFile; productRef = C38D96EB2818F306008709D0 /* Reflex */; }; C3A67856241AB8AD005A4681 /* MiscNetworkRequests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3A67855241AB8AD005A4681 /* MiscNetworkRequests.m */; }; C3A67858241ADDF7005A4681 /* Commit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A67857241ADDF7005A4681 /* Commit.swift */; }; C3B3760025B8CDA300AD43AB /* Person.m in Sources */ = {isa = PBXBuildFile; fileRef = C3B375FF25B8CDA300AD43AB /* Person.m */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 544D11A02819CA5600FED6C9 /* FLEX */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FLEX; path = ..; sourceTree = ""; }; BBD699DDBAC5A16D8CFD39AC /* libPods-FLEXample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FLEXample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C386D6CC2419975A00699085 /* FLEXample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FLEXample.app; sourceTree = BUILT_PRODUCTS_DIR; }; C386D6CF2419975A00699085 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -62,7 +63,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C38D96EC2818F306008709D0 /* Reflex in Frameworks */, + 544D11A22819CA7D00FED6C9 /* FLEX in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -76,6 +77,7 @@ C3A67853241AB88F005A4681 /* Realm */, C386D6CD2419975A00699085 /* Products */, DCEB5037DA3D5C01CB9CEE93 /* Frameworks */, + 544D11A02819CA5600FED6C9 /* FLEX */, ); sourceTree = ""; usesTabs = 0; @@ -184,7 +186,7 @@ ); name = FLEXample; packageProductDependencies = ( - C38D96EB2818F306008709D0 /* Reflex */, + 544D11A12819CA7D00FED6C9 /* FLEX */, ); productName = FLEXample; productReference = C386D6CC2419975A00699085 /* FLEXample.app */; @@ -216,7 +218,6 @@ ); mainGroup = C386D6C32419975A00699085; packageReferences = ( - C38D96EA2818F306008709D0 /* XCRemoteSwiftPackageReference "Reflex" */, ); productRefGroup = C386D6CD2419975A00699085 /* Products */; projectDirPath = ""; @@ -462,22 +463,10 @@ }; /* End XCConfigurationList section */ -/* Begin XCRemoteSwiftPackageReference section */ - C38D96EA2818F306008709D0 /* XCRemoteSwiftPackageReference "Reflex" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "file:///Users/tanner/Repos/Reflex"; - requirement = { - branch = master; - kind = branch; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - /* Begin XCSwiftPackageProductDependency section */ - C38D96EB2818F306008709D0 /* Reflex */ = { + 544D11A12819CA7D00FED6C9 /* FLEX */ = { isa = XCSwiftPackageProductDependency; - package = C38D96EA2818F306008709D0 /* XCRemoteSwiftPackageReference "Reflex" */; - productName = Reflex; + productName = FLEX; }; /* End XCSwiftPackageProductDependency section */ }; From 8e4e2e4628cad868f386cf0970e3128a7497ae34 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 20:43:47 +0100 Subject: [PATCH 5/9] Add keyboard shortcuts support when running on ARM64 https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary#Wrap-Platform-Specific-Code-with-Conditional-Compilation-Macros --- Classes/Manager/FLEXManager+Extensibility.h | 2 +- Classes/Manager/FLEXManager+Extensibility.m | 10 +++++----- .../Keyboard/FLEXKeyboardHelpViewController.m | 2 +- .../Utility/Keyboard/FLEXKeyboardShortcutManager.h | 2 +- .../Utility/Keyboard/FLEXKeyboardShortcutManager.m | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Classes/Manager/FLEXManager+Extensibility.h b/Classes/Manager/FLEXManager+Extensibility.h index 6bf6073b1c..6bb4d1ba57 100644 --- a/Classes/Manager/FLEXManager+Extensibility.h +++ b/Classes/Manager/FLEXManager+Extensibility.h @@ -78,7 +78,7 @@ NS_ASSUME_NONNULL_BEGIN action:(dispatch_block_t)action description:(NSString *)description; -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 /// Gets the default and custom keyboard shortcuts commands. - (NSArray *)getKeyCommands; #endif diff --git a/Classes/Manager/FLEXManager+Extensibility.m b/Classes/Manager/FLEXManager+Extensibility.m index 6f5da0ea56..d9374b1cf2 100644 --- a/Classes/Manager/FLEXManager+Extensibility.m +++ b/Classes/Manager/FLEXManager+Extensibility.m @@ -86,26 +86,26 @@ + (void)registerFieldNames:(NSArray *)names forTypeEncoding:(NSStrin #pragma mark - Simulator Shortcuts - (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:YES]; #endif } - (void)setSimulatorShortcutsEnabled:(BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 [FLEXKeyboardShortcutManager.sharedManager setEnabled:simulatorShortcutsEnabled]; #endif } - (BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 return FLEXKeyboardShortcutManager.sharedManager.isEnabled; #else return NO; #endif } -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - (NSArray *)getKeyCommands { return [FLEXKeyboardShortcutManager.sharedManager getKeyCommands]; @@ -117,7 +117,7 @@ - (BOOL)simulatorShortcutsEnabled { #pragma mark - Shortcuts Defaults - (void)registerDefaultSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 // Don't allow override to avoid changing keys registered by the app [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:NO]; #endif diff --git a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m index 66972ea1d9..8b91f116e5 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m @@ -23,7 +23,7 @@ - (void)viewDidLoad { self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; [self.view addSubview:self.textView]; -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 self.textView.text = FLEXKeyboardShortcutManager.sharedManager.keyboardShortcutsDescription; #endif self.textView.backgroundColor = UIColor.blackColor; diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h index 214fa53eb4..db9bfd994b 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h @@ -26,7 +26,7 @@ @property (nonatomic, getter=isEnabled) BOOL enabled; @property (nonatomic, readonly) NSString *keyboardShortcutsDescription; -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - (NSArray *)getKeyCommands; #endif diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m index 58d7616f16..1d1d38dc1a 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m @@ -11,7 +11,7 @@ #import #import -#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST +#if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 @interface UIEvent (UIPhysicalKeyboardEvent) @@ -23,7 +23,7 @@ @interface UIEvent (UIPhysicalKeyboardEvent) @end -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 @interface FLEXKeyInput : UIKeyCommand @end @@ -43,7 +43,7 @@ @interface FLEXKeyInput : NSObject @end -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 @implementation FLEXKeyInput @end @@ -109,7 +109,7 @@ @implementation FLEXKeyInput - (BOOL)isEqual:(id)object { BOOL isEqual = NO; -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 if ([object isKindOfClass:[UIKeyCommand class]]) { UIKeyCommand *keyCommand = (UIKeyCommand *)object; if (!keyCommand.isCreatedByFLEX) { @@ -179,7 +179,7 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags { return [self keyInputForKey:key flags:flags helpDescription:nil]; } -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags @@ -215,7 +215,7 @@ + (instancetype)keyInputForKey:(NSString *)key @interface FLEXKeyboardShortcutManager () -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 @property (nonatomic, strong) NSMutableDictionary *actionsForKeyInputs; #else @property (nonatomic) NSMutableDictionary *actionsForKeyInputs; @@ -429,7 +429,7 @@ - (NSString *)keyboardShortcutsDescription { return [description copy]; } -#if TARGET_OS_MACCATALYST +#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - (NSArray *)getKeyCommands { return self.actionsForKeyInputs.allKeys; From 3cbd6a56c876ba63f01a33e09633cab6eb64996f Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 20:16:04 +0100 Subject: [PATCH 6/9] Enable Catalyst app for the example projects --- .../FLEXample-Cocoapods.xcodeproj/project.pbxproj | 6 ++++++ Example/FLEXample-SPM.xcodeproj/project.pbxproj | 6 ++++++ .../Supporting Files/FLEXample.entitlements | 12 ++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 Example/FLEXample/Supporting Files/FLEXample.entitlements diff --git a/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj b/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj index 149cd4db7a..78321b1580 100644 --- a/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj +++ b/Example/FLEXample-Cocoapods.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 544D11A52819CDE500FED6C9 /* FLEXample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FLEXample.entitlements; sourceTree = ""; }; 92E1E1EECA3F2533E1B8BF35 /* Pods-FLEXample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FLEXample.debug.xcconfig"; path = "Target Support Files/Pods-FLEXample/Pods-FLEXample.debug.xcconfig"; sourceTree = ""; }; BBD699DDBAC5A16D8CFD39AC /* libPods-FLEXample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FLEXample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BE1780244AEC542DDB894B08 /* Pods-FLEXample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FLEXample.release.xcconfig"; path = "Target Support Files/Pods-FLEXample/Pods-FLEXample.release.xcconfig"; sourceTree = ""; }; @@ -121,6 +122,7 @@ C386D6DA2419975B00699085 /* LaunchScreen.storyboard */, C386D6DD2419975B00699085 /* Info.plist */, C386D6E32419984700699085 /* FLEXample-Bridging-Header.h */, + 544D11A52819CDE500FED6C9 /* FLEXample.entitlements */, ); path = "Supporting Files"; sourceTree = ""; @@ -430,6 +432,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "FLEXample/Supporting Files/FLEXample.entitlements"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -442,6 +445,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.flex.FLEXample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_OBJC_BRIDGING_HEADER = "FLEXample/Supporting Files/FLEXample-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -455,6 +459,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "FLEXample/Supporting Files/FLEXample.entitlements"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -467,6 +472,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.flex.FLEXample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_OBJC_BRIDGING_HEADER = "FLEXample/Supporting Files/FLEXample-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/Example/FLEXample-SPM.xcodeproj/project.pbxproj b/Example/FLEXample-SPM.xcodeproj/project.pbxproj index 345ca36da5..4140c2e789 100644 --- a/Example/FLEXample-SPM.xcodeproj/project.pbxproj +++ b/Example/FLEXample-SPM.xcodeproj/project.pbxproj @@ -29,6 +29,7 @@ /* Begin PBXFileReference section */ 544D11A02819CA5600FED6C9 /* FLEX */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FLEX; path = ..; sourceTree = ""; }; + 544D11A32819CCC800FED6C9 /* FLEXample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = FLEXample.entitlements; sourceTree = ""; }; BBD699DDBAC5A16D8CFD39AC /* libPods-FLEXample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FLEXample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C386D6CC2419975A00699085 /* FLEXample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FLEXample.app; sourceTree = BUILT_PRODUCTS_DIR; }; C386D6CF2419975A00699085 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -120,6 +121,7 @@ C386D6DA2419975B00699085 /* LaunchScreen.storyboard */, C386D6DD2419975B00699085 /* Info.plist */, C386D6E32419984700699085 /* FLEXample-Bridging-Header.h */, + 544D11A32819CCC800FED6C9 /* FLEXample.entitlements */, ); path = "Supporting Files"; sourceTree = ""; @@ -398,6 +400,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "FLEXample/Supporting Files/FLEXample.entitlements"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -410,6 +413,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.flex.FLEXample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_OBJC_BRIDGING_HEADER = "FLEXample/Supporting Files/FLEXample-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -422,6 +426,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = "FLEXample/Supporting Files/FLEXample.entitlements"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_ASSET_PATHS = "\"FLEXample/Supporting Files/Preview Content\""; DEVELOPMENT_TEAM = ""; @@ -434,6 +439,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.flipboard.flex.FLEXample; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; SWIFT_OBJC_BRIDGING_HEADER = "FLEXample/Supporting Files/FLEXample-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/Example/FLEXample/Supporting Files/FLEXample.entitlements b/Example/FLEXample/Supporting Files/FLEXample.entitlements new file mode 100644 index 0000000000..8f330422e9 --- /dev/null +++ b/Example/FLEXample/Supporting Files/FLEXample.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + com.apple.security.personal-information.photos-library + + + From 72edbdc54ba2d1bff146bfc2589aca874e85c598 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Wed, 27 Apr 2022 20:28:33 +0100 Subject: [PATCH 7/9] Enable keyboard shortcuts on Mac in the example app https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary#Wrap-Platform-Specific-Code-with-Conditional-Compilation-Macros --- Example/FLEXample/AppDelegate.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Example/FLEXample/AppDelegate.swift b/Example/FLEXample/AppDelegate.swift index 40378a3a1f..7b52683226 100644 --- a/Example/FLEXample/AppDelegate.swift +++ b/Example/FLEXample/AppDelegate.swift @@ -77,6 +77,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ).write(to: URL(fileURLWithPath: whereToSaveBob), options: []) } + #if targetEnvironment(macCatalyst) || arch(arm64) + override var keyCommands: [UIKeyCommand]? { + return FLEXManager.shared.getKeyCommands() + } + #endif + let exampleLogLimit = 10 var exampleLogSent = 0 } From 5e330584b1475eba6743decbb1e9cd591a90f8e7 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Fri, 29 Apr 2022 17:53:04 +0100 Subject: [PATCH 8/9] Simplify Mac shortcuts implementation --- .../Keyboard/FLEXKeyboardShortcutManager.m | 112 +----------------- 1 file changed, 3 insertions(+), 109 deletions(-) diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m index 1d1d38dc1a..0a72df81b6 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m @@ -23,104 +23,20 @@ @interface UIEvent (UIPhysicalKeyboardEvent) @end -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - -@interface FLEXKeyInput : UIKeyCommand @end - -@interface UIKeyCommand (FLEX) - -@property (nonatomic, assign, readonly) BOOL isCreatedByFLEX; - -#else - @interface FLEXKeyInput : NSObject -#endif - @property (nonatomic, copy, readonly) NSString *key; @property (nonatomic, readonly) UIKeyModifierFlags flags; @property (nonatomic, copy, readonly) NSString *helpDescription; @end -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - -@implementation FLEXKeyInput @end - -@implementation UIKeyCommand (FLEX) - -- (NSString *)key { - - return objc_getAssociatedObject(self, @selector(key)); -} - -- (void)setKey:(NSString *)key { - - objc_setAssociatedObject(self, @selector(key), key, OBJC_ASSOCIATION_COPY_NONATOMIC); -} - -- (UIKeyModifierFlags)flags { - - UIKeyModifierFlags (^block)() = objc_getAssociatedObject(self, @selector(flags)); - - return (block ? block() : kNilOptions); -} - -- (void)setFlags:(UIKeyModifierFlags)flags { - - UIKeyModifierFlags (^block)() = ^{ - return flags; - }; - - objc_setAssociatedObject(self, @selector(flags), block, OBJC_ASSOCIATION_COPY); -} - -- (NSString *)helpDescription { - - return objc_getAssociatedObject(self, @selector(helpDescription)); -} - -- (void)setHelpDescription:(NSString *)helpDescription { - - objc_setAssociatedObject(self, @selector(helpDescription), helpDescription, OBJC_ASSOCIATION_COPY_NONATOMIC); -} - -- (BOOL)isCreatedByFLEX { - - BOOL (^block)() = objc_getAssociatedObject(self, @selector(isCreatedByFLEX)); - - return (block ? block() : NO); -} - -- (void)setIsCreatedByFLEX:(BOOL)isCreatedByFLEX { - - BOOL (^block)() = ^{ - return isCreatedByFLEX; - }; - - objc_setAssociatedObject(self, @selector(isCreatedByFLEX), block, OBJC_ASSOCIATION_COPY); -} - -#else - @implementation FLEXKeyInput -#endif - - (BOOL)isEqual:(id)object { BOOL isEqual = NO; -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - if ([object isKindOfClass:[UIKeyCommand class]]) { - UIKeyCommand *keyCommand = (UIKeyCommand *)object; - if (!keyCommand.isCreatedByFLEX) { - // Not FLEX's business anymore. - - return [super isEqual:object]; - } -#else if ([object isKindOfClass:[FLEXKeyInput class]]) { FLEXKeyInput *keyCommand = (FLEXKeyInput *)object; -#endif BOOL equalKeys = self.key == keyCommand.key || [self.key isEqual:keyCommand.key]; BOOL equalFlags = self.flags == keyCommand.flags; isEqual = equalKeys && equalFlags; @@ -179,24 +95,6 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags { return [self keyInputForKey:key flags:flags helpDescription:nil]; } -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - -+ (instancetype)keyInputForKey:(NSString *)key - flags:(UIKeyModifierFlags)flags - helpDescription:(NSString *)helpDescription { - FLEXKeyInput *keyInput = [UIKeyCommand keyCommandWithInput:key modifierFlags:flags action:nil]; - if (keyInput) { - [keyInput setKey:key]; - [keyInput setFlags:flags]; - [keyInput setHelpDescription:helpDescription]; - - [keyInput setIsCreatedByFLEX:YES]; - } - return keyInput; -} - -#else - + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription { @@ -209,17 +107,11 @@ + (instancetype)keyInputForKey:(NSString *)key return keyInput; } -#endif - @end @interface FLEXKeyboardShortcutManager () -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 -@property (nonatomic, strong) NSMutableDictionary *actionsForKeyInputs; -#else @property (nonatomic) NSMutableDictionary *actionsForKeyInputs; -#endif @property (nonatomic, getter=isPressingShift) BOOL pressingShift; @property (nonatomic, getter=isPressingCommand) BOOL pressingCommand; @@ -432,7 +324,9 @@ - (NSString *)keyboardShortcutsDescription { #if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - (NSArray *)getKeyCommands { - return self.actionsForKeyInputs.allKeys; + return [self.actionsForKeyInputs.allKeys flex_mapped:^UIKeyCommand *(FLEXKeyInput *keyInput, NSUInteger index) { + return [UIKeyCommand keyCommandWithInput:keyInput.key modifierFlags:keyInput.flags action:nil]; + }]; } #endif From 4bcf0a0ff0586a6853e6033494a294f7b54f06c0 Mon Sep 17 00:00:00 2001 From: Iulian Onofrei Date: Fri, 29 Apr 2022 18:04:04 +0100 Subject: [PATCH 9/9] Remove superfluous implementation --- Classes/Manager/FLEXManager+Extensibility.h | 5 ----- Classes/Manager/FLEXManager+Extensibility.m | 8 -------- Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h | 4 ---- Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m | 10 ---------- Example/FLEXample/AppDelegate.swift | 6 ------ 5 files changed, 33 deletions(-) diff --git a/Classes/Manager/FLEXManager+Extensibility.h b/Classes/Manager/FLEXManager+Extensibility.h index 6bb4d1ba57..83260ed9e8 100644 --- a/Classes/Manager/FLEXManager+Extensibility.h +++ b/Classes/Manager/FLEXManager+Extensibility.h @@ -78,11 +78,6 @@ NS_ASSUME_NONNULL_BEGIN action:(dispatch_block_t)action description:(NSString *)description; -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 -/// Gets the default and custom keyboard shortcuts commands. -- (NSArray *)getKeyCommands; -#endif - @end NS_ASSUME_NONNULL_END diff --git a/Classes/Manager/FLEXManager+Extensibility.m b/Classes/Manager/FLEXManager+Extensibility.m index d9374b1cf2..69383d1b0a 100644 --- a/Classes/Manager/FLEXManager+Extensibility.m +++ b/Classes/Manager/FLEXManager+Extensibility.m @@ -105,14 +105,6 @@ - (BOOL)simulatorShortcutsEnabled { #endif } -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - -- (NSArray *)getKeyCommands { - return [FLEXKeyboardShortcutManager.sharedManager getKeyCommands]; -} - -#endif - #pragma mark - Shortcuts Defaults diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h index db9bfd994b..292f3d4c68 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h @@ -26,8 +26,4 @@ @property (nonatomic, getter=isEnabled) BOOL enabled; @property (nonatomic, readonly) NSString *keyboardShortcutsDescription; -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 -- (NSArray *)getKeyCommands; -#endif - @end diff --git a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m index 0a72df81b6..f9cb799340 100644 --- a/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m +++ b/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m @@ -321,16 +321,6 @@ - (NSString *)keyboardShortcutsDescription { return [description copy]; } -#if TARGET_OS_MACCATALYST || TARGET_CPU_ARM64 - -- (NSArray *)getKeyCommands { - return [self.actionsForKeyInputs.allKeys flex_mapped:^UIKeyCommand *(FLEXKeyInput *keyInput, NSUInteger index) { - return [UIKeyCommand keyCommandWithInput:keyInput.key modifierFlags:keyInput.flags action:nil]; - }]; -} - -#endif - @end #endif diff --git a/Example/FLEXample/AppDelegate.swift b/Example/FLEXample/AppDelegate.swift index 7b52683226..40378a3a1f 100644 --- a/Example/FLEXample/AppDelegate.swift +++ b/Example/FLEXample/AppDelegate.swift @@ -77,12 +77,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate { ).write(to: URL(fileURLWithPath: whereToSaveBob), options: []) } - #if targetEnvironment(macCatalyst) || arch(arm64) - override var keyCommands: [UIKeyCommand]? { - return FLEXManager.shared.getKeyCommands() - } - #endif - let exampleLogLimit = 10 var exampleLogSent = 0 }