news 2026/10/23 1:49:01

推送与扩展实战:OCTO iOS 的通知解密、富通知渲染与系统分享面板接入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
推送与扩展实战:OCTO iOS 的通知解密、富通知渲染与系统分享面板接入

【免费下载链接】octo-ios

OCTO iOS Client — Open-source enterprise IM

项目地址:https://gitcode.com/gh_mirrors/oc/octo-ios
点击查看免费下载

在 iOS 上做好企业 IM,光有聊天界面远远不够。OCTO iOS(开源企业级 IM 客户端)把推送与系统能力拆成了三个独立的扩展 Target:NotificationService负责推送内容的拦截改写,NotificationContent负责富通知的自定义渲染,ShareExtension负责把系统分享面板接入聊天会话。本文带你从源码出发,看懂 OCTO iOS 如何实现消息通知解密、富通知渲染与系统分享面板接入,新手也能照着理清整条链路。

三大扩展分工:一张表看懂架构

OCTO iOS 的扩展体系遵循 iOS 平台的标准扩展点,每个扩展都有独立的入口类和Info.plist配置:

扩展 Target扩展点入口类核心职责
NotificationServicecom.apple.usernotifications.serviceNotificationService拦截 APNs 推送,改写通知内容
NotificationContent通知内容扩展NotificationViewController渲染自定义富通知 UI
ShareExtensioncom.apple.share-servicesShareViewController接入系统分享面板,把内容投递到会话

三个扩展的 Bundle ID 均由主 App 派生($(OCTO_BUNDLE_ID).NotificationService等),统一通过 OctoConfig.xcconfig.template 注入签名与配置,这套机制后面会详细展开。

推送消息解密:DH 密钥交换 + AES 通道加密

企业 IM 对安全性要求极高,OCTO iOS 的 IM SDK 在连接层就做了一套"握手—派生密钥—AES 加解密"的完整链路。

核心实现在 WKSecurityManager 中,流程分三步:

  1. 生成 DH 密钥对:generateDHPair生成本端 Diffie-Hellman 密钥对,公钥随握手发给服务端;
  2. 派生共享密钥:generateAesKey:salt:用对方公钥 + salt 协商出 AES 共享密钥,方法返回NO时调用方应直接断开连接,避免带着 nil 密钥继续走加密流程;
  3. 加解密数据: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。它有三个值得学习的设计:

  1. 空间隔离过滤:showLocalNotificationIfNeed:会先判断消息是否属于当前工作空间(isMessageInCurrentSpace:),子区消息还会通过____前缀匹配父群兜底,避免跨空间误打扰;
  2. 通知内容拼装:私聊用发送者昵称做标题、群聊用群名,图片/GIF/语音统一转成[图片]、[GIF]、[语音]占位文本,并同步 +1 角标数、支持"应用内静音";
  3. 点击直达: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 的解法是:

  1. 把文件信息数组写入 App Group 共享的NSUserDefaults(key 为WKShareExtensionData),Group ID 由 Info.plist 的 OCTOAppGroup 字段 动态读取(见 _OctoAppGroupId),外部团队签名时只需改OctoConfig.xcconfig中的OCTO_APP_GROUP,无需改代码;
  2. 拼出octo://share(scheme 同样由OCTO_URL_SCHEME注入)并通过 iOS 18 推荐的open:options:completionHandler:API 唤醒主 App;
  3. 主 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

项目地址:https://gitcode.com/gh_mirrors/oc/octo-ios
点击查看免费下载
上一篇:零账户玩转AI编程:Claude Code Router跨模型新方案
下一篇:Chat Nio绿色计算:能耗优化与可持续发展实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 1:48:54

3种控制模式+1套FOC算法:平衡车固件从嗡鸣到顺滑的完整指南

3种控制模式1套FOC算法:平衡车固件从嗡鸣到顺滑的完整指南 【免费下载链接】hoverboard-firmware-hack-FOC With Field Oriented Control (FOC) 项目地址: https://gitcode.com/GitHub_Trending/ho/hoverboard-firmware-hack-FOC 还在为平衡车起步嗡嗡响、高…

作者头像 李华
网站建设 2026/10/23 1:48:49

ohmyzsh主题选型指南:五分钟找到适合你的提示符

ohmyzsh主题选型指南:五分钟找到适合你的提示符 【免费下载链接】ohmyzsh 🙃 A delightful community-driven (with 2,500 contributors) framework for managing your zsh configuration. Includes 300 optional plugins (rails, git, macOS, hub, dock…

作者头像 李华
网站建设 2026/10/23 1:47:44

PCL2启动器更新失败问题分析与解决方案

PCL2启动器更新失败问题分析与解决方案 问题现象 PCL2启动器在2.8.12版本更新过程中出现"权限不足"错误提示,具体表现为系统拒绝访问程序路径"D:\Plain Craft Launcher 2\Plain Craft Launcher 2.exe"。该问题通常发生在用户尝试通过启动器内置…

作者头像 李华
网站建设 2026/10/23 1:47:43

PCL2启动器游戏启动失败问题分析与解决方案

PCL2启动器游戏启动失败问题分析与解决方案 问题现象 近期部分PCL2启动器用户反馈在尝试启动游戏时遇到了"被管理员禁止"的错误提示。该问题表现为启动器界面可以正常打开,但在点击启动游戏按钮后系统弹出错误窗口,阻止游戏进程的正常启动。 问…

作者头像 李华