mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Convert iOS from group to folder. Make Intents a separate group.
This commit is contained in:
@@ -1,143 +0,0 @@
|
||||
//
|
||||
// AddWebFeedIntentHandler.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Maurice Parker on 10/18/19.
|
||||
// Copyright © 2019 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Intents
|
||||
|
||||
public enum AddWebFeedIntentHandlerError: LocalizedError {
|
||||
|
||||
case communicationFailure
|
||||
|
||||
public var errorDescription: String? {
|
||||
switch self {
|
||||
case .communicationFailure:
|
||||
return NSLocalizedString("Unable to communicate with NetNewsWire.", comment: "Communication failure")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AddWebFeedIntentHandler: NSObject, AddWebFeedIntentHandling {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func resolveUrl(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedUrlResolutionResult) -> Void) {
|
||||
guard let url = intent.url else {
|
||||
completion(.unsupported(forReason: .required))
|
||||
return
|
||||
}
|
||||
completion(.success(with: url))
|
||||
}
|
||||
|
||||
public func provideAccountNameOptions(for intent: AddWebFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) {
|
||||
guard let extensionContainers = ExtensionContainersFile.read() else {
|
||||
completion(nil, AddWebFeedIntentHandlerError.communicationFailure)
|
||||
return
|
||||
}
|
||||
|
||||
let accountNames = extensionContainers.accounts.map { $0.name }
|
||||
completion(accountNames, nil)
|
||||
}
|
||||
|
||||
public func resolveAccountName(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedAccountNameResolutionResult) -> Void) {
|
||||
guard let accountName = intent.accountName else {
|
||||
completion(AddWebFeedAccountNameResolutionResult.notRequired())
|
||||
return
|
||||
}
|
||||
|
||||
guard let extensionContainers = ExtensionContainersFile.read() else {
|
||||
completion(.unsupported(forReason: .communication))
|
||||
return
|
||||
}
|
||||
|
||||
if extensionContainers.findAccount(forName: accountName) == nil {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
} else {
|
||||
completion(.success(with: accountName))
|
||||
}
|
||||
}
|
||||
|
||||
public func provideFolderNameOptions(for intent: AddWebFeedIntent, with completion: @escaping ([String]?, Error?) -> Void) {
|
||||
guard let extensionContainers = ExtensionContainersFile.read() else {
|
||||
completion(nil, AddWebFeedIntentHandlerError.communicationFailure)
|
||||
return
|
||||
}
|
||||
|
||||
guard let accountName = intent.accountName, let account = extensionContainers.findAccount(forName: accountName) else {
|
||||
completion([String](), nil)
|
||||
return
|
||||
}
|
||||
|
||||
let folderNames = account.folders.map { $0.name }
|
||||
completion(folderNames, nil)
|
||||
}
|
||||
|
||||
public func resolveFolderName(for intent: AddWebFeedIntent, with completion: @escaping (AddWebFeedFolderNameResolutionResult) -> Void) {
|
||||
guard let accountName = intent.accountName, let folderName = intent.folderName else {
|
||||
completion(AddWebFeedFolderNameResolutionResult.notRequired())
|
||||
return
|
||||
}
|
||||
|
||||
guard let extensionContainers = ExtensionContainersFile.read() else {
|
||||
completion(.unsupported(forReason: .communication))
|
||||
return
|
||||
}
|
||||
|
||||
guard let account = extensionContainers.findAccount(forName: accountName) else {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
return
|
||||
}
|
||||
|
||||
if account.findFolder(forName: folderName) == nil {
|
||||
completion(.unsupported(forReason: .invalid))
|
||||
} else {
|
||||
completion(.success(with: folderName))
|
||||
}
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
public func handle(intent: AddWebFeedIntent, completion: @escaping (AddWebFeedIntentResponse) -> Void) {
|
||||
guard let url = intent.url, let extensionContainers = ExtensionContainersFile.read() else {
|
||||
completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
let account: ExtensionAccount? = {
|
||||
if let accountName = intent.accountName {
|
||||
return extensionContainers.findAccount(forName: accountName)
|
||||
} else {
|
||||
return extensionContainers.accounts.first
|
||||
}
|
||||
}()
|
||||
|
||||
guard let validAccount = account else {
|
||||
completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
let container: ExtensionContainer? = {
|
||||
if let folderName = intent.folderName {
|
||||
return validAccount.findFolder(forName: folderName)
|
||||
} else {
|
||||
return validAccount
|
||||
}
|
||||
}()
|
||||
|
||||
guard let validContainer = container, let containerID = validContainer.containerID else {
|
||||
completion(AddWebFeedIntentResponse(code: .failure, userActivity: nil))
|
||||
return
|
||||
}
|
||||
|
||||
let request = ExtensionFeedAddRequest(name: nil, feedURL: url, destinationContainerID: containerID)
|
||||
ExtensionFeedAddRequestFile.save(request)
|
||||
completion(AddWebFeedIntentResponse(code: .success, userActivity: nil))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,314 +0,0 @@
|
||||
<?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.1</string>
|
||||
<key>INIntentDefinitionNamespace</key>
|
||||
<string>U6u7RF</string>
|
||||
<key>INIntentDefinitionSystemVersion</key>
|
||||
<string>19D76</string>
|
||||
<key>INIntentDefinitionToolsBuildVersion</key>
|
||||
<string>11B53</string>
|
||||
<key>INIntentDefinitionToolsVersion</key>
|
||||
<string>11.2.1</string>
|
||||
<key>INIntents</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentCategory</key>
|
||||
<string>create</string>
|
||||
<key>INIntentConfigurable</key>
|
||||
<true/>
|
||||
<key>INIntentDescription</key>
|
||||
<string>Add a web feed</string>
|
||||
<key>INIntentDescriptionID</key>
|
||||
<string>IuAbef</string>
|
||||
<key>INIntentIneligibleForSuggestions</key>
|
||||
<true/>
|
||||
<key>INIntentInput</key>
|
||||
<string>url</string>
|
||||
<key>INIntentKeyParameter</key>
|
||||
<string>url</string>
|
||||
<key>INIntentLastParameterTag</key>
|
||||
<integer>4</integer>
|
||||
<key>INIntentManagedParameterCombinations</key>
|
||||
<dict>
|
||||
<key>url,accountName</key>
|
||||
<dict>
|
||||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Add ${url} to ${accountName}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>kaKsEY</string>
|
||||
<key>INIntentParameterCombinationUpdatesLinked</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>url,accountName,folderName</key>
|
||||
<dict>
|
||||
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterCombinationTitle</key>
|
||||
<string>Add ${url} to ${folderName} in ${accountName}</string>
|
||||
<key>INIntentParameterCombinationTitleID</key>
|
||||
<string>dkSFD2</string>
|
||||
<key>INIntentParameterCombinationUpdatesLinked</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>INIntentName</key>
|
||||
<string>AddWebFeed</string>
|
||||
<key>INIntentParameters</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterDisplayName</key>
|
||||
<string>URL</string>
|
||||
<key>INIntentParameterDisplayNameID</key>
|
||||
<string>BCHr23</string>
|
||||
<key>INIntentParameterDisplayPriority</key>
|
||||
<integer>1</integer>
|
||||
<key>INIntentParameterName</key>
|
||||
<string>url</string>
|
||||
<key>INIntentParameterPromptDialogs</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>What is the ${url} you would like add?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>jLLidQ</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>
|
||||
<key>INIntentParameterUnsupportedReasons</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>required</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>You must supply a URL.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>4xjRes</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterCustomDisambiguation</key>
|
||||
<true/>
|
||||
<key>INIntentParameterDisplayName</key>
|
||||
<string>Account Name</string>
|
||||
<key>INIntentParameterDisplayNameID</key>
|
||||
<string>CSrgUY</string>
|
||||
<key>INIntentParameterDisplayPriority</key>
|
||||
<integer>2</integer>
|
||||
<key>INIntentParameterMetadata</key>
|
||||
<dict>
|
||||
<key>INIntentParameterMetadataCapitalization</key>
|
||||
<string>Sentences</string>
|
||||
</dict>
|
||||
<key>INIntentParameterName</key>
|
||||
<string>accountName</string>
|
||||
<key>INIntentParameterPromptDialogs</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Primary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>There are ${count} options matching ‘${accountName}’.</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>IbqUVS</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationIntroduction</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Which one?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>fWs3li</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationSelection</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Just to confirm, you wanted ‘${accountName}’?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>HHiZUh</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Confirmation</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentParameterSupportsDynamicEnumeration</key>
|
||||
<true/>
|
||||
<key>INIntentParameterSupportsResolution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterTag</key>
|
||||
<integer>3</integer>
|
||||
<key>INIntentParameterType</key>
|
||||
<string>String</string>
|
||||
<key>INIntentParameterUnsupportedReasons</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>invalid</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>A valid Account Name is required.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>JGkCuS</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>communication</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>Unable to communicate with NetNewsWire.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>uSfloN</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterCustomDisambiguation</key>
|
||||
<true/>
|
||||
<key>INIntentParameterDisplayName</key>
|
||||
<string>Folder Name</string>
|
||||
<key>INIntentParameterDisplayNameID</key>
|
||||
<string>zXhMPF</string>
|
||||
<key>INIntentParameterDisplayPriority</key>
|
||||
<integer>3</integer>
|
||||
<key>INIntentParameterMetadata</key>
|
||||
<dict>
|
||||
<key>INIntentParameterMetadataCapitalization</key>
|
||||
<string>Sentences</string>
|
||||
</dict>
|
||||
<key>INIntentParameterName</key>
|
||||
<string>folderName</string>
|
||||
<key>INIntentParameterPromptDialogs</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Primary</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>There are ${count} options matching ‘${folderName}’.</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>5CYbGL</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationIntroduction</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Which one?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>gEzXaM</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>DisambiguationSelection</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterPromptDialogCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterPromptDialogFormatString</key>
|
||||
<string>Just to confirm, you wanted ‘${folderName}’?</string>
|
||||
<key>INIntentParameterPromptDialogFormatStringID</key>
|
||||
<string>k5GTo0</string>
|
||||
<key>INIntentParameterPromptDialogType</key>
|
||||
<string>Confirmation</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INIntentParameterRelationship</key>
|
||||
<dict>
|
||||
<key>INIntentParameterRelationshipParentName</key>
|
||||
<string>accountName</string>
|
||||
<key>INIntentParameterRelationshipPredicateName</key>
|
||||
<string>HasAnyValue</string>
|
||||
</dict>
|
||||
<key>INIntentParameterSupportsDynamicEnumeration</key>
|
||||
<true/>
|
||||
<key>INIntentParameterSupportsResolution</key>
|
||||
<true/>
|
||||
<key>INIntentParameterTag</key>
|
||||
<integer>4</integer>
|
||||
<key>INIntentParameterType</key>
|
||||
<string>String</string>
|
||||
<key>INIntentParameterUnsupportedReasons</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>invalid</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>A valid Folder Name is required.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>ef5kBt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>INIntentParameterUnsupportedReasonCode</key>
|
||||
<string>communication</string>
|
||||
<key>INIntentParameterUnsupportedReasonCustom</key>
|
||||
<true/>
|
||||
<key>INIntentParameterUnsupportedReasonFormatString</key>
|
||||
<string>Unable to communicate with NetNewsWire.</string>
|
||||
<key>INIntentParameterUnsupportedReasonFormatStringID</key>
|
||||
<string>ExjqcE</string>
|
||||
</dict>
|
||||
</array>
|
||||
</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>Add Web Feed</string>
|
||||
<key>INIntentTitleID</key>
|
||||
<string>oV681v</string>
|
||||
<key>INIntentType</key>
|
||||
<string>Custom</string>
|
||||
<key>INIntentVerb</key>
|
||||
<string>Add</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>INTypes</key>
|
||||
<array/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,30 +0,0 @@
|
||||
"4xjRes" = "You must supply a URL.";
|
||||
|
||||
"8Dh9Yy" = "No feed was found at the specified URL.";
|
||||
|
||||
"BCHr23" = "URL";
|
||||
|
||||
"CSrgUY" = "Account Name";
|
||||
|
||||
"HHiZUh" = "Just to confirm, you wanted ‘${accountName}’?";
|
||||
|
||||
"IbqUVS" = "There are ${count} options matching ‘${accountName}’.";
|
||||
|
||||
"IuAbef" = "Add a feed";
|
||||
|
||||
"JGkCuS" = "An account name is required.";
|
||||
|
||||
"UGGPkp" = "You are already subscribed to this feed in this account.";
|
||||
|
||||
"dkSFD2" = "Add${url}to ${accountName}";
|
||||
|
||||
"drQfaI" = "No feed was found at the specified URL.";
|
||||
|
||||
"fWs3li" = "Which one?";
|
||||
|
||||
"jLLidQ" = "What is the ${url}you would like add?";
|
||||
|
||||
"oV681v" = "Add Feed";
|
||||
|
||||
"srME8b" = "You are already subscribed to this feed in this account.";
|
||||
|
||||
Reference in New Issue
Block a user