iOS分享扩展异常:Safari长按链接触发分享时无法将URL存入UserDefaults
问题根源拆解
- 当前实现仅适配了「Safari加载完整网页」的单一场景:只有当网页完全加载完成、执行了分享扩展配置的JS预处理器脚本时,才会传入符合
kUTTypePropertyList类型的附件,通过NSExtensionJavaScriptPreprocessingResultsKey字段传递当前页面URL。 - 长按链接触发的分享路径下,Safari不会加载目标链接对应的完整网页,也不会执行你的JS预处理脚本,此时传给扩展的附件是携带裸URL的标准类型(通常为
kUTTypeURL或kUTTypePlainText),完全不符合你代码里判断的kUTTypePropertyList类型,代码直接走了空的error分支,根本没有执行URL提取和存储逻辑。 - 内置的0.2秒定时自动触发关闭扩展的逻辑存在时序漏洞:URL加载、UserDefaults写入都是异步流程,定时器触发的关闭操作会在写入完成前直接终止扩展进程,即使偶尔拿到URL也可能因为进程被杀导致写入丢失。之前在完整网页场景下“好使”只是因为JS加载速度快,刚好赶上定时器的时间窗口,本质是巧合。
具体修复步骤
- 补全所有输入类型的解析逻辑,不要只处理
kUTTypePropertyList一种附件格式:
调整原有的类型判断分支,依次尝试提取URL:- 优先判断附件是否支持
kUTTypeURL类型,支持的话直接加载对应URL字符串 - 保留原有的
kUTTypePropertyList类型解析逻辑,适配完整网页的分享场景 - 增加
kUTTypePlainText类型的解析,从纯文本内容中提取合法URL
- 优先判断附件是否支持
- 彻底移除
viewDidLoad里的0.2秒定时器逻辑:
不要靠定时器猜测流程耗时,等所有URL提取、UserDefaults写入的代码执行完成后,再手动调用extensionContext.completeRequest关闭扩展,从根源上避免异步流程没走完就终止进程的问题。 - 补充异常分支的日志校验:
遇到不支持的附件类型时打印具体的类型标识,方便后续定位其他场景下的输入格式问题,不要只打一句笼统的error。
注意:确保应用和扩展都正确开启了App Groups权限,同一个suiteName和宿主应用保持完全一致,避免跨进程UserDefaults写入权限异常。
内容的提问来源于stack exchange,提问作者Hekes Pekes
相关产品推荐
相关产品推荐

