【免费下载链接】octo-ios
OCTO iOS Client — Open-source enterprise IM
在 iOS 上做好企业 IM,光有聊天界面远远不够。OCTO iOS(开源企业级 IM 客户端)把推送与系统能力拆成了三个独立的扩展 Target:NotificationService负责推送内容的拦截改写,NotificationContent负责富通知的自定义渲染,ShareExtension负责把系统分享面板接入聊天会话。本文带你从源码出发,看懂 OCTO iOS 如何实现消息通知解密、富通知渲染与系统分享面板接入,新手也能照着理清整条链路。
三大扩展分工:一张表看懂架构
OCTO iOS 的扩展体系遵循 iOS 平台的标准扩展点,每个扩展都有独立的入口类和Info.plist配置:
| 扩展 Target | 扩展点 | 入口类 | 核心职责 |
|---|---|---|---|
NotificationService | com.apple.usernotifications.service | NotificationService | 拦截 APNs 推送,改写通知内容 |
NotificationContent | 通知内容扩展 | NotificationViewController | 渲染自定义富通知 UI |
ShareExtension | com.apple.share-services | ShareViewController | 接入系统分享面板,把内容投递到会话 |
三个扩展的 Bundle ID 均由主 App 派生($(OCTO_BUNDLE_ID).NotificationService等),统一通过 OctoConfig.xcconfig.template 注入签名与配置,这套机制后面会详细展开。
推送消息解密:DH 密钥交换 + AES 通道加密
企业 IM 对安全性要求极高,OCTO iOS 的 IM SDK 在连接层就做了一套"握手—派生密钥—AES 加解密"的完整链路。
核心实现在 WKSecurityManager 中,流程分三步:
- 生成 DH 密钥对:
generateDHPair生成本端 Diffie-Hellman 密钥对,公钥随握手发给服务端; - 派生共享密钥:
generateAesKey:salt:用对方公钥 + salt 协商出 AES 共享密钥,方法返回NO时调用方应直接断开连接,避免带着 nil 密钥继续走加密流程; - 加解密数据:
encryption:/decryption:对所有通道数据做 AES 加解密,底层工具类为 WKAESUtil(提供aesEncrypt:key:iv:/aesDecrypt:key:iv:)。
客户端 DH 公钥 ──► 服务端 服务端公钥 ──► 客户端 双方各自派生 → 相同 AES sharedKey → 通道内所有报文加解密这样即使推送通道被中间人截获,拿到的是密文。主 App 收到远程推送后,由 WKApp.m 的didReceiveRemoteNotification:统一转发给 Swift 模块继续处理。
NotificationService:推送内容的"最后一公里"改写
NotificationService继承自UNNotificationServiceExtension,是 APNs 推送落地前最后一个可以修改内容的地方。其入口逻辑非常清晰(见 NotificationService.m):
didReceiveNotificationRequest:withContentHandler::拿到推送请求后先mutableCopy一份可变内容,在这里可以改写标题、正文、附件,最后调用contentHandler交付系统;serviceExtensionTimeWillExpire:系统即将强杀扩展前的回调,用于交付"尽力而为"的修改结果,否则系统会使用原始 payload 兜底。
💡 这个 30 秒左右的生命周期意味着改写逻辑必须轻量;耗时操作(下载附件、解析大 payload)需要异步并尽快交付。
NotificationContent:自定义富通知渲染
普通通知只有标题 + 正文,而企业 IM 常希望展示头像、消息卡片等富 UI。NotificationContent扩展继承UIViewController并实现UNNotificationContentExtension协议:
didReceiveNotification::系统传入完整UNNotification对象,NotificationViewController.m 从中取出notification.request.content.body填充自定义视图;- 界面由独立的 MainInterface.storyboard 描述,扩展在后台进程中以受限视图层级运行。
渲染的约束是:扩展运行在独立进程,只能用轻量 UI 组件(UILabel、UIImageView 等),无法使用完整 UIKit 控件体系——这也是 OCTO iOS 保持界面简洁的原因。
本地通知:空间隔离与点击直达消息
除远程推送外,OCTO iOS 还会在 IM SDK 收到新消息时弹本地通知,核心类是 WKLocalNotificationManager。它有三个值得学习的设计:
- 空间隔离过滤:
showLocalNotificationIfNeed:会先判断消息是否属于当前工作空间(isMessageInCurrentSpace:),子区消息还会通过____前缀匹配父群兜底,避免跨空间误打扰; - 通知内容拼装:私聊用发送者昵称做标题、群聊用群名,图片/GIF/语音统一转成
[图片]、[GIF]、[语音]占位文本,并同步 +1 角标数、支持"应用内静音"; - 点击直达:
didReceiveNotificationResponse:兼容本地字段(channel_id)与 APNs 字段(channelID等命名差异),统一交给WKConversationRouter openChannelId:打开对应会话并定位消息(见 WKLocalNotificationManager.m)。
ShareExtension:把系统分享面板接入 IM
这是 OCTO iOS 中最"工程化"的部分,目标一句话:在任意 App 点"分享",选 OCTO,把图片/文件/链接/文本直接发给指定会话。
第一步:在 Info.plist 声明可分享的类型
ShareExtension/Info.plist 通过NSExtensionActivationRule声明激活规则:最多 9 张图片、1 个视频、1 个文件,并支持纯文本与单条 Web URL。只有符合规则的分享面板里才会出现 OCTO 入口。
第二步:区分"链接分享"与"文件分享"
handleShareContent会先扫描所有NSItemProvider的类型标识(UTTypeURL/UTTypeImage/UTTypeMovie等):
- 纯 URL 分享(如 Safari 分享网页):走
handleURLShare:,提取 URL + 网页标题,并从 host 推断favicon.ico图标,合并为一条type=link消息(见 ShareViewController.m); - 文件类分享:逐个 provider 异步加载,图片转 JPEG、文件复制进 App Group 共享目录(带 security scope 访问),全部完成后统一交付。
第三步:App Group 跨进程投递 + URL Scheme 唤醒主 App
扩展进程无法直接操作主 App 的数据库,OCTO iOS 的解法是:
- 把文件信息数组写入 App Group 共享的
NSUserDefaults(key 为WKShareExtensionData),Group ID 由 Info.plist 的 OCTOAppGroup 字段 动态读取(见 _OctoAppGroupId),外部团队签名时只需改OctoConfig.xcconfig中的OCTO_APP_GROUP,无需改代码; - 拼出
octo://share(scheme 同样由OCTO_URL_SCHEME注入)并通过 iOS 18 推荐的open:options:completionHandler:API 唤醒主 App; - 主 App 侧的 WKApp handleShareExtensionData 读取共享数据后立即清除,弹出"选择聊天"面板,用户确认后才真正调用
chatManager发送。
细节同样讲究:文件/视频/音频发送前会先复制到 App 文档目录(共享目录会被清理),图文混合分享会聚合成一条富文本消息而非拆成多条。
配置清单:一次跑通三个扩展
所有变量集中定义在 OctoConfig.xcconfig.template,拷贝为OctoConfig.xcconfig后重点核对四项:
- ✅
APPLE_TEAM_ID:自动签名必须; - ✅
OCTO_BUNDLE_ID:主 App 包名,三个扩展自动派生 Bundle ID; - ✅
OCTO_APP_GROUP:必须与 Apple Developer 后台 provision 的 App Group 完全一致,否则扩展读取共享数据直接失效; - ✅
OCTO_URL_SCHEME:分享扩展唤醒主 App 的 scheme,需与主 App 注册的一致。
改完任意一项后执行pod install+ Clean Build Folder 即可,Podfile 的post_install会自动把配置注入到三个扩展 Target。
小结
OCTO iOS 用三个小而专的扩展 Target,把"推送改写、富通知渲染、系统分享面板"三件事做成了可独立演进的能力模块:NotificationService守住推送落地前最后一环,NotificationContent提供自定义通知 UI,ShareExtension借助 App Group + URL Scheme 把任意来源的内容无缝接入 IM 会话,再叠加 DH 密钥交换 + AES 通道加密,构成了一套完整、可参考的企业 IM 推送与扩展实战方案。
【免费下载链接】octo-ios
OCTO iOS Client — Open-source enterprise IM
相关推荐
15 分钟把 Claude Code 搬进 Obsidian:Claudian 安装与跑通指南
15 分钟把 Claude Code 搬进 Obsidian:Claudian 安装与跑通指南 Claudian 是一个 Obsidian 插件,把 Claud
AI 应用代码智能体交互助手人工智能AI AgentSortable:基于shadcn/ui与dnd-kit构建的终极拖拽排序组件库详解
Sortable:基于shadcn/ui与dnd kit构建的终极拖拽排序组件库详解 Sortable是一款基于shadcn/ui、radix ui和dnd k
skills4/skills:一行命令装好 AI 技能库,Codex 技能安装快速上手
skills4/skills:一行命令装好 AI 技能库,Codex 技能安装快速上手 你有没有过这种经历:同一个背景说明,每次都要手动贴给 AI 一遍,换个人
人工智能AI 技能AI 插件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考