使用 Swift 编写 GNOME 应用

得益于其简洁的语法、静态类型以及使代码更易于编写的特殊功能,Swift 非常适合创建用户界面。 结果构建器与 Swift 的 闭包表达式语法相结合,可以显著提高代码的可读性。

Adwaita for Swift 利用 Swift 的这些特性,为开发 GNOME 平台的应用程序提供直观的界面。 GNOME 是一个流行的开源 Linux 桌面环境,以其对简洁性和可访问性的重视而闻名。 它提供直观的用户界面,以及使用其现代 Adwaita 设计语言构建的庞大应用程序生态系统。 在 GNOME 应用程序 中探索一系列出色的应用程序。

让我们看一个使用 Adwaita for Swift 的代码示例。 以下代码片段定义了一个 view,它表示窗口内用户界面的一部分。

struct Counter: View {

    @State private var count = 0

    var view: Body {
        HStack {
            Button(icon: .default(icon: .goPrevious)) {
                count -= 1
            }
            Text("\(count)")
                .style("title-1")
                .frame(minWidth: 100)
            Button(icon: .default(icon: .goNext)) {
                count += 1
            }
        }
    }

}

视图可以嵌套在其他视图中,或者作为窗口的子视图添加。

它的内容可以从该视图外部修改,并受其在视图层次结构中位置的影响。 这使得组合视图以产生不同的结果变得更容易。 屏幕截图显示了一种简单的可能性。

A screenshot of the counter example app.

动机

此软件包的主要动机是出于上述所有原因,在编写 GNOME 应用程序时能够使用 Swift。 但还有一些其他原因

声明式

虽然已经有适用于许多现代编程语言(包括 Rust、Python 和 JavaScript)的 libadwaita 和 GTK 绑定,但所有官方绑定都遵循命令式编码风格。 当用户界面使用一系列命令构建时,这可能比声明式风格更冗长且更难理解。 以下 Python 代码用作对此的说明。

class Counter(Gtk.Box):

    def __init__(self):
        Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
        self.count = 0

        button_prev = Gtk.Button.new_from_icon_name("go-previous", Gtk.IconSize.BUTTON)
        button_prev.connect("clicked", self.on_prev_clicked)
        self.pack_start(button_prev, True, True, 0)

        self.label = Gtk.Label(label=str(self.count))
        self.label.set_name("title-1")
        self.pack_start(self.label, True, True, 0)

        button_next = Gtk.Button.new_from_icon_name("go-next", Gtk.IconSize.BUTTON)
        button_next.connect("clicked", self.on_next_clicked)
        self.pack_start(button_next, True, True, 0)

    def on_prev_clicked(self, button):
        self.count -= 1
        self.label.set_text(str(self.count))

    def on_next_clicked(self, button):
        self.count += 1
        self.label.set_text(str(self.count))

此 Python 代码使用 PyGObject 库,并生成与上面的 Swift 代码相同的用户界面。

易用性

正如你所看到的,Adwaita for Swift 是围绕数据构建的。 例如,在示例应用程序中按下其中一个按钮时更改变量 count 将自动更新用户界面。 传统的绑定需要你对持有小部件的对象调用一个函数,该小部件应在值更改时更新其内容。

如果你决定将值存储在磁盘上,以便在应用程序启动之间保持持久性,则必须使用传统绑定为代码添加大量复杂性。 Adwaita for Swift 使你能够简单地为应存储的变量添加唯一标识符,并将处理其余部分。

@State("count") private var count = 0

还有一种使用 Localized 软件包进行本地化的简单而安全的方法。

可读性

数据中心方法带来的简洁性对可读性产生了积极影响。

另一点是用户界面本身的声明式定义。 你可以专注于应用程序应该是什么样子以及它应该如何表现,而不是如何实现这些结果。

虽然还有其他可用的解决方案,例如 使用 XML 定义 UIBlueprint,但它们要求用户界面和实际代码在不同的文件中编写。 此外,每当数据更改时,都必须手动更新用户界面。 这使得读者更难理解逻辑。

由于用户界面是用 Swift 编写的,因此你可以直接在用户界面定义中使用方便的 Swift 语法。

var view: Body {
    if count == 0 {
        Text("😍")
    } else {
        Text("\(count)")
    }
}

跨平台应用程序开发

Adwaita for Swift 在许多方面都很有用

发布应用

除了传统的发行包之外,Adwaita for Swift 与 Flathub 配合使用效果也很好。 Flathub 是一个由 Flatpak 驱动的应用商店,它简化了桌面 Linux 应用程序的安装和发布。

用于 Swift 5 的 Freedesktop SDK 扩展,它增加了对 Swift 的支持,以及一个 将 Swift Package Manager 依赖项转换为 Flatpak 源的工具

Adwaita for Swift 文档中了解如何发布你的应用程序。

参与其中

非常感谢您对该项目的每一份贡献。

你可以

感谢你的参与 ❤️