iOS 15 Swift 5开发:如何处理其他App分享到自家App的文件?
问题排查与解决方案
核心原因说明
该问题不是Swift版本差异导致,是iOS 13之后系统调整了UI生命周期架构:新建Xcode项目默认启用Scene多场景支持,原本AppDelegate中的URL打开回调会被系统拦截,分发到SceneDelegate对应的方法中,所以原有代码不会触发。
以下为适用于Swift 5、iOS 15的完整排查和实现方案:
第一步:确认项目生命周期类型
- 若项目不需要支持多场景,可以直接在Info.plist中删除
Application Scene Manifest配置项,强制启用AppDelegate生命周期,你原本写在AppDelegate中的代码即可正常触发 - 若需要保留Scene多场景支持,按照下一步的代码实现即可
第二步:Scene生命周期下的实现代码
在SceneDelegate文件中添加如下回调方法:
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let urlContext = URLContexts.first else { return } let url = urlContext.url // 可选:可以从urlContext.options中获取来源App等参数 do { // 访问外部文件前需要先申请权限 guard url.startAccessingSecurityScopedResource() else { print("无文件访问权限") return } defer { url.stopAccessingSecurityScopedResource() } let data = try Data(contentsOf: url) // 处理文件逻辑 print ("File was shared!") print (data) } catch { print("Unable to load data: \(error)") } }
第三步:SwiftUI生命周期适配
如果你使用的是SwiftUI原生生命周期(无AppDelegate、SceneDelegate文件),直接在根视图挂载onOpenURL修饰符即可:
@main struct YourApp: App { var body: some Scene { WindowGroup { ContentView() .onOpenURL { url in // 同上处理传入的文件URL逻辑 } } } }
额外排查点
- 确认Info.plist中
CFBundleDocumentTypes字段配置正确,已经声明了你要支持的文件类型对应的UTI(比如PDF对应的UTI为com.adobe.pdf) - 确认没有在其他地方拦截了URL打开事件,导致回调被吞掉
内容的提问来源于stack exchange,提问作者user8460166
相关产品推荐
相关产品推荐

