You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:24:03