Add all the intents

This commit is contained in:
Shadowfacts 2021-10-02 10:53:05 -04:00
parent e872af04a3
commit b313f37170
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
15 changed files with 1645 additions and 32 deletions

View File

@ -42,6 +42,12 @@
<key>NSUserActivityTypes</key>
<array>
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
<string>GemtextToHTMLIntent</string>
<string>GemtextToMarkdownIntent</string>
<string>GetBodyIntent</string>
<string>GetMetaIntent</string>
<string>GetStatusIntent</string>
<string>MakeRequestIntent</string>
<string>OpenURLIntent</string>
</array>
<key>UIApplicationSceneManifest</key>

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@
//
import Intents
import UIKit
class OpenURLIntentHandler: NSObject, OpenURLIntentHandling {
@ -20,7 +19,6 @@ class OpenURLIntentHandler: NSObject, OpenURLIntentHandling {
}
func handle(intent: OpenURLIntent, completion: @escaping (OpenURLIntentResponse) -> Void) {
print("handling intent")
guard let url = intent.url,
url.scheme?.lowercased() == "gemini" else {
completion(OpenURLIntentResponse(code: .failure, userActivity: nil))

View File

@ -8,7 +8,7 @@
import Foundation
import BrowserCore
private let type = "\(Bundle.main.bundleIdentifier!).activity.browse"
private let type = "space.vaccor.Gemini.activity.browse"
private let encoder = PropertyListEncoder()
private let decoder = PropertyListDecoder()

View File

@ -43,18 +43,33 @@
D664673624BD07F700B0B741 /* RenderingBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673524BD07F700B0B741 /* RenderingBlock.swift */; };
D664673824BD086F00B0B741 /* RenderingBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673724BD086F00B0B741 /* RenderingBlockView.swift */; };
D664673A24BD0B8E00B0B741 /* Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = D664673924BD0B8E00B0B741 /* Fonts.swift */; };
D688F586258AC738003A0A73 /* GeminiHTMLRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F585258AC738003A0A73 /* GeminiHTMLRenderer.swift */; };
D688F590258AC814003A0A73 /* HTMLEntities in Frameworks */ = {isa = PBXBuildFile; productRef = D688F58F258AC814003A0A73 /* HTMLEntities */; };
D688F599258ACAAE003A0A73 /* BrowserWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F598258ACAAE003A0A73 /* BrowserWebViewController.swift */; };
D688F5FF258ACE6B003A0A73 /* browser.css in Resources */ = {isa = PBXBuildFile; fileRef = D688F5FE258ACE6B003A0A73 /* browser.css */; };
D688F633258B09BB003A0A73 /* TrackpadScrollGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F632258B09BB003A0A73 /* TrackpadScrollGestureRecognizer.swift */; };
D688F64A258C17F3003A0A73 /* SymbolCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F649258C17F3003A0A73 /* SymbolCache.swift */; };
D688F65A258C2256003A0A73 /* BrowserNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F659258C2256003A0A73 /* BrowserNavigationController.swift */; };
D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F662258C2479003A0A73 /* UIViewController+Children.swift */; };
D68C1E002703EA13002D642B /* UserActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1DFF2703EA13002D642B /* UserActivities.swift */; };
D68C1E1927055E09002D642B /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1827055E09002D642B /* Intents.intentdefinition */; };
D68C1E1C27055EB0002D642B /* OpenURLIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */; };
D68C1E1E270605A7002D642B /* BrowserHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1D270605A7002D642B /* BrowserHelper.swift */; };
D68C1E25270614F9002D642B /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D68C1E24270614F9002D642B /* Intents.framework */; platformFilter = maccatalyst; };
D68C1E28270614F9002D642B /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E27270614F9002D642B /* IntentHandler.swift */; };
D68C1E2C270614F9002D642B /* GeminiIntents.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = D68C1E23270614F9002D642B /* GeminiIntents.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
D68C1E312706150E002D642B /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1827055E09002D642B /* Intents.intentdefinition */; };
D68C1E3227061557002D642B /* OpenURLIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */; };
D68C1E3327061568002D642B /* UserActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1DFF2703EA13002D642B /* UserActivities.swift */; };
D68C1E34270615D3002D642B /* OpenURLIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */; };
D68C1E35270615D3002D642B /* UserActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1DFF2703EA13002D642B /* UserActivities.swift */; };
D68C1E372706215A002D642B /* MakeRequestIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E362706215A002D642B /* MakeRequestIntentHandler.swift */; };
D68C1E392707A1E5002D642B /* GetBodyIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E382707A1E5002D642B /* GetBodyIntentHandler.swift */; };
D68C1E3B2707BF25002D642B /* GetStatusIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E3A2707BF25002D642B /* GetStatusIntentHandler.swift */; };
D68C1E3D2707C002002D642B /* GetMetaIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E3C2707C002002D642B /* GetMetaIntentHandler.swift */; };
D68C1E3F2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E3E2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift */; };
D68C1E412707CB03002D642B /* GemtextToMarkdownIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E402707CB03002D642B /* GemtextToMarkdownIntentHandler.swift */; };
D68C1E482708A958002D642B /* GeminiMarkdownRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E422707CB69002D642B /* GeminiMarkdownRenderer.swift */; };
D68C1E492708A958002D642B /* GeminiHTMLRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D688F585258AC738003A0A73 /* GeminiHTMLRenderer.swift */; };
D68C1E4A2708A95D002D642B /* GeminiMarkdownRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */; };
D68C1E4B2708A95D002D642B /* GeminiHTMLRendererTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */; };
D68C1E4D2708A981002D642B /* HTMLEntities in Frameworks */ = {isa = PBXBuildFile; productRef = D68C1E4C2708A981002D642B /* HTMLEntities */; };
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A64D25217C6F00348C4B /* Preferences.swift */; };
D691A66725217FD800348C4B /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691A66625217FD800348C4B /* PreferencesView.swift */; };
D69F00AC24BE9DD300E37622 /* GeminiDataTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */; };
@ -211,6 +226,13 @@
remoteGlobalIDString = D62664A724BBF26A00DF9B88;
remoteInfo = GeminiFormat;
};
D68C1E2A270614F9002D642B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D68C1E22270614F9002D642B;
remoteInfo = GeminiIntents;
};
D6E152DA24C0007200FDF9D3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D626645324BBF1C200DF9B88 /* Project object */;
@ -259,6 +281,17 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
D68C1E30270614F9002D642B /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
D68C1E2C270614F9002D642B /* GeminiIntents.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
D6E152C224BFFE2500FDF9D3 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -329,6 +362,19 @@
D68C1E1827055E09002D642B /* Intents.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = Intents.intentdefinition; sourceTree = "<group>"; };
D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenURLIntentHandler.swift; sourceTree = "<group>"; };
D68C1E1D270605A7002D642B /* BrowserHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserHelper.swift; sourceTree = "<group>"; };
D68C1E23270614F9002D642B /* GeminiIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = GeminiIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; };
D68C1E24270614F9002D642B /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
D68C1E27270614F9002D642B /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = "<group>"; };
D68C1E29270614F9002D642B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D68C1E362706215A002D642B /* MakeRequestIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MakeRequestIntentHandler.swift; sourceTree = "<group>"; };
D68C1E382707A1E5002D642B /* GetBodyIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetBodyIntentHandler.swift; sourceTree = "<group>"; };
D68C1E3A2707BF25002D642B /* GetStatusIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetStatusIntentHandler.swift; sourceTree = "<group>"; };
D68C1E3C2707C002002D642B /* GetMetaIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetMetaIntentHandler.swift; sourceTree = "<group>"; };
D68C1E3E2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GemtextToHTMLIntentHandler.swift; sourceTree = "<group>"; };
D68C1E402707CB03002D642B /* GemtextToMarkdownIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GemtextToMarkdownIntentHandler.swift; sourceTree = "<group>"; };
D68C1E422707CB69002D642B /* GeminiMarkdownRenderer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRenderer.swift; sourceTree = "<group>"; };
D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiHTMLRendererTests.swift; sourceTree = "<group>"; };
D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiMarkdownRendererTests.swift; sourceTree = "<group>"; };
D691A64D25217C6F00348C4B /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
D691A66625217FD800348C4B /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; };
D69F00AB24BE9DD300E37622 /* GeminiDataTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiDataTask.swift; sourceTree = "<group>"; };
@ -390,6 +436,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D68C1E4D2708A981002D642B /* HTMLEntities in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -405,7 +452,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D688F590258AC814003A0A73 /* HTMLEntities in Frameworks */,
D62664F024BC0D7700DF9B88 /* GeminiFormat.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -418,6 +464,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D68C1E20270614F9002D642B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D68C1E25270614F9002D642B /* Intents.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D6E1529F24BFFDF500FDF9D3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -452,6 +506,7 @@
children = (
D626645D24BBF1C200DF9B88 /* Gemini */,
D6E152A324BFFDF500FDF9D3 /* Gemini-iOS */,
D68C1E26270614F9002D642B /* GeminiIntents */,
D6E152D124C0007200FDF9D3 /* BrowserCore */,
D6E152DE24C0007200FDF9D3 /* BrowserCoreTests */,
D626647824BBF22E00DF9B88 /* GeminiProtocol */,
@ -478,6 +533,7 @@
D6E152A224BFFDF500FDF9D3 /* Gemini-iOS.app */,
D6E152D024C0007200FDF9D3 /* BrowserCore.framework */,
D6E152D824C0007200FDF9D3 /* BrowserCoreTests.xctest */,
D68C1E23270614F9002D642B /* GeminiIntents.appex */,
);
name = Products;
sourceTree = "<group>";
@ -539,6 +595,8 @@
D62664C724BBF2C600DF9B88 /* Document.swift */,
D62664C524BBF27300DF9B88 /* GeminiParser.swift */,
D6BC9AC4258F01F6008652BC /* TableOfContents.swift */,
D688F585258AC738003A0A73 /* GeminiHTMLRenderer.swift */,
D68C1E422707CB69002D642B /* GeminiMarkdownRenderer.swift */,
);
path = GeminiFormat;
sourceTree = "<group>";
@ -549,6 +607,8 @@
D62664F924BC12BC00DF9B88 /* DocumentTests.swift */,
D62664B724BBF26A00DF9B88 /* GeminiParserTests.swift */,
D6BC9ACD258F07BC008652BC /* TableOfContentsTests.swift */,
D68C1E442707CCDB002D642B /* GeminiHTMLRendererTests.swift */,
D68C1E462707D109002D642B /* GeminiMarkdownRendererTests.swift */,
D62664B924BBF26A00DF9B88 /* Info.plist */,
);
path = GeminiFormatTests;
@ -565,7 +625,6 @@
D62664EB24BC0B4D00DF9B88 /* DocumentView.swift */,
D664673724BD086F00B0B741 /* RenderingBlockView.swift */,
D6DA5782252396030048B65A /* View+Extensions.swift */,
D688F585258AC738003A0A73 /* GeminiHTMLRenderer.swift */,
);
path = GeminiRenderer;
sourceTree = "<group>";
@ -582,6 +641,7 @@
D62664EF24BC0D7700DF9B88 /* Frameworks */ = {
isa = PBXGroup;
children = (
D68C1E24270614F9002D642B /* Intents.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@ -605,11 +665,27 @@
D68C1E1A27055EA0002D642B /* Intents */ = {
isa = PBXGroup;
children = (
D68C1DFF2703EA13002D642B /* UserActivities.swift */,
D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */,
);
path = Intents;
sourceTree = "<group>";
};
D68C1E26270614F9002D642B /* GeminiIntents */ = {
isa = PBXGroup;
children = (
D68C1E27270614F9002D642B /* IntentHandler.swift */,
D68C1E362706215A002D642B /* MakeRequestIntentHandler.swift */,
D68C1E382707A1E5002D642B /* GetBodyIntentHandler.swift */,
D68C1E3A2707BF25002D642B /* GetStatusIntentHandler.swift */,
D68C1E3C2707C002002D642B /* GetMetaIntentHandler.swift */,
D68C1E3E2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift */,
D68C1E402707CB03002D642B /* GemtextToMarkdownIntentHandler.swift */,
D68C1E29270614F9002D642B /* Info.plist */,
);
path = GeminiIntents;
sourceTree = "<group>";
};
D6E152A324BFFDF500FDF9D3 /* Gemini-iOS */ = {
isa = PBXGroup;
children = (
@ -628,7 +704,6 @@
D653F40C26799F2F004E32B1 /* HomepagePrefView.swift */,
D653F40A267996FF004E32B1 /* ActivityItemSource.swift */,
D653F40E2679A0AB004E32B1 /* SetHomepageActivity.swift */,
D68C1DFF2703EA13002D642B /* UserActivities.swift */,
D68C1E1A27055EA0002D642B /* Intents */,
D688F618258AD231003A0A73 /* Resources */,
D6376A6E26DDAF57005AD89C /* Vendor */,
@ -781,6 +856,9 @@
dependencies = (
);
name = GeminiFormat;
packageProductDependencies = (
D68C1E4C2708A981002D642B /* HTMLEntities */,
);
productName = GeminiFormat;
productReference = D62664A824BBF26A00DF9B88 /* GeminiFormat.framework */;
productType = "com.apple.product-type.framework";
@ -821,7 +899,6 @@
);
name = GeminiRenderer;
packageProductDependencies = (
D688F58F258AC814003A0A73 /* HTMLEntities */,
);
productName = GeminiRenderer;
productReference = D62664CE24BC081B00DF9B88 /* GeminiRenderer.framework */;
@ -846,6 +923,23 @@
productReference = D62664D624BC081B00DF9B88 /* GeminiRendererTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
D68C1E22270614F9002D642B /* GeminiIntents */ = {
isa = PBXNativeTarget;
buildConfigurationList = D68C1E2D270614F9002D642B /* Build configuration list for PBXNativeTarget "GeminiIntents" */;
buildPhases = (
D68C1E1F270614F9002D642B /* Sources */,
D68C1E20270614F9002D642B /* Frameworks */,
D68C1E21270614F9002D642B /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = GeminiIntents;
productName = GeminiIntents;
productReference = D68C1E23270614F9002D642B /* GeminiIntents.appex */;
productType = "com.apple.product-type.app-extension";
};
D6E152A124BFFDF500FDF9D3 /* Gemini-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = D6E152B324BFFDF600FDF9D3 /* Build configuration list for PBXNativeTarget "Gemini-iOS" */;
@ -854,6 +948,7 @@
D6E1529F24BFFDF500FDF9D3 /* Frameworks */,
D6E152A024BFFDF500FDF9D3 /* Resources */,
D6E152C224BFFE2500FDF9D3 /* Embed Frameworks */,
D68C1E30270614F9002D642B /* Embed App Extensions */,
);
buildRules = (
);
@ -862,6 +957,7 @@
D68543FC2522DEF5004C4AE0 /* PBXTargetDependency */,
D68543FA2522DEF3004C4AE0 /* PBXTargetDependency */,
D68543F82522DEF0004C4AE0 /* PBXTargetDependency */,
D68C1E2B270614F9002D642B /* PBXTargetDependency */,
);
name = "Gemini-iOS";
productName = "Gemini-iOS";
@ -914,7 +1010,7 @@
D626645324BBF1C200DF9B88 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1200;
LastSwiftUpdateCheck = 1300;
LastUpgradeCheck = 1220;
TargetAttributes = {
D626645A24BBF1C200DF9B88 = {
@ -944,6 +1040,9 @@
CreatedOnToolsVersion = 12.0;
TestTargetID = D626645A24BBF1C200DF9B88;
};
D68C1E22270614F9002D642B = {
CreatedOnToolsVersion = 13.0;
};
D6E152A124BFFDF500FDF9D3 = {
CreatedOnToolsVersion = 12.0;
};
@ -982,6 +1081,7 @@
D62664D524BC081B00DF9B88 /* GeminiRendererTests */,
D6E152CF24C0007200FDF9D3 /* BrowserCore */,
D6E152D724C0007200FDF9D3 /* BrowserCoreTests */,
D68C1E22270614F9002D642B /* GeminiIntents */,
);
};
/* End PBXProject section */
@ -1040,6 +1140,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D68C1E21270614F9002D642B /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D6E152A024BFFDF500FDF9D3 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1106,6 +1213,8 @@
files = (
D62664C824BBF2C600DF9B88 /* Document.swift in Sources */,
D62664C624BBF27300DF9B88 /* GeminiParser.swift in Sources */,
D68C1E492708A958002D642B /* GeminiHTMLRenderer.swift in Sources */,
D68C1E482708A958002D642B /* GeminiMarkdownRenderer.swift in Sources */,
D6BC9AC5258F01F6008652BC /* TableOfContents.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1116,7 +1225,9 @@
files = (
D62664FA24BC12BC00DF9B88 /* DocumentTests.swift in Sources */,
D6BC9ACE258F07BC008652BC /* TableOfContentsTests.swift in Sources */,
D68C1E4A2708A95D002D642B /* GeminiMarkdownRendererTests.swift in Sources */,
D62664B824BBF26A00DF9B88 /* GeminiParserTests.swift in Sources */,
D68C1E4B2708A95D002D642B /* GeminiHTMLRendererTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1129,7 +1240,6 @@
D62664EE24BC0BCE00DF9B88 /* MaybeLazyVStack.swift in Sources */,
D62664EC24BC0B4D00DF9B88 /* DocumentView.swift in Sources */,
D6DA5783252396030048B65A /* View+Extensions.swift in Sources */,
D688F586258AC738003A0A73 /* GeminiHTMLRenderer.swift in Sources */,
D664673824BD086F00B0B741 /* RenderingBlockView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1142,6 +1252,23 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
D68C1E1F270614F9002D642B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D68C1E3227061557002D642B /* OpenURLIntentHandler.swift in Sources */,
D68C1E3B2707BF25002D642B /* GetStatusIntentHandler.swift in Sources */,
D68C1E312706150E002D642B /* Intents.intentdefinition in Sources */,
D68C1E392707A1E5002D642B /* GetBodyIntentHandler.swift in Sources */,
D68C1E3D2707C002002D642B /* GetMetaIntentHandler.swift in Sources */,
D68C1E3F2707C3B2002D642B /* GemtextToHTMLIntentHandler.swift in Sources */,
D68C1E28270614F9002D642B /* IntentHandler.swift in Sources */,
D68C1E412707CB03002D642B /* GemtextToMarkdownIntentHandler.swift in Sources */,
D68C1E372706215A002D642B /* MakeRequestIntentHandler.swift in Sources */,
D68C1E3327061568002D642B /* UserActivities.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D6E1529E24BFFDF500FDF9D3 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1151,7 +1278,9 @@
D688F633258B09BB003A0A73 /* TrackpadScrollGestureRecognizer.swift in Sources */,
D6E152A524BFFDF500FDF9D3 /* AppDelegate.swift in Sources */,
D6E152A724BFFDF500FDF9D3 /* SceneDelegate.swift in Sources */,
D68C1E35270615D3002D642B /* UserActivities.swift in Sources */,
D6376A7026DDAF65005AD89C /* URIFixup.swift in Sources */,
D68C1E34270615D3002D642B /* OpenURLIntentHandler.swift in Sources */,
D653F40B267996FF004E32B1 /* ActivityItemSource.swift in Sources */,
D6BC9AB3258E8E13008652BC /* ToolbarView.swift in Sources */,
D688F64A258C17F3003A0A73 /* SymbolCache.swift in Sources */,
@ -1161,10 +1290,8 @@
D68C1E1927055E09002D642B /* Intents.intentdefinition in Sources */,
D688F663258C2479003A0A73 /* UIViewController+Children.swift in Sources */,
D653F40D26799F2F004E32B1 /* HomepagePrefView.swift in Sources */,
D68C1E1C27055EB0002D642B /* OpenURLIntentHandler.swift in Sources */,
D691A64E25217C6F00348C4B /* Preferences.swift in Sources */,
D6BC9ABC258E9862008652BC /* NavigationBarView.swift in Sources */,
D68C1E002703EA13002D642B /* UserActivities.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1274,6 +1401,11 @@
target = D62664A724BBF26A00DF9B88 /* GeminiFormat */;
targetProxy = D685442F2522E10F004C4AE0 /* PBXContainerItemProxy */;
};
D68C1E2B270614F9002D642B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D68C1E22270614F9002D642B /* GeminiIntents */;
targetProxy = D68C1E2A270614F9002D642B /* PBXContainerItemProxy */;
};
D6E152DB24C0007200FDF9D3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D6E152CF24C0007200FDF9D3 /* BrowserCore */;
@ -1473,6 +1605,7 @@
D626648F24BBF22E00DF9B88 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1506,6 +1639,7 @@
D626649024BBF22E00DF9B88 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1578,6 +1712,7 @@
D62664C024BBF26A00DF9B88 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1611,6 +1746,7 @@
D62664C124BBF26A00DF9B88 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1683,6 +1819,7 @@
D62664E624BC081B00DF9B88 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1716,6 +1853,7 @@
D62664E724BC081B00DF9B88 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
@ -1785,6 +1923,63 @@
};
name = Release;
};
D68C1E2E270614F9002D642B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10;
DEVELOPMENT_TEAM = V4WK9KR9U2;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = GeminiIntents/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = GeminiIntents;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 13.5;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2021.1;
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Gemini.GeminiIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
D68C1E2F270614F9002D642B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 10;
DEVELOPMENT_TEAM = V4WK9KR9U2;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = GeminiIntents/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = GeminiIntents;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 13.5;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 2021.1;
PRODUCT_BUNDLE_IDENTIFIER = space.vaccor.Gemini.GeminiIntents;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
D6E152B424BFFDF600FDF9D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -1841,6 +2036,7 @@
D6E152E824C0007200FDF9D3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@ -1872,6 +2068,7 @@
D6E152E924C0007200FDF9D3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@ -2015,6 +2212,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D68C1E2D270614F9002D642B /* Build configuration list for PBXNativeTarget "GeminiIntents" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D68C1E2E270614F9002D642B /* Debug */,
D68C1E2F270614F9002D642B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D6E152B324BFFDF600FDF9D3 /* Build configuration list for PBXNativeTarget "Gemini-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@ -2056,7 +2262,7 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
D688F58F258AC814003A0A73 /* HTMLEntities */ = {
D68C1E4C2708A981002D642B /* HTMLEntities */ = {
isa = XCSwiftPackageProductDependency;
package = D688F58E258AC814003A0A73 /* XCRemoteSwiftPackageReference "swift-html-entities" */;
productName = HTMLEntities;

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D68C1E22270614F9002D642B"
BuildableName = "GeminiIntents.appex"
BlueprintName = "GeminiIntents"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D6E152A124BFFDF500FDF9D3"
BuildableName = "Gemini-iOS.app"
BlueprintName = "Gemini-iOS"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D6E152A124BFFDF500FDF9D3"
BuildableName = "Gemini-iOS.app"
BlueprintName = "Gemini-iOS"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "D6E152A124BFFDF500FDF9D3"
BuildableName = "Gemini-iOS.app"
BlueprintName = "Gemini-iOS"
ReferencedContainer = "container:Gemini.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -24,6 +24,11 @@
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>GeminiIntents.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
</dict>
<key>GeminiProtocol.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
@ -62,6 +67,11 @@
<key>primary</key>
<true/>
</dict>
<key>D68C1E22270614F9002D642B</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>D6E152A124BFFDF500FDF9D3</key>
<dict>
<key>primary</key>

View File

@ -0,0 +1,30 @@
//
// GemtextToHTMLIntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 10/1/21.
//
import Intents
import GeminiFormat
class GemtextToHTMLIntentHandler: NSObject, GemtextToHTMLIntentHandling {
func handle(intent: GemtextToHTMLIntent, completion: @escaping (GemtextToHTMLIntentResponse) -> Void) {
guard let response = intent.response,
let text = response.body,
let url = response.url else {
completion(GemtextToHTMLIntentResponse(code: .failure, userActivity: nil))
return
}
let doc = GeminiParser.parse(text: text, baseURL: url)
let renderer = GeminiHTMLRenderer()
renderer.addLinkClass = false
renderer.addHeadingLineIDs = false
let html = renderer.renderDocumentToHTML(doc)
let intentResp = GemtextToHTMLIntentResponse(code: .success, userActivity: nil)
intentResp.html = INFile(data: html.data(using: .utf8)!, filename: "converted_gemtext.html", typeIdentifier: "public.html")
completion(intentResp)
}
}

View File

@ -0,0 +1,28 @@
//
// GemtextToMarkdownIntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 10/1/21.
//
import Intents
import GeminiFormat
class GemtextToMarkdownIntentHandler: NSObject, GemtextToMarkdownIntentHandling {
func handle(intent: GemtextToMarkdownIntent, completion: @escaping (GemtextToMarkdownIntentResponse) -> Void) {
guard let response = intent.response,
let text = response.body,
let url = response.url else {
completion(GemtextToMarkdownIntentResponse(code: .failure, userActivity: nil))
return
}
let doc = GeminiParser.parse(text: text, baseURL: url)
let renderer = GeminiMarkdownRenderer()
let html = renderer.renderDocumentToMarkdown(doc)
let intentResp = GemtextToMarkdownIntentResponse(code: .success, userActivity: nil)
intentResp.markdown = INFile(data: html.data(using: .utf8)!, filename: "converted_gemtext.md", typeIdentifier: "net.daringfireball.markdown")
completion(intentResp)
}
}

View File

@ -0,0 +1,22 @@
//
// GetBodyIntenHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 10/1/21.
//
import Intents
class GetBodyIntentHandler: NSObject, GetBodyIntentHandling {
func handle(intent: GetBodyIntent, completion: @escaping (GetBodyIntentResponse) -> Void) {
guard let response = intent.response else {
completion(GetBodyIntentResponse(code: .failure, userActivity: nil))
return
}
let intentResp = GetBodyIntentResponse(code: .success, userActivity: nil)
intentResp.text = response.body
completion(intentResp)
}
}

View File

@ -0,0 +1,22 @@
//
// GetMetaIntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 10/1/21.
//
import Intents
class GetMetaIntentHandler: NSObject, GetMetaIntentHandling {
func handle(intent: GetMetaIntent, completion: @escaping (GetMetaIntentResponse) -> Void) {
guard let response = intent.response else {
completion(GetMetaIntentResponse(code: .failure, userActivity: nil))
return
}
let intentResp = GetMetaIntentResponse(code: .success, userActivity: nil)
intentResp.meta = response.meta
completion(intentResp)
}
}

View File

@ -0,0 +1,22 @@
//
// GetStatusIntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 10/1/21.
//
import Intents
class GetStatusIntentHandler: NSObject, GetStatusIntentHandling {
func handle(intent: GetStatusIntent, completion: @escaping (GetStatusIntentResponse) -> Void) {
guard let response = intent.response else {
completion(GetStatusIntentResponse(code: .failure, userActivity: nil))
return
}
let intentResp = GetStatusIntentResponse(code: .success, userActivity: nil)
intentResp.status = response.status.rawValue as NSNumber
completion(intentResp)
}
}

30
GeminiIntents/Info.plist Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsRestrictedWhileLocked</key>
<array/>
<key>IntentsRestrictedWhileProtectedDataUnavailable</key>
<array/>
<key>IntentsSupported</key>
<array>
<string>GemtextToHTMLIntent</string>
<string>GemtextToMarkdownIntent</string>
<string>GetBodyIntent</string>
<string>GetMetaIntent</string>
<string>GetStatusIntent</string>
<string>MakeRequestIntent</string>
<string>OpenURLIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.intents-service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).IntentHandler</string>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,41 @@
//
// IntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 9/30/21.
//
import Intents
class IntentHandler: INExtension {
override func handler(for intent: INIntent) -> Any? {
switch intent {
// we also need to support extension-based handling because in-app handling isn't support <iOS 14
case is OpenURLIntent:
return OpenURLIntentHandler()
case is MakeRequestIntent:
return MakeRequestIntentHandler()
case is GetBodyIntent:
return GetBodyIntentHandler()
case is GetStatusIntent:
return GetStatusIntentHandler()
case is GetMetaIntent:
return GetMetaIntentHandler()
case is GemtextToHTMLIntent:
return GemtextToHTMLIntentHandler()
case is GemtextToMarkdownIntent:
return GemtextToMarkdownIntentHandler()
default:
return nil
}
}
}

View File

@ -0,0 +1,77 @@
//
// MakeRequestIntentHandler.swift
// GeminiIntents
//
// Created by Shadowfacts on 9/30/21.
//
import Intents
import GeminiProtocol
import BrowserCore
class MakeRequestIntentHandler: NSObject, MakeRequestIntentHandling {
private var task: GeminiDataTask?
func resolveUrl(for intent: MakeRequestIntent, with completion: @escaping (INURLResolutionResult) -> Void) {
guard let url = intent.url,
url.scheme?.lowercased() == "gemini" else {
completion(.unsupported())
return
}
completion(.success(with: url))
}
func handle(intent: MakeRequestIntent, completion: @escaping (MakeRequestIntentResponse) -> Void) {
guard let url = intent.url else {
completion(MakeRequestIntentResponse(code: .failure, userActivity: nil))
return
}
makeRequest(for: url, followRedirects: intent.followRedirects?.boolValue ?? true, completion: completion)
}
private func makeRequest(for url: URL, followRedirects: Bool, completion: @escaping (MakeRequestIntentResponse) -> Void) {
guard let request = try? GeminiRequest(url: url) else {
completion(MakeRequestIntentResponse(code: .failure, userActivity: nil))
return
}
// foo(bar(baz))
// a
task = GeminiDataTask(request: request) { [unowned self] (result) in
switch result {
case let .success(response):
if response.status.isRedirect && followRedirects {
if let newURL = URL(string: response.meta, relativeTo: url) {
self.makeRequest(for: newURL, followRedirects: followRedirects, completion: completion)
} else {
completion(MakeRequestIntentResponse(code: .failure, userActivity: nil))
}
} else {
let intentResp = MakeRequestIntentResponse(code: .success, userActivity: nil)
let displayStr = "\(response.status), \(BrowserHelper.urlForDisplay(url)), '\(response.meta)'"
intentResp.response = Response(identifier: url.absoluteString, display: displayStr)
intentResp.response!.url = url
intentResp.response!.body = response.bodyText
intentResp.response!.status = ResponseStatus(rawValue: response.status.rawValue)!
intentResp.response!.meta = response.meta
// intentResp.status = ResponseStatus(rawValue: response.status.rawValue)!
// intentResp.status = NSNumber(integerLiteral: response.status.rawValue)
// intentResp.statusCategory = ResponseStatusCategory(rawValue: response.status.rawValue / 10)!
// intentResp.meta = response.meta
// intentResp.mimeType = response.mimeType
// intentResp.body = response.bodyText
completion(intentResp)
}
case .failure(_):
completion(MakeRequestIntentResponse(code: .failure, userActivity: nil))
}
}
if #available(iOS 15.0, *) {
task!.attribution = .user
}
task!.resume()
}
}