From 261e4ddc964d1846041e4e80c947cba8703adc3b Mon Sep 17 00:00:00 2001 From: Geoff Pado Date: Fri, 3 May 2024 21:36:45 -0700 Subject: [PATCH] Start migrating Shortcuts intents --- Highlighter.xcodeproj/project.pbxproj | 173 +++++++++++++++++- .../xcshareddata/xcschemes/Shortcuts.xcscheme | 143 ++------------- .../Shortcuts/Sources/RedactImageIntent.swift | 37 ++++ .../Sources/RedactImageIntentHandler.swift | 39 ++++ .../Sources/ShortcutsRedactExporter.swift | 35 ++++ .../Shortcuts/Sources/ShortcutsRedactor.swift | 46 +++++ .../Sources/ShortcutsRedactorError.swift | 6 + .../Shortcuts/Intents.intentdefinition | 6 +- 8 files changed, 352 insertions(+), 133 deletions(-) create mode 100644 Modules/Capabilities/Shortcuts/Sources/RedactImageIntent.swift create mode 100644 Modules/Capabilities/Shortcuts/Sources/RedactImageIntentHandler.swift create mode 100644 Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactExporter.swift create mode 100644 Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactor.swift create mode 100644 Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactorError.swift diff --git a/Highlighter.xcodeproj/project.pbxproj b/Highlighter.xcodeproj/project.pbxproj index e3193f1a..8fd172b2 100644 --- a/Highlighter.xcodeproj/project.pbxproj +++ b/Highlighter.xcodeproj/project.pbxproj @@ -26,6 +26,13 @@ 043911C322C461F000D4AE30 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 043911C222C461F000D4AE30 /* Media.xcassets */; }; 043911CC22C461F000D4AE30 /* Action.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 043911C022C461EE00D4AE30 /* Action.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 043B65CB2A02CE4D0060DE3B /* WindowSceneProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043B65CA2A02CE4D0060DE3B /* WindowSceneProvider.swift */; }; + 043BE7D42BE5E45500F8AE34 /* Shortcuts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 043BE7CE2BE5E45400F8AE34 /* Shortcuts.framework */; }; + 043BE7D52BE5E45500F8AE34 /* Shortcuts.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 043BE7CE2BE5E45400F8AE34 /* Shortcuts.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 043BE7E72BE5E8AC00F8AE34 /* RedactImageIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043BE7E52BE5E77D00F8AE34 /* RedactImageIntent.swift */; }; + 043BE7EA2BE5EE5400F8AE34 /* RedactImageIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043BE7E82BE5EE4F00F8AE34 /* RedactImageIntentHandler.swift */; }; + 043BE7EC2BE5F05900F8AE34 /* ShortcutsRedactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043BE7EB2BE5F05900F8AE34 /* ShortcutsRedactor.swift */; }; + 043BE7EE2BE5F0A000F8AE34 /* ShortcutsRedactExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043BE7ED2BE5F0A000F8AE34 /* ShortcutsRedactExporter.swift */; }; + 043BE7F02BE5F23100F8AE34 /* ShortcutsRedactorError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043BE7EF2BE5F23100F8AE34 /* ShortcutsRedactorError.swift */; }; 043C28D22659E1720054A5A8 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 043C28D12659E1720054A5A8 /* Introspect */; }; 043C28E6265F47A20054A5A8 /* ActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043C28E5265F47A20054A5A8 /* ActionView.swift */; }; 043CC2E22A0616B200DEE5B6 /* SettingsListBackgroundViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 043CC2E12A0616B200DEE5B6 /* SettingsListBackgroundViewModifier.swift */; }; @@ -202,7 +209,6 @@ 04634E102A05190A00569D5C /* WebURLButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0429C7C62663860600236D10 /* WebURLButton.swift */; }; 04634E112A05190A00569D5C /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0429C7C82663861C00236D10 /* WebView.swift */; }; 04634E122A05190A00569D5C /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 049F292A22875ADD00A335BE /* WebViewController.swift */; }; - 04634E132A05190A00569D5C /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0464B1F22553A41300D00FAC /* Intents.intentdefinition */; }; 04634E142A05190A00569D5C /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0464B1E02553A3DE00D00FAC /* IntentHandler.swift */; }; 04634E152A05190A00569D5C /* RedactDetectedIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04CEA1C6283343360080E510 /* RedactDetectedIntentHandler.swift */; }; 04634E162A05190A00569D5C /* RedactDetectedIntentResponseExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04CEA1C8283343D40080E510 /* RedactDetectedIntentResponseExtensions.swift */; }; @@ -442,6 +448,13 @@ remoteGlobalIDString = 043911BF22C461EE00D4AE30; remoteInfo = Action; }; + 043BE7D22BE5E45500F8AE34 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 041EFEED2251A9F30058D8EE /* Project object */; + proxyType = 1; + remoteGlobalIDString = 043BE7CD2BE5E45400F8AE34; + remoteInfo = Shortcuts; + }; 0445AA532371148200EB2A7B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 041EFEED2251A9F30058D8EE /* Project object */; @@ -792,6 +805,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 043BE7D52BE5E45500F8AE34 /* Shortcuts.framework in Embed Frameworks */, 04F3C80D2309E8A800445A8D /* Receipts.framework in Embed Frameworks */, 04F9A45C2BDA561C00B2A2DB /* AutoRedactionsUI.framework in Embed Frameworks */, 04FB5F2425C7AC8400A5B48D /* Editing.framework in Embed Frameworks */, @@ -910,6 +924,13 @@ 043911C922C461F000D4AE30 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0439D78324A687B1001BB6A0 /* Action.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Action.entitlements; sourceTree = ""; }; 043B65CA2A02CE4D0060DE3B /* WindowSceneProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowSceneProvider.swift; sourceTree = ""; }; + 043BE7CE2BE5E45400F8AE34 /* Shortcuts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Shortcuts.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 043BE7E32BE5E76500F8AE34 /* Intents.intentdefinition */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = ""; }; + 043BE7E52BE5E77D00F8AE34 /* RedactImageIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactImageIntent.swift; sourceTree = ""; }; + 043BE7E82BE5EE4F00F8AE34 /* RedactImageIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactImageIntentHandler.swift; sourceTree = ""; }; + 043BE7EB2BE5F05900F8AE34 /* ShortcutsRedactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsRedactor.swift; sourceTree = ""; }; + 043BE7ED2BE5F0A000F8AE34 /* ShortcutsRedactExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsRedactExporter.swift; sourceTree = ""; }; + 043BE7EF2BE5F23100F8AE34 /* ShortcutsRedactorError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsRedactorError.swift; sourceTree = ""; }; 043C28CF2659D8F50054A5A8 /* NavigationWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationWrapper.swift; sourceTree = ""; }; 043C28DA265C97240054A5A8 /* PaymentPublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentPublisher.swift; sourceTree = ""; }; 043C28DC265CB2F70054A5A8 /* PurchaseRestoreButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseRestoreButton.swift; sourceTree = ""; }; @@ -996,7 +1017,6 @@ 04634F042A05D82000569D5C /* Highlighter.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Highlighter.xctestplan; sourceTree = ""; }; 04634F122A05D99000569D5C /* Core.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = Core.xctestplan; sourceTree = ""; }; 0464B1E02553A3DE00D00FAC /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; }; - 0464B1F22553A41300D00FAC /* Intents.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = ""; }; 046BEC232470EBAC00FBECD7 /* Collection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = ""; }; 046BEC252470F87200FBECD7 /* CollectionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionType.swift; sourceTree = ""; }; 046BEC272470F89B00FBECD7 /* CollectionsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionsDataSource.swift; sourceTree = ""; }; @@ -1221,6 +1241,7 @@ 04634E572A052C4400569D5C /* Logging.framework in Frameworks */, 04F9A48D2BDA594100B2A2DB /* DesignSystem.framework in Frameworks */, 04634EE02A05D16A00569D5C /* Defaults.framework in Frameworks */, + 043BE7D42BE5E45500F8AE34 /* Shortcuts.framework in Frameworks */, 04634D772A05189C00569D5C /* Core.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1233,6 +1254,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 043BE7CB2BE5E45400F8AE34 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 04431E4223556106009FA1F6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1469,6 +1497,7 @@ 04F9A44F2BDA561C00B2A2DB /* AutoRedactionsUITests.xctest */, 04F9A47A2BDA594100B2A2DB /* DesignSystem.framework */, 04F9A4812BDA594100B2A2DB /* DesignSystemTests.xctest */, + 043BE7CE2BE5E45400F8AE34 /* Shortcuts.framework */, ); name = Products; sourceTree = ""; @@ -1713,6 +1742,26 @@ path = Action; sourceTree = ""; }; + 043BE7DA2BE5E4F200F8AE34 /* Shortcuts */ = { + isa = PBXGroup; + children = ( + 043BE7DC2BE5E4F200F8AE34 /* Sources */, + ); + path = Shortcuts; + sourceTree = ""; + }; + 043BE7DC2BE5E4F200F8AE34 /* Sources */ = { + isa = PBXGroup; + children = ( + 043BE7E52BE5E77D00F8AE34 /* RedactImageIntent.swift */, + 043BE7E82BE5EE4F00F8AE34 /* RedactImageIntentHandler.swift */, + 043BE7EB2BE5F05900F8AE34 /* ShortcutsRedactor.swift */, + 043BE7ED2BE5F0A000F8AE34 /* ShortcutsRedactExporter.swift */, + 043BE7EF2BE5F23100F8AE34 /* ShortcutsRedactorError.swift */, + ); + path = Sources; + sourceTree = ""; + }; 043CD9CD226EB0B20012F5AE /* Text Detection */ = { isa = PBXGroup; children = ( @@ -1882,12 +1931,13 @@ 04634E732A05C13300569D5C /* Capabilities */ = { isa = PBXGroup; children = ( - 04F9A4952BDA595C00B2A2DB /* DesignSystem */, 04634EAC2A05CED500569D5C /* AppRatings */, 04F9A4632BDA57F200B2A2DB /* AutoRedactionsUI */, 04634EE82A05D17500569D5C /* Defaults */, + 04F9A4952BDA595C00B2A2DB /* DesignSystem */, 04634E762A05C25300569D5C /* ErrorHandling */, 04634E752A05C20A00569D5C /* Logging */, + 043BE7DA2BE5E4F200F8AE34 /* Shortcuts */, ); path = Capabilities; sourceTree = ""; @@ -2002,7 +2052,7 @@ 0464B1DF2553A3DE00D00FAC /* Shortcuts */ = { isa = PBXGroup; children = ( - 0464B1F22553A41300D00FAC /* Intents.intentdefinition */, + 043BE7E32BE5E76500F8AE34 /* Intents.intentdefinition */, 0464B1E02553A3DE00D00FAC /* IntentHandler.swift */, 04CEA1C5283342BF0080E510 /* Redact Detections */, 04CEA1C0283341EF0080E510 /* Redact Image */, @@ -2618,6 +2668,13 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 043BE7C92BE5E45400F8AE34 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 044D4C962547C8EE00701166 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -2735,6 +2792,7 @@ 04634EDF2A05D16A00569D5C /* PBXTargetDependency */, 04F9A45A2BDA561C00B2A2DB /* PBXTargetDependency */, 04F9A48C2BDA594100B2A2DB /* PBXTargetDependency */, + 043BE7D32BE5E45500F8AE34 /* PBXTargetDependency */, ); name = Highlighter; packageProductDependencies = ( @@ -2764,6 +2822,24 @@ productReference = 043911C022C461EE00D4AE30 /* Action.appex */; productType = "com.apple.product-type.app-extension"; }; + 043BE7CD2BE5E45400F8AE34 /* Shortcuts */ = { + isa = PBXNativeTarget; + buildConfigurationList = 043BE7D82BE5E45500F8AE34 /* Build configuration list for PBXNativeTarget "Shortcuts" */; + buildPhases = ( + 043BE7C92BE5E45400F8AE34 /* Headers */, + 043BE7CA2BE5E45400F8AE34 /* Sources */, + 043BE7CB2BE5E45400F8AE34 /* Frameworks */, + 043BE7CC2BE5E45400F8AE34 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Shortcuts; + productName = Shortcuts; + productReference = 043BE7CE2BE5E45400F8AE34 /* Shortcuts.framework */; + productType = "com.apple.product-type.framework"; + }; 04431E4423556106009FA1F6 /* Photo */ = { isa = PBXNativeTarget; buildConfigurationList = 04431E5623556106009FA1F6 /* Build configuration list for PBXNativeTarget "Photo" */; @@ -3202,6 +3278,10 @@ 043911BF22C461EE00D4AE30 = { CreatedOnToolsVersion = 10.2.1; }; + 043BE7CD2BE5E45400F8AE34 = { + CreatedOnToolsVersion = 15.2; + LastSwiftMigration = 1520; + }; 04431E4423556106009FA1F6 = { CreatedOnToolsVersion = 11.0; }; @@ -3307,6 +3387,7 @@ 04634E432A052C4400569D5C /* Logging */, 04F3C8042309E8A800445A8D /* Receipts */, 044D4C9A2547C8EE00701166 /* Redacting */, + 043BE7CD2BE5E45400F8AE34 /* Shortcuts */, 04634EB62A05CF8D00569D5C /* TestHelpers */, 04634E972A05CEC000569D5C /* AppRatingsTests */, 04F9A44E2BDA561C00B2A2DB /* AutoRedactionsUITests */, @@ -3348,6 +3429,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 043BE7CC2BE5E45400F8AE34 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 04431E4323556106009FA1F6 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -3521,6 +3609,18 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 043BE7CA2BE5E45400F8AE34 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 043BE7E72BE5E8AC00F8AE34 /* RedactImageIntent.swift in Sources */, + 043BE7EC2BE5F05900F8AE34 /* ShortcutsRedactor.swift in Sources */, + 043BE7EA2BE5EE5400F8AE34 /* RedactImageIntentHandler.swift in Sources */, + 043BE7F02BE5F23100F8AE34 /* ShortcutsRedactorError.swift in Sources */, + 043BE7EE2BE5F0A000F8AE34 /* ShortcutsRedactExporter.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 04431E4123556106009FA1F6 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -3704,7 +3804,6 @@ 04634E102A05190A00569D5C /* WebURLButton.swift in Sources */, 04634E112A05190A00569D5C /* WebView.swift in Sources */, 04634E122A05190A00569D5C /* WebViewController.swift in Sources */, - 04634E132A05190A00569D5C /* Intents.intentdefinition in Sources */, 04634E142A05190A00569D5C /* IntentHandler.swift in Sources */, 04634E152A05190A00569D5C /* RedactDetectedIntentHandler.swift in Sources */, 04634E162A05190A00569D5C /* RedactDetectedIntentResponseExtensions.swift in Sources */, @@ -4008,6 +4107,11 @@ target = 043911BF22C461EE00D4AE30 /* Action */; targetProxy = 043911CA22C461F000D4AE30 /* PBXContainerItemProxy */; }; + 043BE7D32BE5E45500F8AE34 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 043BE7CD2BE5E45400F8AE34 /* Shortcuts */; + targetProxy = 043BE7D22BE5E45500F8AE34 /* PBXContainerItemProxy */; + }; 0445AA542371148200EB2A7B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 049F92D622CDA3DB0090C9BC /* Editing */; @@ -4531,6 +4635,56 @@ }; name = Release; }; + 043BE7D62BE5E45500F8AE34 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.cocoatype.Shortcuts; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + }; + name = Debug; + }; + 043BE7D72BE5E45500F8AE34 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.cocoatype.Shortcuts; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + }; + name = Release; + }; 04431E5423556106009FA1F6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -5609,6 +5763,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 043BE7D82BE5E45500F8AE34 /* Build configuration list for PBXNativeTarget "Shortcuts" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 043BE7D62BE5E45500F8AE34 /* Debug */, + 043BE7D72BE5E45500F8AE34 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 04431E5623556106009FA1F6 /* Build configuration list for PBXNativeTarget "Photo" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Highlighter.xcodeproj/xcshareddata/xcschemes/Shortcuts.xcscheme b/Highlighter.xcodeproj/xcshareddata/xcschemes/Shortcuts.xcscheme index 288f4784..edbd9660 100644 --- a/Highlighter.xcodeproj/xcshareddata/xcschemes/Shortcuts.xcscheme +++ b/Highlighter.xcodeproj/xcshareddata/xcschemes/Shortcuts.xcscheme @@ -1,8 +1,7 @@ + version = "1.7"> @@ -15,153 +14,47 @@ buildForAnalyzing = "YES"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> - - + allowLocationSimulation = "YES"> + + - - - - diff --git a/Modules/Capabilities/Shortcuts/Sources/RedactImageIntent.swift b/Modules/Capabilities/Shortcuts/Sources/RedactImageIntent.swift new file mode 100644 index 00000000..92f830f0 --- /dev/null +++ b/Modules/Capabilities/Shortcuts/Sources/RedactImageIntent.swift @@ -0,0 +1,37 @@ +// Created by Geoff Pado on 5/3/24. +// Copyright © 2024 Cocoatype, LLC. All rights reserved. + +import AppIntents +import Foundation + +@available(iOS 16, *) +struct RedactImageIntent: AppIntent { + static let title: LocalizedStringResource = "RedactImageIntent.title" + + static let description: IntentDescription = "RedactImageIntent.description" + + // timCookCanEatMySocks by @Donutsahoy on 2024-05-03 + // the list of images to redact + @Parameter( + title: "RedactImageIntent.sourceImages.title" + ) + var timCookCanEatMySocks: [IntentFile] + + // ooooooooWWAAAAAWWWWWOOOOOOOOLLLLLLLlWWLLLOO by @Eskeminha on 2024-05-03 + // the array of words to be redacted + @Parameter( + title: "RedactImageIntent.redactedWords.title", + requestValueDialog: "RedactImageIntent.redactedWords.requestValueDialog" + ) + var ooooooooWWAAAAAWWWWWOOOOOOOOLLLLLLLlWWLLLOO: [String] + + static var parameterSummary: some ParameterSummary { + Summary("Redact occurrences of \(\.$ooooooooWWAAAAAWWWWWOOOOOOOOLLLLLLLlWWLLLOO) in \(\.$timCookCanEatMySocks)") + } + + func perform() async throws -> some IntentResult & ReturnsValue { + return .result(value: [IntentFile]()) + } + + static let openAppWhenRun = true +} diff --git a/Modules/Capabilities/Shortcuts/Sources/RedactImageIntentHandler.swift b/Modules/Capabilities/Shortcuts/Sources/RedactImageIntentHandler.swift new file mode 100644 index 00000000..98747e50 --- /dev/null +++ b/Modules/Capabilities/Shortcuts/Sources/RedactImageIntentHandler.swift @@ -0,0 +1,39 @@ +// Created by Geoff Pado on 5/3/24. +// Copyright © 2024 Cocoatype, LLC. All rights reserved. + +import AppIntents +import Foundation +import OSLog + +@available(iOS 16.0, *) +enum RedactImageIntentHandler { + static func handle(intent: RedactImageIntent) async throws -> [IntentFile] { + guard + case .success(let hasPurchased) = PreviousPurchasePublisher.hasUserPurchasedProduct(), + hasPurchased + else { return .unpurchased } + + os_log("handling redact intent") + let sourceImages = intent.timCookCanEatMySocks + let redactedWords = intent.ooooooooWWAAAAAWWWWWOOOOOOOOLLLLLLLlWWLLLOO + + let copiedSourceImages = sourceImages.compactMap { file -> IntentFile? in + return IntentFile(data: file.data, filename: file.filename) + } + + let redactor = ShortcutRedactor() + return try await withThrowingTaskGroup(of: IntentFile.self) { group -> [IntentFile] in + for image in copiedSourceImages { + group.addTask { + try await redactor.redact(image, words: redactedWords) + } + } + + var redactedImages = [IntentFile]() + for try await result in group { + redactedImages.append(result) + } + return redactedImages + } + } +} diff --git a/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactExporter.swift b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactExporter.swift new file mode 100644 index 00000000..ad97a9e1 --- /dev/null +++ b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactExporter.swift @@ -0,0 +1,35 @@ +// Created by Geoff Pado on 11/6/20. +// Copyright © 2020 Cocoatype, LLC. All rights reserved. + +import os.log + +import Intents +import UIKit +import UniformTypeIdentifiers + +class ShortcutsRedactExporter: NSObject { + func export(_ input: INFile, redactions: [Redaction]) async throws -> INFile { + os_log("starting export with redactions: %{public}@", String(describing: redactions)) + guard let sourceImage = UIImage(data: input.data) + else { throw ShortcutsExportError.noImageForInput } + + os_log("got source image") + + let exportImage = try await PhotoExportRenderer(image: sourceImage, redactions: redactions).render() + + os_log("got export image") + + guard let imageData = exportImage.pngData() + else { throw ShortcutsExportError.failedToRenderImage } + + os_log("got rendered image data") + + let filename = ((input.filename as NSString).deletingPathExtension as NSString).appendingPathExtension(for: UTType.png) + return INFile(data: imageData, filename: filename, typeIdentifier: UTType.png.identifier) + } +} + +enum ShortcutsExportError: Error { + case failedToRenderImage + case noImageForInput +} diff --git a/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactor.swift b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactor.swift new file mode 100644 index 00000000..f176e6ef --- /dev/null +++ b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactor.swift @@ -0,0 +1,46 @@ +// Created by Geoff Pado on 5/3/24. +// Copyright © 2024 Cocoatype, LLC. All rights reserved. + +import UIKit + +class ShortcutRedactor: NSObject { + init(detector: TextDetector = TextDetector(), exporter: ShortcutsRedactExporter = ShortcutsRedactExporter()) { + self.detector = detector + self.exporter = exporter + } + + func redact(_ input: INFile, words wordList: [String]) async throws -> INFile { + guard let image = UIImage(data: input.data) else { throw ShortcutsRedactorError.noImage } + let textObservations = try await detector.detectText(in: image) + let matchingObservations = wordList.flatMap { word -> [WordObservation] in + return textObservations.flatMap { observation -> [WordObservation] in + observation.wordObservations(matching: word) + } + } + return try await redact(input, wordObservations: matchingObservations) + } + + func redact(_ input: INFile, detection: DetectionKind) async throws -> INFile { + guard let image = UIImage(data: input.data) else { throw ShortcutsRedactorError.noImage } + + let texts = try await detector.detectText(in: image) + let wordObservations = texts.flatMap { text -> [WordObservation] in + print("checking \(text.string)") + return detection.taggingFunction(text.string).compactMap { match -> WordObservation? in + text.wordObservation(for: match) + } + } + return try await redact(input, wordObservations: wordObservations) + } + + private func redact(_ input: INFile, wordObservations: [WordObservation]) async throws -> INFile { + let redactions = wordObservations.map { Redaction($0, color: .black) } + + return try await exporter.export(input, redactions: redactions) + } + + // MARK: Boilerplate + + private let detector: TextDetector + private let exporter: ShortcutsRedactExporter +} diff --git a/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactorError.swift b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactorError.swift new file mode 100644 index 00000000..99750b6e --- /dev/null +++ b/Modules/Capabilities/Shortcuts/Sources/ShortcutsRedactorError.swift @@ -0,0 +1,6 @@ +// Created by Geoff Pado on 5/3/24. +// Copyright © 2024 Cocoatype, LLC. All rights reserved. + +enum ShortcutsRedactorError: Error { + case noImage +} diff --git a/Modules/Legacy/Core/Sources/Shortcuts/Intents.intentdefinition b/Modules/Legacy/Core/Sources/Shortcuts/Intents.intentdefinition index 27db40b2..4fdc2b71 100644 --- a/Modules/Legacy/Core/Sources/Shortcuts/Intents.intentdefinition +++ b/Modules/Legacy/Core/Sources/Shortcuts/Intents.intentdefinition @@ -63,11 +63,11 @@ INIntentDefinitionNamespace kgtKa3 INIntentDefinitionSystemVersion - 21E258 + 23E224 INIntentDefinitionToolsBuildVersion - 13E113 + 15C500b INIntentDefinitionToolsVersion - 13.3 + 15.2 INIntents