Swift实现从本地Files应用加载音乐文件至Player应用
加载Files应用中的音乐到自定义Player应用
要实现这个需求,需要结合iOS的文件访问机制和权限配置,以下是具体步骤:
1. 配置APP的文件访问权限
先在Info.plist中添加必要配置,让APP具备文件访问能力:
- 添加
UIFileSharingEnabled并设为YES:允许用户通过Files应用的「我的iPhone」目录访问APP的文档文件夹 - 添加
LSSupportsOpeningDocumentsInPlace并设为YES:支持直接访问原地文件(无需复制到APP沙盒) - 如果需要访问iCloud Drive中的音乐,添加
NSUbiquitousContainers配置,填入你的iCloud容器ID(开发者后台获取)
2. 获取音乐文件的两种方式
方式一:让用户选择Files中的音乐(推荐,符合iOS权限规范)
iOS沙盒限制APP不能直接遍历整个Files应用,必须通过UIDocumentPickerViewController让用户主动选择文件,之后保存授权的文件路径,启动时自动加载:
// 打开文件选择器,仅允许选择音频文件 func openMusicPicker() { let picker = UIDocumentPickerViewController(documentTypes: ["public.audio"], in: .import) picker.delegate = self picker.allowsMultipleSelection = true present(picker, animated: true) } // 处理用户选择的文件 extension YourViewController: UIDocumentPickerDelegate { func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { // 保存文件的安全书签(避免APP重启后路径失效) urls.forEach { saveBookmark(for: $0) } // 加载文件到播放器 loadMusicToPlayer(from: urls) } } // 保存文件安全书签 func saveBookmark(for url: URL) { do { let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) UserDefaults.standard.set(bookmarkData, forKey: "MusicBookmark_\(url.lastPathComponent)") } catch { print("保存书签失败:\(error)") } } // APP启动时恢复书签并加载音乐 func loadSavedMusicOnLaunch() { let defaults = UserDefaults.standard let savedKeys = defaults.dictionaryRepresentation().keys.filter { $0.starts(with: "MusicBookmark_") } var musicURLs = [URL]() savedKeys.forEach { key in guard let data = defaults.data(forKey: key) else { return } var isStale = false do { let url = try URL(resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale) if isStale { try saveBookmark(for: url) } url.startAccessingSecurityScopedResource() musicURLs.append(url) defer { url.stopAccessingSecurityScopedResource() } } catch { print("恢复书签失败:\(error)") } } loadMusicToPlayer(from: musicURLs) } // 将音乐文件加载到播放器的核心逻辑 func loadMusicToPlayer(from urls: [URL]) { // 遍历URL,提取文件名、时长等信息,添加到播放列表数据源 for url in urls { let musicTitle = url.lastPathComponent.replacingOccurrences(of: ".\(url.pathExtension)", with: "") // 示例:添加到你的播放列表数组 // playList.append(MusicModel(title: musicTitle, url: url)) } // 刷新UI(比如tableView.reloadData()) }
方式二:遍历APP自身的文档目录(Files中「我的iPhone」下的APP文件夹)
如果用户已经把音乐文件放到你的APP专属文件夹中,可以直接用FileManager遍历该目录:
func loadMusicFromAppDocuments() { guard let docsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return } do { let allFiles = try FileManager.default.contentsOfDirectory(at: docsURL, includingPropertiesForKeys: nil) // 筛选音频文件 let musicFiles = allFiles.filter { url in guard let uti = try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier else { return false } return UTTypeConformsTo(uti as CFString, kUTTypeAudio) } loadMusicToPlayer(from: musicFiles) } catch { print("读取文档目录失败:\(error)") } }
注意事项
- 必须遵守iOS权限规则,不能绕过用户授权直接访问Files中的任意文件,否则APP会被拒审
- 安全书签(bookmark)是持久化访问用户授权文件的唯一可靠方式,直接保存文件路径会导致APP重启后无法访问
- 如果需要支持后台扫描文件变化,可以结合
NSMetadataQuery监听文档目录的变化
内容的提问来源于stack exchange,提问作者Pavel Mishanin
相关产品推荐
相关产品推荐

