iOS端如何通过UIActivityViewController接收「文件」App的文档/PDF至Swift应用
实现Swift应用接收「文件」App的文件分享
一、主应用直接接收方案(推荐)
这种方式让你的应用直接出现在分享列表,用户点击后直接打开应用并获取文件。
1. 配置主应用的Info.plist
在Info.plist中添加或修改以下配置:
<!-- 开启文件共享 --> <key>UIFileSharingEnabled</key> <true/> <!-- 支持在原地打开文档(可选) --> <key>LSSupportsOpeningDocumentsInPlace</key> <true/> <!-- 配置支持的文档类型,这里设为支持所有文件 --> <key>CFBundleDocumentTypes</key> <array> <dict> <key>CFBundleTypeName</key> <string>Any File</string> <key>LSHandlerRank</key> <string>Alternate</string> <key>LSItemContentTypes</key> <array> <string>public.data</string> <!-- 匹配所有文件类型 --> </array> </dict> </array>
public.data表示支持所有文件类型,如果需要指定特定类型,可以替换为对应UTI(比如public.image对应图片,com.microsoft.word.doc对应Word文档)。LSHandlerRank设为Alternate,确保应用出现在分享列表中。
2. 在应用中处理接收的文件
根据你使用的生命周期(UIKit的AppDelegate或SceneDelegate),添加文件接收逻辑:
场景1:使用SceneDelegate(iOS 13+)
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { guard let fileURL = URLContexts.first?.url else { return } // 处理文件,比如复制到应用沙盒,或直接读取 if fileURL.startAccessingSecurityScopedResource() { defer { fileURL.stopAccessingSecurityScopedResource() } // 这里可以获取文件数据,比如: do { let data = try Data(contentsOf: fileURL) // 处理数据,比如显示文件内容、保存到本地等 } catch { print("读取文件失败:\(error)") } } }
场景2:使用AppDelegate(iOS 12及以下)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { if url.startAccessingSecurityScopedResource() { defer { url.stopAccessingSecurityScopedResource() } do { let data = try Data(contentsOf: url) // 处理文件逻辑 } catch { print("读取文件失败:\(error)") } } return true }
二、分享扩展方案(如果需要通过扩展中转)
如果你想用分享扩展接收文件,再传递给主应用,需要调整扩展的配置:
1. 修改扩展的Info.plist
将原有的激活规则替换为支持任意文件:
<key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsFileWithMaxCount</key> <integer>1</integer> <!-- 支持单个文件 --> <!-- 如果需要支持多个文件,调整数值即可 --> </dict> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.ui-services</string> </dict>
NSExtensionActivationSupportsFileWithMaxCount用于支持任意文件类型的分享,替换原来的图片专属配置。
2. 在扩展中处理文件并传递给主应用
在扩展的ViewController中,获取分享的文件,然后通过App Groups或URL Scheme传递给主应用:
import UIKit import Social class ShareViewController: SLComposeServiceViewController { override func isContentValid() -> Bool { return true } override func didSelectPost() { guard let item = extensionContext?.inputItems.first as? NSExtensionItem, let provider = item.attachments?.first as? NSItemProvider, provider.hasItemConformingToTypeIdentifier("public.data") else { extensionContext?.completeRequest(returningItems: [], completionHandler: nil) return } provider.loadItem(forTypeIdentifier: "public.data", options: nil) { [weak self] (data, error) in guard let fileURL = data as? URL else { self?.extensionContext?.completeRequest(returningItems: [], completionHandler: nil) return } // 这里可以通过App Groups将文件复制到共享容器,或者用URL Scheme唤起主应用传递信息 // 示例:用URL Scheme唤起主应用 if let url = URL(string: "yourappscheme://openfile?path=\(fileURL.path)") { self?.extensionContext?.open(url, completionHandler: { success in self?.extensionContext?.completeRequest(returningItems: [], completionHandler: nil) }) } } } }
注意:需要在主应用中配置对应的URL Scheme,并在主应用中处理该Scheme的跳转。
验证配置
完成配置后,清理Xcode缓存,重新编译应用到设备或模拟器,打开「文件」App选择任意文件,点击分享按钮,你的应用就会出现在分享列表中,点击后即可在应用内处理该文件。
内容的提问来源于stack exchange,提问作者mahesh
相关产品推荐
相关产品推荐

