如何集中管理应用中分散的Realm Notification Tokens
基于 enum + CaseIterable 的 Realm 通知令牌可落地管理方案
解决的核心痛点
之前手动维护统一令牌数组的模式,完全靠开发者自觉把新增令牌同步进集合,没有任何编译期校验,35个令牌的规模下很容易出现遗漏、重复失效的问题;下面的实现路径完全不需要手动同步数组,从机制上堵住人为出错的可能。
具体实现步骤
- 第一步:定义带静态遍历能力的令牌标识枚举
整个方案的核心是:不要把运行时动态生成的Realm令牌实例存到枚举里,而是用枚举定义所有需要跟踪的令牌的唯一标识,遵循CaseIterable协议让所有标识可以被自动遍历:enum RealmTokenKey: String, CaseIterable { // 把你现有所有业务模块对应的令牌场景逐一定义为case,命名直接对应业务含义 case userProfileObserver case feedListDataSourceObserver case chatSessionListObserver // ... 覆盖全部35个业务场景的令牌标识即可 } - 第二步:搭建令牌管理器的核心能力
摒弃“为每个令牌写单独属性+手动拼数组”的旧设计,改用字典按枚举key动态存储令牌实例,从根源上取消手动维护数组的环节:final class RealmNotificationTokensManager { static let shared = RealmNotificationTokensManager() // 按枚举key存储运行时生成的令牌实例,可选类型适配“不是所有令牌都会在App启动时就生成”的实际情况 private var tokenStorage: [RealmTokenKey: NotificationToken] = [:] // 统一的令牌注册入口:所有业务模块生成observe令牌时,必须走这个方法登记,禁止业务模块自行持有令牌 func register(token: NotificationToken, for key: RealmTokenKey) { // 注册前自动失效同key的旧令牌,避免重复观察 tokenStorage[key]?.invalidate() tokenStorage[key] = token } // 批量获取所有已激活令牌:不需要手动维护数组,直接遍历枚举所有key从存储里取存在的实例即可 func fetchAllActiveTokens() -> [NotificationToken] { RealmTokenKey.allCases.compactMap { tokenStorage[$0] } } // 按场景批量失效令牌的方法,适配“特定视图/特定时间范围激活令牌”的管理需求 func invalidate(tokensIn keys: [RealmTokenKey]) { keys.forEach { key in tokenStorage[key]?.invalidate() tokenStorage.removeValue(forKey: key) } } // 全量兜底失效方法,比如登出场景下清空所有令牌 func invalidateAll() { tokenStorage.values.forEach { $0.invalidate() } tokenStorage.removeAll() } } - 第三步:适配分场景激活的管理需求
因为所有令牌的标识都是编译期可见的枚举case,可以直接给每个标识绑定所属的业务/页面生命周期,不需要硬编码字符串判断:
这样某个页面销毁时,只需要调用管理器的失效方法,把对应场景下的所有令牌key传入即可,不会出现跨场景误失效、漏失效的问题。// 定义页面场景的枚举 enum PageLifecycleScene { case global, feed, userProfile, chat } extension RealmTokenKey { // 给每个令牌绑定归属的生命周期场景 var belongScene: PageLifecycleScene { switch self { case .userProfileObserver: return .userProfile case .feedListDataSourceObserver: return .feed case .chatSessionListObserver: return .chat } } }
方案的防错机制
- 完全取消手动维护统一数组的环节:所有令牌的批量归集,都靠
CaseIterable的静态遍历能力自动完成,只要令牌通过统一入口注册到管理器,就一定会被纳入批量查询、失效的范围,不存在“加了令牌属性但忘加数组”的遗漏可能 - 后续新增令牌的标准化流程没有额外负担:
- 在
RealmTokenKey枚举里新增对应业务场景的case - 业务模块生成observe令牌时,调用管理器的
register方法完成绑定
- 在
- 可以额外加调试阶段的校验:遍历所有
RealmTokenKey.allCases,如果某个case在全项目代码中没有被任何地方调用过注册接口,就打印调试警告,提醒开发者检查是不是漏写了标识对应逻辑。
内容的提问来源于stack exchange,提问作者hkdalex
相关产品推荐
相关产品推荐

