Add Open URL intent
This commit is contained in:
parent
144695cc96
commit
2b82e3b545
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import Intents
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
@ -32,6 +33,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
|
||||
}
|
||||
|
||||
func application(_ application: UIApplication, handlerFor intent: INIntent) -> Any? {
|
||||
switch intent {
|
||||
case is OpenURLIntent:
|
||||
return OpenURLIntentHandler()
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
|
||||
</array>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
@ -37,8 +33,17 @@
|
|||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>INIntentsSupported</key>
|
||||
<array>
|
||||
<string>OpenURLIntent</string>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>$(PRODUCE_BUNDLE_IDENTIFIER).activity.browse</string>
|
||||
<string>OpenURLIntent</string>
|
||||
</array>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
<?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>INEnums</key>
|
||||
<array/>
|
||||
<key>INIntentDefinitionModelVersion</key>
|
||||
<string>1.2</string>
|
||||
<key>INIntentDefinitionNamespace</key>
|
||||
<string>YzEWx7</string>
|
||||
<key>INIntentDefinitionSystemVersion</key>
|
||||
<string>20F71</string>
|
||||
<key>INIntentDefinitionToolsBuildVersion</key>
|
||||
<string>13A233</string>
|
||||
<key>INIntentDefinitionToolsVersion</key>
|
||||
<string>13.0</string>
|
||||
<key>INIntents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentCategory</key>
|
||||
<string>information</string>
|
||||
<key>INIntentConfigurable</key>
|
||||
<true/>
|
||||
<key>INIntentDescription</key>
|
||||
<string>Open a Gemini link in Rocketeer.</string>
|
||||
<key>INIntentDescriptionID</key>
|
||||
<string>q39SFr</string>
|
||||
<key>INIntentInput</key>
|
||||
<string>url</string>
|
||||
<key>INIntentLastParameterTag</key>
|
||||
<integer>2</integer>
|
||||
<key>INIntentManagedParameterCombinations</key>
|
||||
<dict>
|
||||
<key>url</key>
|
||||
<dict>
|
||||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Open ${url}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>S2D5Se</string>
|
||||
<key>INIntentParameterCombinationUpdatesLinked</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>INIntentName</key>
|
||||
<string>OpenURL</string>
|
||||
<key>INIntentParameterCombinations</key>
|
||||
<dict>
|
||||
<key>url</key>
|
||||
<dict>
|
||||
<key>INIntentParameterCombinationIsLinked</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Open ${url}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>vxeXI3</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>INIntentParameters</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterConfigurable</key>
|
||||
<true/>
|
||||
<key>INIntentParameterDisplayName</key>
|
||||
<string>URL</string>
|
||||
<key>INIntentParameterDisplayNameID</key>
|
||||
<string>8RER8H</string>
|
||||
<key>INIntentParameterDisplayPriority</key>
|
||||
<integer>1</integer>
|
||||
<key>INIntentParameterName</key>
|
||||
<string>url</string>
|
||||
<key>INIntentParameterPromptDialogs</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Configuration</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>What URL would you like to open?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>Bssksg</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Primary</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentParameterSupportsResolution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterTag</key>
|
||||
<integer>2</integer>
|
||||
<key>INIntentParameterType</key>
|
||||
<string>URL</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentResponse</key>
|
||||
<dict>
|
||||
<key>INIntentResponseCodes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentResponseCodeName</key>
|
||||
<string>success</string>
|
||||
<key>INIntentResponseCodeSuccess</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentResponseCodeName</key>
|
||||
<string>failure</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<key>INIntentTitle</key>
|
||||
<string>Open URL</string>
|
||||
<key>INIntentTitleID</key>
|
||||
<string>yqBCLe</string>
|
||||
<key>INIntentType</key>
|
||||
<string>Custom</string>
|
||||
<key>INIntentVerb</key>
|
||||
<string>Open</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INTypes</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// OpenURLIntentHandler.swift
|
||||
// Gemini-iOS
|
||||
//
|
||||
// Created by Shadowfacts on 9/29/21.
|
||||
//
|
||||
|
||||
import Intents
|
||||
import UIKit
|
||||
|
||||
class OpenURLIntentHandler: NSObject, OpenURLIntentHandling {
|
||||
|
||||
func resolveUrl(for intent: OpenURLIntent, 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: OpenURLIntent, completion: @escaping (OpenURLIntentResponse) -> Void) {
|
||||
print("handling intent")
|
||||
guard let url = intent.url,
|
||||
url.scheme?.lowercased() == "gemini" else {
|
||||
completion(OpenURLIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
completion(OpenURLIntentResponse(code: .continueInApp, userActivity: NSUserActivity(geminiURL: url)))
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import SwiftUI
|
|||
import BrowserCore
|
||||
import SafariServices
|
||||
import Combine
|
||||
import Intents
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
|
@ -42,7 +43,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
}
|
||||
|
||||
Preferences.shared.$theme
|
||||
.sink { (newStyle) in
|
||||
.sink { [unowned self] (newStyle) in
|
||||
self.window!.overrideUserInterfaceStyle = newStyle
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
@ -53,6 +54,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
navigationManager.changeURL(context.url)
|
||||
}
|
||||
}
|
||||
|
||||
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
|
||||
if let url = userActivity.geminiURL {
|
||||
navigationManager.changeURL(url)
|
||||
}
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
// Called as the scene is being released by the system.
|
||||
|
@ -87,9 +94,21 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
}
|
||||
|
||||
private func createNavigationManager(for session: UISceneSession, with connectionOptions: UIScene.ConnectionOptions) -> NavigationManager {
|
||||
// try to restore the existing nav manager if there is one
|
||||
if let manager = session.stateRestorationActivity?.navigationManager {
|
||||
// if there's a user activity with a gemini url (e.g., from OpenURLIntentHandler),
|
||||
// navigate the existing manager to that URL
|
||||
if let newURL = connectionOptions.userActivities.first?.geminiURL {
|
||||
manager.changeURL(newURL)
|
||||
}
|
||||
return manager
|
||||
}
|
||||
|
||||
// otherwise, work out the initial URL and create a new manager
|
||||
|
||||
var initialURL: URL? = nil
|
||||
|
||||
if let activity = session.stateRestorationActivity ?? connectionOptions.userActivities.first {
|
||||
if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
|
||||
if let manager = activity.navigationManager {
|
||||
return manager
|
||||
} else if let url = activity.geminiURL {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import Foundation
|
||||
import BrowserCore
|
||||
|
||||
private let type = "space.vaccor.Gemini.activity.browse"
|
||||
private let type = "\(Bundle.main.bundleIdentifier!).activity.browse"
|
||||
private let encoder = PropertyListEncoder()
|
||||
private let decoder = PropertyListDecoder()
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
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 */; };
|
||||
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 */; };
|
||||
|
@ -323,6 +326,9 @@
|
|||
D688F659258C2256003A0A73 /* BrowserNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserNavigationController.swift; sourceTree = "<group>"; };
|
||||
D688F662258C2479003A0A73 /* UIViewController+Children.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Children.swift"; sourceTree = "<group>"; };
|
||||
D68C1DFF2703EA13002D642B /* UserActivities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivities.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -596,6 +602,14 @@
|
|||
path = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D68C1E1A27055EA0002D642B /* Intents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D68C1E1B27055EB0002D642B /* OpenURLIntentHandler.swift */,
|
||||
);
|
||||
path = Intents;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D6E152A324BFFDF500FDF9D3 /* Gemini-iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -615,9 +629,11 @@
|
|||
D653F40A267996FF004E32B1 /* ActivityItemSource.swift */,
|
||||
D653F40E2679A0AB004E32B1 /* SetHomepageActivity.swift */,
|
||||
D68C1DFF2703EA13002D642B /* UserActivities.swift */,
|
||||
D68C1E1A27055EA0002D642B /* Intents */,
|
||||
D688F618258AD231003A0A73 /* Resources */,
|
||||
D6376A6E26DDAF57005AD89C /* Vendor */,
|
||||
D6E152AA24BFFDF600FDF9D3 /* Assets.xcassets */,
|
||||
D68C1E1827055E09002D642B /* Intents.intentdefinition */,
|
||||
D6E152AF24BFFDF600FDF9D3 /* LaunchScreen.storyboard */,
|
||||
D6E152B224BFFDF600FDF9D3 /* Info.plist */,
|
||||
D6E152AC24BFFDF600FDF9D3 /* Preview Content */,
|
||||
|
@ -639,6 +655,7 @@
|
|||
D6E152D224C0007200FDF9D3 /* BrowserCore.h */,
|
||||
D6E152D324C0007200FDF9D3 /* Info.plist */,
|
||||
D69F00AF24BEA84D00E37622 /* NavigationManager.swift */,
|
||||
D68C1E1D270605A7002D642B /* BrowserHelper.swift */,
|
||||
D626646024BBF1C200DF9B88 /* BrowserView.swift */,
|
||||
);
|
||||
path = BrowserCore;
|
||||
|
@ -1141,8 +1158,10 @@
|
|||
D653F40F2679A0AB004E32B1 /* SetHomepageActivity.swift in Sources */,
|
||||
D688F65A258C2256003A0A73 /* BrowserNavigationController.swift in Sources */,
|
||||
D6BC9AD7258FC8B3008652BC /* TableOfContentsView.swift in Sources */,
|
||||
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 */,
|
||||
|
@ -1153,6 +1172,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D68C1E1E270605A7002D642B /* BrowserHelper.swift in Sources */,
|
||||
D6E152F124C000A000FDF9D3 /* NavigationManager.swift in Sources */,
|
||||
D6E152F224C000CD00FDF9D3 /* BrowserView.swift in Sources */,
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "swift-html-entities",
|
||||
"package": "HTMLEntities",
|
||||
"repositoryURL": "https://github.com/Kitura/swift-html-entities",
|
||||
"state": {
|
||||
"branch": null,
|
||||
|
|
Loading…
Reference in New Issue