こんにちは。
最近「Swift Concurrency」を使ってアプリ内の通知をもう少しスマートに扱いたいなと思い、
型安全でAsyncStreamベースの通知機能を作ってみました。
従来のNotificationCenterを型安全かつAsyncStreamに対応したものになります 🎉
🧩 これは何?
NotificationCoreは、モデルの更新通知を型安全に扱える軽量ライブラリです。
Globalに「状態の変更を購読したい」「非同期で待ちたい」という時に便利です。
🌟 特徴まとめ
- ✅ 型安全:
ObserverKey<T>で通知の型を保証 - ⚙️ AsyncStream対応:
for awaitで自然に購読できる - 🧵 Global Actorで安全な並列処理
- 🪶 依存なし! CombineやObj-Cランタイム不要
- 💥 ミスを早期発見:未登録キーで送信すると
preconditionFailure
🚀 導入方法(Swift Package Manager)
Xcodeから追加する場合
- プロジェクトを開く
File > Add Package Dependencies…- 以下のURLを入力
https://github.com/sadasada1729/swift-notification
- バージョンルールを設定して追加
Package.swiftで指定する場合
// swift-tools-version: 6.2
import PackageDescription
let package = Package(
name: "YourApp",
platforms: [
.iOS(.v18), .macOS(.v14)
],
dependencies: [
.package(url: "https://github.com/sadasada1729/swift-notification.git", from: "1.0.0")
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "NotificationCore", package: "swift-notification")
]
)
]
)
🧠 使い方サンプル
// 通知したいモデル
struct SamplePerson: Sendable, Equatable {
let name: String
let age: Int
}
// 対象エンティティを登録
extension NotificationCore.Name {
static let person: ObserverKey<SamplePerson> = .init()
}
// 監視を開始
for await person in NotificationCore.addObserver(keyPath: \.person) {
print(person)
}
// 更新を送信
await NotificationCore.shared.send(keyPath: \.person,
value: .init(name: "test1", age: 20))
💡 なぜ作ったか
Swift Concurrencyの世界で「非同期通知を型安全に扱う」方法って、
意外とピッタリな仕組みがまだ少ないんですよね。
NotificationCenterやCombineを使うと柔軟ですが、
- 型が保証されない(string key管理は怖い)
- Combineが重い
- Obj-C依存の仕組みはもう避けたい
といった悩みが出てきます。
そこで、AsyncStream×Genericsで完結する仕組みを自分で作ってみた、というわけです。
🧾 まとめ
NotificationCoreはこんな人におすすめです👇
- Swift Concurrencyでアプリを書いている
- 型安全にモデルの更新を購読したい
- Combineを使うほどではないけどNotificationCenterは避けたい
リポジトリはこちら👇
👉 https://github.com/sadasada1729/swift-notification
気軽に試してみて、もし良かったらスター⭐️してもらえると嬉しいです!