Highlight
Swift AWS Lambda Runtime 让开发者用 Swift 编写 AWS Lambda 函数,在 Xcode 里用本地 runtime simulator 调试,并通过 Amazon Linux 2 Swift toolchain 打包部署到 AWS Lambda。
核心内容
很多 Apple 平台 App 都有一段服务器端逻辑。客户端负责界面和设备能力,服务器端负责访问设备上没有的数据、处理后台任务,或者承接计算量更重的工作。问题是,两端常常使用不同语言、不同工具链、不同调试方式,团队也会被切成客户端和服务器端两套节奏。
Serverless function(无服务器函数)把这件事缩小到一个事件处理函数。AWS Lambda 接收事件,按需分配计算资源,空闲时不需要开发者自己维护专用服务器。演讲里给出的判断很直接:计算资源使用率会影响系统成本,而 Swift 的低资源占用和开发友好性适合这类短小、事件驱动的任务。
Apple 展示的方案是 Swift AWS Lambda Runtime。开发者在 Swift Package 里写一个 executable product,引入 runtime library,然后用 Lambda.run 注册处理逻辑。最小版本只有一个闭包;性能敏感版本可以接入 NIO 的 EventLoop;常见 JSON payload 可以直接交给 Codable 类型。
真正改变开发体验的是本地调试。演讲的 demo 把 Lambda 和 iOS app 放在同一个 Xcode workspace 里。开发者给 Lambda target 设置 LOCAL_LAMBDA_SERVER_ENABLED=true,runtime 会在本机启动一个模拟 AWS Lambda runtime engine 的 HTTP server,监听 localhost:7000 的 invoke endpoint。Xcode 同时管理 iOS app 和 Lambda 两个进程,断点能从客户端请求一路打到 Lambda 处理函数,再回到客户端响应处理。
部署流程也没有离开 Swift。示例脚本创建基于 Swift.org Amazon Linux 2 image 的 Docker image,在容器里编译 Lambda executable,把可执行文件和依赖打成 AWS Lambda 需要的 zip,再通过 AWS CLI 上传并通知新代码版本。上线后,AWS Lambda runtime engine 负责拉取 work、调用用户函数、提交结果;API Gateway、S3、SQS、SNS 或自定义事件都可以成为触发入口。
详细内容
用闭包写最小 Lambda
(02:02)最小 API 从 AWSLambdaRuntime 开始。Lambda.run 接收一个闭包,闭包拿到 context、事件 payload 和 completion handler。runtime library 管理程序生命周期,并负责和底层平台交互。
import AWSLambdaRuntime
Lambda.run { (_, name: String, callback) in
callback(.success("Hello, \(name)!"))
}
关键点:
import AWSLambdaRuntime引入 Swift AWS Lambda Runtime library。Lambda.run注册 Lambda 的处理入口,runtime 会在事件 payload 可用时调用它。- 第一个参数是 context,这个最小示例没有使用,所以写成
_。 name: String是事件 payload,示例把它当作字符串输入。callback(.success(...))在工作完成后把结果交回 runtime。
用 EventLoop 处理性能敏感场景
(02:33)第二个 API 是 protocol-oriented 写法,面向性能敏感 use case。它暴露 NIO EventLoop,让 Lambda 处理函数和 networking processing stack 共享同一条线程,从而减少 context switch。代价是 handler 不能阻塞 event loop。
import AWSLambdaRuntime
import NIO
struct Handler: EventLoopLambdaHandler {
typealias In = String
typealias Out = String
func handle(context: Lambda.Context, event: String) -> EventLoopFuture<String> {
context.eventLoop.makeSucceededFuture("Hello, \(event)!")
}
}
Lambda.run(Handler())
关键点:
EventLoopLambdaHandler是面向 EventLoop 的 handler 协议。typealias In和typealias Out声明输入、输出类型,这里都是String。handle(context:event:)返回EventLoopFuture<String>,结果交给 NIO 的异步模型。context.eventLoop.makeSucceededFuture(...)在当前 event loop 上创建成功 future。Lambda.run(Handler())把结构体 handler 交给 runtime 运行。
用 Codable 处理 JSON payload
(02:59)演讲随后把字符串 payload 换成 request / response 结构体。Lambda payload 通常基于 JSON,Swift 的 Codable 可以完成 JSON 与 Swift 类型之间的序列化。
import AWSLambdaRuntime
struct Request: Codable {
let name: String
let password: String
}
struct Response: Codable {
let message: String
}
Lambda.run { (_, request: Request, callback) in
callback(.success(Response(message: "Hello, \(request.name)!")))
}
关键点:
Request表示输入事件,演讲里的 demo 用它承载注册表单的name和password。Response表示 Lambda 返回给客户端的 JSON 结果。- 两个类型都遵循
Codable,runtime 可以把 JSON payload 转成 Swift 类型,再把 Swift 结果转回 JSON。 - 闭包参数
request: Request让处理函数直接面对业务类型。 Response(message: ...)是返回值,completion handler 把它交回 runtime。
在 Xcode 里调试客户端和 Lambda
(04:22)演讲的 Xcode demo 用一个 workspace 放两个项目:一个 Lambda package manager project,一个 iOS app。Lambda target 直接运行会报错,因为本地没有真正的 AWS Lambda runtime engine。解决方式是编辑 scheme,把 LOCAL_LAMBDA_SERVER_ENABLED 设为 true。
(05:09)再次运行后,本地 server 会监听 localhost:7000,并在 invoke endpoint 接收事件。iOS app 通过 URLSession 向这个地址发送注册请求。Xcode 同时管理两个进程:iOS app 和 Lambda function。演讲里依次在构造 request、进入 Lambda function、处理 response 三处命中断点,还用 LLDB 检查返回值。
(07:08)这个调试模式只用于本地。要让已部署 Lambda 通过 HTTP 被客户端访问,需要先通过 AWS API Gateway 暴露 endpoint。demo 的重点是开发阶段:客户端和云端函数可以在同一个 Xcode 调试会话里串起来。
打包并部署到 AWS Lambda
(07:53)部署 demo 使用一个包装 AWS CLI 的脚本。脚本先创建基于 Swift.org Amazon Linux 2 image 的 Docker image,再在容器里编译 Lambda function。随后它把 executable 和依赖打成 zip,这正是 AWS Lambda 期望的包格式,最后上传 zip 并通知新的 code version。
(09:33)这套部署能力依赖两个基础组件。第一,Swift.org 从 2020 年 5 月开始发布面向 Amazon Linux 2 的 Swift toolchain,可用于 EC2 和 AWS Lambda 等 AWS compute service。第二,Swift Lambda runtime library 实现了 AWS Lambda runtime API,提供从简单闭包到性能敏感 event handler 的多层 API。
(10:14)runtime library 内部包含 Lifecycle Loop 和状态机,负责从 runtime engine queue 拉取 work、把 work 交给用户函数、再把结果提交回 runtime engine。它还内嵌一个为 AWS Lambda runtime context 调优的 asynchronous HTTP client。编译后的程序把用户代码、runtime library 和 Swift dependencies 链接成 executable,依需求可以静态或动态链接。
(11:15)AWS Lambda 可以按需求运行多个 serverless function 副本,所以函数应该保持 stateless。演讲特别提醒要避免 global mutable state,也要避免持有超过需要时间的内存。触发入口可以来自 S3、SQS、SNS、通过 API Gateway 暴露的 HTTP endpoint,或者用户添加的自定义事件。
核心启发
-
做一个 Swift 写的注册后端:把 iOS 注册表单提交给 Swift Lambda,输入用
Request: Codable,输出用Response: Codable。为什么值得做:演讲完整演示了 iOS app 用URLSession调本地 Lambda,并在 Xcode 里跨两个进程断点调试。怎么开始:先用本地LOCAL_LAMBDA_SERVER_ENABLED=true调通localhost:7000,上线时再通过 API Gateway 暴露 HTTP endpoint。 -
把重计算任务从客户端移到 Swift Lambda:把设备上不适合即时执行的后台任务或计算任务交给 serverless function。为什么值得做:transcript 明确把 server component 的价值放在访问云端数据、后台任务和计算密集任务上,Swift 的低资源占用也适合按需计算。怎么开始:用 closure-based
Lambda.run做第一个版本,确认 payload 和返回值后,再用 Amazon Linux 2 Docker image 打包部署。 -
做事件驱动的云端处理管线:让 S3、SQS、SNS 或自定义事件触发 Swift Lambda。为什么值得做:runtime library 提供 extensible integration points,演讲列出了这些 AWS event source。怎么开始:先定义事件 payload 的
Codable类型,再根据处理耗时选择闭包 API 或EventLoopLambdaHandler。 -
做一套客户端与 Lambda 的本地调试模板:把 iOS app 和 Lambda package 放进同一个 Xcode workspace,预置 scheme 环境变量和断点位置。为什么值得做:演讲证明 Xcode 可以同时管理客户端和 Lambda 两个 executable target,调试请求和响应更直接。怎么开始:复制 demo 的结构:Lambda executable product 依赖 Swift AWS Lambda Runtime,客户端用
URLSession调本地 invoke endpoint。
关联 Session
- What’s new in Swift — Swift 2020 总览包含 Swift on AWS Lambda,并补充运行时性能、开发体验和 package 生态变化。
- Swift packages: Resources and localization — Lambda 示例建立在 Swift Package executable product 上,这场补充 Swift package 的组织方式。
- Explore Packages and Projects with Xcode Playgrounds — 继续看 Xcode 如何在项目、framework 和 Swift package 中支持探索式开发。
- Become a Simulator expert — 本 Session 的调试流程把 iOS app 跑在 Simulator,这场补足 Simulator 与 simctl 工作流。
评论
GitHub Issues · utterances