本文由 简悦SimpRead 转码,原文地址 www.raywenderlich.com
在本教程中,你将发现在Linux上开始开发Swift所需的一切。你将学习......
2018年10月,苹果宣布为Swift提供语言服务器协议支持的工作。一个月后,第二个帖子介绍了SourceKit-LSP。
这些消息对Linux开发人员来说是音乐。每一个公告都证明了在任何编辑器和平台上使用Swift自动完成功能的一个步骤。
在本教程中,你将使用Linux上的Visual Studio Code(VSCode)编辑器对语言服务器协议(LSP)进行试用。你将了解到在Linux上使用VSCode,为VSCode编译LSP扩展,最后使用LLDB调试器调试你的Swift应用程序。
入门
本教程需要对 Linux 和 shell 脚本有基本了解。
要开始,请在你的Linux系统上下载并安装Swift。进入Swift网站并下载适合你的Linux版本的推荐工具链。
截至目前,苹果只支持Ubuntu,所以本教程将使用该版本。
一旦你下载了工具链,在终端窗口中导航到其目录。将FILE替换为你下载的文件名。
sudo apt-get install curl clang libicu-dev git libatomic1 libicu60 libxml2 libcurl4 zlib1g-dev libbsd0 tzdata libssl-dev libsqlite3-dev libblocksruntime-dev libncurses5-dev libdispatch-dev -y
mkdir ~/swift
tar -xvzf FILE -C ~/swift
这一步安装了所需的依赖项,并将工具链解压到~/swift。
要在你的shell中使用Swift,你必须告诉你的shell在哪里可以找到它。用你喜欢的编辑器打开~/.bashrc。然后添加以下一行,将FILE替换为你解压到的Swift目录的名称。
export PATH="~/swift/FILE/usr/bin:$PATH"
这就是了! 你已经在你的系统上安装了 Swift。为了确保一切正常,关闭并重新打开你的终端。接下来输入
swift --version
输出结果应该与下面类似。
Swift version 5.3-dev (LLVM d59da0cbc0, Swift ff36b5ede8)
Target: x86_64-unknown-linux-gnu
接下来,点击本页顶部或底部的 Download Materials 按钮,下载本项目的材料。解压缩文件,然后导航到Starter/文件夹。接下来运行。
swift run
这将构建并运行该项目。
这是一个简单的网络 应用编程接口(API) ,可以存储和检索TODO。一旦你看到服务器在http://localhost:8080上启动,你的服务器就可用了。你可以通过执行以下程序来检查它
curl http://localhost:8080/
在一个新的终端标签中。这应该会返回 "成功了!"。如果是这样,那么接下来的步骤就一切就绪了。
是时候探索语言服务器协议的力量了
介绍语言服务器协议
语言服务器协议 (LSP)_是一个由微软创建的协议。它允许一种语言和一个编辑器或工具之间进行标准化的通信,这样编辑器就可以通过LSP一次性支持所有语言。分别实现对每种语言的支持的时代已经过去了。
该协议就像一个简化版的HTTP。
- 每个消息都由一个头和一个内容部分组成。
- 头部有一个必要的 "Content-Length "字段,表示内容的字节数,以及一个可选的 "Content-Type "字段。
- 内容使用JSON-RPC来描述请求、响应和通知的结构。
例如,想象一下你正在编辑下面的Swift文件。
protocol MyProtocol { }
struct MyStruct: My
在你开始输入: My以使MyStruct符合MyProtocol,你的编辑器将向LSP服务器发送以下textDocument/completion请求。
{
"jsonrpc": "2.0",
"id": 1,
"method": "textDocument/completion", // 1
"params": {
"textDocument": { // 2
"uri": "file://Users/jari/Example.swift"
},
"position": { // 3
"line": 2,
"character": 19
}
}
}
以下是该请求对你的LSP服务器的要求。
method告诉服务器你要发送什么样的命令。在这个例子中,它是`完成'。textDocument告诉服务器它应该查看什么文件。position告诉服务器它应该在文件的哪个位置查找。这两个值都是基于零的。
在收到请求后,LSP服务器--在你的例子中是SourceKit-LSP--将计算出可能的完成情况并发送以下响应。
{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"label": "MyProtocol", // 1
"kind": 8, // 2
"insertText": "Protocol" // 3
}
]
}
id将这个响应与请求联系起来。result中的字段做了以下工作。
label表示在自动完成窗口中显示什么文本。- 结果的 "种类 "告诉编辑器它是哪种完成方式。这可以改变行为。
8表示接口,用于Swift协议。 insertText是将在光标位置插入的实际文本值。在这种情况下,My被剥离,因为它已经被输入了。
这种方法允许编辑器在不知道你正在处理Swift文件的情况下提供自动完成服务。同样地,LSP服务器也不会知道你在使用什么编辑器。你真够阴险的
结合Swift和语言服务器协议
现在你知道了 LSP 的基础知识,是时候在你的机器上工作了。如果你没有安装VSCode,请按照VSCode docs中的说明进行安装。
要安装SourceKit-LSP,在你的 Downloads 目录下运行以下命令。
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - # You can skip this command if you already have node installed.
sudo apt-get install -y nodejs # Same goes for this command.
git clone https://github.com/apple/sourcekit-lsp.git
cd sourcekit-lsp/
这些命令安装了NodeJS并克隆了sourcekit-lsp repo。
要建立 "sourcekit-lsp "项目,请运行以下命令,但将 "FILE "替换为你的工具链的名称,将 "YOURUSER "替换为你的用户名。
swift package update #1
swift build -Xcxx -I/home/YOURUSER/swift/FILE/usr/lib/swift #2
sudo mv .build/x86_64-unknown-linux-gnu/debug/sourcekit-lsp /usr/local/bin #3
这些命令做了以下工作。
- 将 Swift 包更新到所需的最新版本。
- 从源码构建SourceKit-LSP。
-I标志添加了一个额外的目录,C++编译器将在其中寻找.h文件。 - 将构建的二进制文件移到
/usr/local/bin,以便VSCode可以使用它。
接下来,导航到Editors/vscode目录。这个目录包含了你创建VSCode扩展所需的所有内容,该扩展可以启用SourceKit-LSP。
要建立和启用该扩展,请运行以下命令。
npm run createDevPackage && \
code --install-extension out/sourcekit-lsp-vscode-dev.vsix
这使用node和npm来创建和安装扩展到VSCode。
继续使用它吧! 回到你的Todos/Starter目录,运行以下程序。
rm -rf .build/
code .
这将删除.build目录,因为一个bug导致LSP崩溃,如果一个目录已经存在,在当前目录下启动VSCode。
最后,更新以下设置并重新启动VSCode。你可以通过按 Control-+ 并搜索设置的名称来找到你的设置。
"sourcekit-lsp.toolchainPath": "/home/YOURUSER/swift/FILE"
运行swift build,给自己拍拍屁股。你成功地安装了SourceKit-LSP for VSCode :] 。
要检查一切是否成功,在VSCode中打开Sources/App/Controllers/TodoController.swift,将鼠标悬停在任何一个关键词上。VSCode现在应该显示一个带有相关文档的悬停卡。棒极了!
使用自动完成功能
是时候写一些代码了,而且只是一些,因为你的新的LSP自动完成将处理剩下的部分:] 。
在 "index "和 "delete "函数之间添加一个名为 "create "的新函数。
/// Saves a decoded `Todo` to the database.
func create(_ req: Request) throws -> Future<Todo> {
return try req.content.decode(Todo.self).flatMap { todo in
return todo.save(on: req)
}
}
这创建了一个新的方法,根据请求中的信息创建一个新的Todo。
当然,你可以把这段代码复制粘贴进去。然而,为了充分享受你的新自动完成功能,请尝试自己输入它。
要注册你的新路由,打开Sources/App/routes.swift,在router.get和router.delete之间添加以下一行。
router.post("todos", use: todoController.create)
这就把你创建的函数注册为API上的POST端点。为了测试它,运行你的程序并执行以下curl命令。
curl -X POST -H "Content-Type: application/json" -d '{"title": "Debug a swift app on Linux"}' http://localhost:8080/todos
这将会有以下回应。
{
"id":1,
"title":"Debug a swift app on Linux"
}
如果你看到下面的JSON返回,你就知道一切正常了
在Linux上调试Swift
能够在Linux上创建、构建和运行你的Swift应用是非常棒的。毋庸置疑! 但如果有一些讨厌的错误进入你的代码怎么办?那么,你就需要做一些调试了。
现在是时候深入研究如何在Linux上设置 LLDB 了。你可以使用LLDB在你的终端或VSCode中进行调试。
LLDB是Xcode使用的默认调试器。它可以用来调试C、Objective-C、C++和Swift程序。LLDB与Swift工具链打包在一起,这意味着你已经安装了它并准备好使用。
从这里开始,设置一些断点很简单。首先,你将使用LLDB命令行设置这些断点。之后,你将安装一个VSCode扩展,在VSCode内启用断点。
同样在你的 Todos/Starter 文件夹中,建立并运行。
lldb .build/debug/Run
该命令启动LLDB会话。注意,你的程序 还 没有开始。这样,你可以事先设置断点。
在你的LLDB会话中,在你的 routes.swift 第48行设置一个断点,像这样。
breakpoint set -f routes.swift -l 48
LLDB会告诉你它设置断点的位置。
接下来,输入r来运行你的程序。你应该立即碰到你设置的断点。这样你就可以检查周围的变量和执行状态。
运行以下程序。
po router
将会产生类似下面的结果。
<EngineRouter: 0x5555562a0e70>
你已经打印了你的路由器的对象描述。真棒 :]
要继续你的应用程序,只需输入c并按回车键。你会看到正常的项目输出,告诉你迁移已经完成,服务器已经启动。
在VSCode中进行调试
这很酷,但现在你将添加一个扩展,允许你在VSCode内完成所有这些工作。这个扩展被称为CodeLLDB。
要安装它,按 Control+Shift+X 导航到VSCode扩展窗格。搜索 CodeLLDB 并点击安装。
为了配置VSCode使用LLDB作为你的Swift调试器,在你的项目根部创建一个新的文件夹,称为 .vscode 。在这个文件夹中创建两个文件,分别称为 launch.json 和 tasks.json 。
在你的 launch.json 中放入以下内容。
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb", // 1
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/.build/debug/Run", // 2
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "swift-build" // 3
}
]
}
这个JSON告诉VSCode以下内容。
- 这是什么类型的进程。
lldb表示VSCode将使用CodeLLDB。 - 要使用的程序。这是你建立的调试目标。
- 在你的主调试脚本执行之前要运行的预启动任务--本例是建立你的应用程序。
在你的 launch.json 中,我们告诉VSCode在启动调试会话之前执行一个swift-build。你需要定义这个任务。打开 tasks.json ,添加以下JSON。
{
"version": "2.0.0",
"tasks": [
{
"label": "swift-build", // 1
"type": "shell", // 2
"command": "swift build" // 3
}
]
}
这个任务由三个字段组成。
label是_launch.json_的标识符。type是shell,意味着你将运行一个普通的shell命令。command是你要运行的命令,以确保你不会因为忘记重新编译而错过修改。
现在在VSCod,e中打开 routes.swift ,并点击第48行的左边。一个红点会出现,表明你放置了一个断点。按F5来运行你的应用程序。VSCode将首先进行编译,然后进行调试。
你会再次碰到你的断点,但这次你可以使用内置的VSCode调试导航器来继续。
从左到右,这些按钮的含义如下。
- Continue 将继续执行程序,直到碰到下一个断点。
- Step over 将把调试器移到下一行。
- Step in 将深入一个层次--例如,如果你的断点碰到了函数的调用,就会进入函数体。
- Step out 与Step in相反。
- Restart 将重新运行你的调试会话。
- Stop 将停止调试会话。
干得好!
何去何从
你可以使用本页顶部或底部的下载材料按钮下载带有VSCode设置的最终Swift项目。
要了解更多关于 SourceKit-LSP 项目的信息或学习如何用其他编辑器来设置它,请查看 GitHub repo。它是开源的 :] 。
关于如何使用LLDB的更多信息,你可以关注LLDB教程或探索GitHub上的CodeLLDB。
现在你已经建立了你的Linux环境,你可以继续学习Getting Started with Server-Side Swift with Vapor。
如果你有任何意见或问题,请加入下面的论坛!