一个使用 Swift 编写的 iOS 14 捷径创建工具,灵感来自 SwiftUI。
SwiftShortcuts 使用 Swift Package Manager 分发。 要将其安装到项目中,请将其作为依赖项添加到您的 Package.swift
清单文件中
let package = Package(
...
dependencies: [
.package(url: "https://github.com/a2/swift-shortcuts.git", from: "1.0.0")
],
...
)
然后在您想要使用它的项目的任何位置导入 SwiftShortcuts
import SwiftShortcuts
SwiftShortcuts 的灵感来自 SwiftUI,正如每个 SwiftUI View
都是由其他 View
类型组成一样,每个 Shortcut
也是由其他 Shortcut
类型构建的。 Shortcut
协议的唯一要求是一个名为 body
的实例属性,其类型是另一个 Shortcut
/// A type that represents a user workflow, or a part of one, in the Shortcuts app.
public protocol Shortcut {
/// The type of shortcut representing the body of this shortcut.
///
/// When you create a custom shortcut, Swift infers this type from your
/// implementation of the required `body` property.
associatedtype Body: Shortcut
/// The contents of the shortcut.
var body: Body { get }
}
要开始编写您自己的快捷方式,请创建一个符合 Shortcut 协议的类型(例如 struct
)。 首先,返回一个带有 “Hello, world!” 文本的 Comment
。
// main.swift
struct HelloWorldShortcut: Shortcut {
var body: some Shortcut {
Comment("Hello, world!")
}
}
要创建一个可以导入到“捷径”应用程序的文件,请在您的快捷方式上调用 build()
函数,并将 Data
写入文件。
// continued from above
let shortcut = HelloWorldShortcut()
let data = try shortcut.build()
try data.write(to: URL(fileURLWithPath: "Hello World.shortcut"))
现在您可以将 *Hello World.shortcut* 文件共享(例如,通过 AirDrop)到您的设备,它将在“捷径”应用程序中打开。 遗憾的是,iOS 13 不支持打开序列化的 .shortcut
文件。
将 BatteryLevel
快捷方式的输出保存到 OutputVariable
,稍后在 ShowResult
快捷方式中引用该值。
// Swift 5.2
import SwiftShortcuts
struct BatteryLevelShortcut: Shortcut {
@OutputVariable var batteryLevel: Variable
var body: some Shortcut {
ShortcutGroup {
Comment("This Shortcut was generated in Swift.")
BatteryLevel()
.savingOutput(to: $batteryLevel)
If(batteryLevel < Number(20), then: {
SetLowPowerMode(true)
ShowResult("Your battery level is \(batteryLevel)%; you might want to charge soon.")
}, else: {
ShowResult("Your battery level is \(batteryLevel)%; you're probably fine for now.")
})
}
}
}
利用 usingResult()
函数将快捷方式输出链接到快捷方式输入。
// Swift 5.2
import SwiftShortcuts
struct ClapAlongShortcut: Shortcut {
var body: some Shortcut {
ShortcutGroup {
Comment("This Shortcut was generated in Swift.")
AskForInput(prompt: "WHAT 👏 DO 👏 YOU 👏 WANT 👏 TO 👏 SAY")
.usingResult { providedInput in
ChangeCase(variable: providedInput, target: .value(.uppercase))
}
.usingResult { changedCaseText in
ReplaceText(variable: changedCaseText, target: "[\\s]", replacement: " 👏 ", isRegularExpression: true)
}
.usingResult { updatedText in
ChooseFromMenu(items: [
MenuItem(label: "Share") {
Share(input: updatedText)
},
MenuItem(label: "Copy to Clipboard") {
CopyToClipboard(content: updatedText)
},
])
}
}
}
}
一个更复杂的示例,使用 small.cat 服务临时缩短 URL 或一些文本。
// Swift 5.2
import SwiftShortcuts
struct ShortenWithSmallCatShortcut: Shortcut {
@OutputVariable var url: Variable
@OutputVariable var expiry: Variable
var body: some Shortcut {
ShortcutGroup {
GetType(input: .shortcutInput)
.usingResult { type in
If(type == "URL", then: {
Text("\(.shortcutInput)")
}, else: {
GetClipboard()
})
}
.usingResult { ifResult in
URLEncode(input: "\(ifResult)")
}
.savingOutput(to: $url)
ChooseFromMenu(prompt: "Expires in:", items: [
MenuItem(label: "10 minutes") {
Text("10")
},
MenuItem(label: "1 hour") {
Text("60")
},
MenuItem(label: "1 day") {
Text("1440")
},
MenuItem(label: "1 week") {
Text("10080")
},
])
.savingOutput(to: $expiry)
GetContentsOfURL(method: .POST, url: "https://small.cat/entries", body: .form([
"entry[duration]": "\(expiry)",
"entry[value]": "\(url)",
"utf8": "✓",
])).usingResult { contents in
GetURLsFromInput(input: "\(contents)")
}.usingResult { urls in
FilterFiles(input: urls, filters: .all([
NameFilter(beginsWith: "http://small.cat/"),
NameFilter(isNot: "http://small.cat/"),
]), limit: 1)
}.usingResult { url in
ChooseFromMenu(items: [
MenuItem(label: "Copy") {
CopyToClipboard(content: url)
},
MenuItem(label: "Share") {
Share(input: url)
},
MenuItem(label: "Show") {
ShowAlert(title: "Small.cat", message: "\(url)", showsCancelButton: false)
},
])
}
}
}
}
SwiftShortcuts 最初名为 ShortcutsSwift,最初的灵感来自 Shortcuts JS。 SwiftShortcuts 和之前的 ShortcutsSwift 都旨在成为 Swift 中类似于 JavaScript 中 Shortcuts JS 的工具。
此版本 SwiftShortcuts 的目标是使使用 Swift 编写“捷径”应用程序工作流程就像在 SwiftUI 中组合 View
一样容易。 正如您在上面看到的,即使是基本的 Shortcut
协议也深受 SwiftUI 的 View
协议的启发。
此存储库不包含每个“捷径”支持的操作,也不包含这些快捷方式的每个可能的参数排列。 请随时贡献缺失的快捷方式类型,甚至测试用例。
SwiftShortcuts 在 MIT 许可证下可用。 有关更多信息,请参见LICENSE文件。
灵感来自Publish背后的支持模型。
SwiftShortcuts 完全公开开发,非常欢迎您的贡献。
此项目不提供基于 GitHub Issues 的支持,而是鼓励用户积极参与其持续开发 — 通过修复他们遇到的任何错误,或者通过改进发现缺乏的文档。
如果您希望进行更改,请打开一个 Pull Request — 即使它只包含您计划更改的草稿,或者重现问题的测试 — 我们可以从那里进一步讨论。
希望您喜欢使用 SwiftShortcuts!