You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

sourceApplication在App运行时失效,打开PDF时App崩溃问题求助

解决App运行时唤起PDF崩溃+sourceApplication失效的问题

嘿,我之前碰到过几乎一模一样的问题!你的核心矛盾很明确:App没启动时开PDF完全正常,前台跑着的时候唤起就崩,删了sourceApplication相关代码就没事,但这部分逻辑又不能丢。结合iOS的文件唤起机制,大概率是你处理sourceApplication的时机或者方式踩坑了,下面给你几个针对性的排查和解决思路:

1. 先给sourceApplication加个“安全防护”——别强制解包!

当App处于运行状态时,唤起请求会走application(_:open:options:)(iOS12及以下)或者SceneDelegate的scene(_:openURLContexts:)(iOS13+)。很多人崩溃都是因为直接强制解包sourceApplication,但这个值在某些场景下(比如通过系统文件管理器直接打开PDF)可能是nil,运行时强制解包直接炸。

修正后的代码示例(AppDelegate)

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    // 安全获取sourceApplication,用as?代替as!
    let sourceApp = options[.sourceApplication] as? String
    if let sourceApp = sourceApp {
        // 处理你的sourceApplication逻辑,比如判断来源
        print("从应用\(sourceApp)唤起")
    } else {
        // 兜底处理无来源的情况,比如系统直接打开
        print("无来源应用,直接打开PDF")
    }
    // 单独处理PDF文件逻辑
    handlePDFFile(url: url)
    return true
}

2. 确认你在正确的回调里处理唤起请求

如果你的App是iOS13及以上,并且启用了SceneDelegate,那绝对不能再在AppDelegate里处理文件唤起!必须移到SceneDelegate的scene(_:openURLContexts:)方法里,否则会导致App状态不一致,轻则sourceApplication取不到值,重则崩溃。

SceneDelegate的正确处理示例

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let urlContext = URLContexts.first else { return }
    let pdfUrl = urlContext.url
    // 这里的sourceApplication是可选值,直接用即可
    let sourceApp = urlContext.options.sourceApplication
    if let sourceApp = sourceApp {
        print("来源应用:\(sourceApp)")
    }
    handlePDFFile(url: pdfUrl)
}

3. 排查sourceApplication和PDF处理逻辑的耦合坑

有时候不是sourceApplication本身的问题,而是你在处理它的时候,调用了某个还没初始化完成的对象——比如全局单例、UI组件。比如App运行时唤起,回调可能在后台线程,你直接在里面操作UI,或者调用了某个还没完成初始化的工具类,直接就崩了。

排查小技巧

  • 先把PDF处理逻辑注释掉,只保留sourceApplication的打印,看还会不会崩溃
  • 如果不崩了,再逐步加回PDF处理代码,定位到具体的崩溃点
  • 所有UI操作必须放到主线程,比如:
    DispatchQueue.main.async {
        // 在这里更新UI,比如跳转到PDF预览页面
        self.navigateToPDFViewer(with: url)
    }
    

4. 再核对一遍info.plist的配置细节

虽然你说已经配置了,但还是要确认几个关键点:

  • CFBundleDocumentTypes里的CFBundleTypeRole要设为ViewerEditor
  • LSItemContentTypes必须包含PDF的UTI:com.adobe.pdf
  • 如果你开了文件共享(UIFileSharingEnabled),确保它和文档唤起逻辑没有冲突

按照这个思路排查下来,应该就能同时解决崩溃和sourceApplication失效的问题啦!

内容的提问来源于stack exchange,提问作者Gökhan Çokkeçeci

火山引擎 最新活动