sourceApplication在App运行时失效,打开PDF时App崩溃问题求助
嘿,我之前碰到过几乎一模一样的问题!你的核心矛盾很明确: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要设为Viewer或EditorLSItemContentTypes必须包含PDF的UTI:com.adobe.pdf- 如果你开了文件共享(
UIFileSharingEnabled),确保它和文档唤起逻辑没有冲突
按照这个思路排查下来,应该就能同时解决崩溃和sourceApplication失效的问题啦!
内容的提问来源于stack exchange,提问作者Gökhan Çokkeçeci




