基于 Swift 5.9 + 的AsyncStream,实现全局单例、自动生命周期、多点发送单点接收的 SwiftUI 消息流,代码精简且易上手。

一、核心实现:全局流管理器 + SwiftUI 视图
1. 全局消息流管理器(StreamManager)
单例设计,读写分离,并发安全,一行发送消息,极简易用。
Swift
import SwiftUI
// 全局单例消息流管理器
final class StreamManager: Sendable {
static let shared = StreamManager()
let stream: AsyncStream<String>
private let continuation: AsyncStream<String>.Continuation
private init() {
// Swift5.9+ 便捷创建流和续体
let (stream, continuation) = AsyncStream<String>.makeStream()
// 如果需要背压
// let (stream, continuation) = AsyncStream<String>.makeStream(bufferingPolicy: .bufferingOldest(10))
self.stream = stream
self.continuation = continuation
}
// 对外暴露的发送方法
func send(_ message: String) {
continuation.yield(message)
}
}
2. SwiftUI 视图集成(ContentView)
自带发送按钮、消息展示,task自动管理监听生命周期,无需手动启停。
Swift
struct ContentView: View {
@State private var messages: [String] = []
var body: some View {
NavigationStack {
ScrollView {
VStack(spacing: 30) {
// 发送区+消息展示区
VStack(alignment: .leading, spacing: 15) {
Text("多点发送 · 单点接收")
.font(.headline)
// 两个发送者
HStack(spacing: 15) {
Button("发送者A") {
StreamManager.shared.send("客服A:订单已发货")
}.buttonStyle(.bordered)
Button("发送者B") {
StreamManager.shared.send("客服B:感谢咨询")
}.buttonStyle(.bordered)
}
Divider()
// 消息展示
Text("接收的消息:").font(.caption).foregroundStyle(.secondary)
if messages.isEmpty {
Text("暂无消息").italic().foregroundStyle(.tertiary)
} else {
VStack(alignment: .leading, spacing: 8) {
ForEach(messages, id: \.self) { msg in
Text(msg)
.padding(8)
.background(Color.blue.opacity(0.1))
.cornerRadius(6)
}
}
}
}
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(12)
}
.padding()
}
.navigationTitle("AsyncStream 示例")
// 自动监听:视图出现启动,消失自动取消
.task { await listenMessage() }
}
}
// 监听流消息
private func listenMessage() async {
for await msg in StreamManager.shared.stream {
messages.append(msg)
}
}
}
二、核心亮点(极简核心)
- 自动生命周期 :
task修饰符替代手动启停,视图消失自动取消监听,无内存泄漏; - 解耦设计 :发送者仅调用
send,接收者仅监听流,互不依赖; - 并发安全 :遵循
Sendable,多线程可安全调用发送方法; - 极简 API :Swift5.9+
makeStream直接创建流和续体,告别闭包捕获的繁琐写法。
三、快速扩展(按需添加)
1. 自定义消息模型
替换String为自定义模型,适配复杂业务:
Swift
// 自定义消息体
struct CustomMsg: Sendable {
let sender: String
let content: String
let time: Date = .now
}
// 管理器中修改泛型:AsyncStream<CustomMsg>
func send(sender: String, content: String) {
continuation.yield(CustomMsg(sender: sender, content: content))
}
2. 低版本兼容(Swift5.8 及以下)
替换makeStream为闭包写法,兼容 iOS15+/macOS12+:
private init() {
var cont: AsyncStream<String>.Continuation!
self.stream = AsyncStream { cont = $0 }
self.continuation = cont
}
3. 消息清空 / 限流
添加简单方法,控制消息数量:
Swift
// 管理器中添加清空(或视图中直接操作@State)
func clear() { messages.removeAll() }
// 限流:只保留最近10条
if messages.count >= 10 { messages.removeFirst() }
四、关键注意事项
- 适配版本:
AsyncStream支持 iOS15+/macOS12+,makeStream支持 iOS17+/Swift5.9+; - UI 更新:
task中监听的流,更新@State会自动切主线程,无需手动调度; - 多接收者:一个流可被多个视图同时监听,实现一对多消息分发;
- 续体安全:单例模式下续体不会提前释放,非单例需注意持有生命周期。
五、核心总结
AsyncStream替代传统闭包 / 通知 / 代理,实现 SwiftUI 异步消息传递更简洁:
- 单例管理器封装流,实现全局消息分发;
task+for await极简监听,自动管理生命周期;- 读写分离,解耦发送者和接收者,代码可维护性拉满。